Test behaviour of color write enable with colorWriteMask
[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_RED,
77         FILL_MODE_MULTISAMPLE,
78         FILL_MODE_BLUE_RED_X,
79         FILL_MODE_BLUE_RED_Y,
80         FILL_MODE_BLUE_RED_Z,
81
82         FILL_MODE_LAST
83 };
84
85 enum MirrorModeBits
86 {
87         MIRROR_MODE_X           = (1<<0),
88         MIRROR_MODE_Y           = (1<<1),
89         MIRROR_MODE_Z           = (1<<2),
90         MIRROR_MODE_LAST        = (1<<3),
91 };
92
93 using MirrorMode = deUint32;
94
95 enum AllocationKind
96 {
97         ALLOCATION_KIND_SUBALLOCATED,
98         ALLOCATION_KIND_DEDICATED,
99 };
100
101 enum ExtensionUse
102 {
103         EXTENSION_USE_NONE,
104         EXTENSION_USE_COPY_COMMANDS2,
105 };
106
107 template <typename Type>
108 class BinaryCompare
109 {
110 public:
111         bool operator() (const Type& a, const Type& b) const
112         {
113                 return deMemCmp(&a, &b, sizeof(Type)) < 0;
114         }
115 };
116
117 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >    FormatSet;
118
119 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
120 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
121
122 using namespace vk;
123
124 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
125 {
126         const VkImageCopy2KHR   imageCopy2 =
127         {
128                 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,             // VkStructureType                              sType;
129                 DE_NULL,                                                                // const void*                                  pNext;
130                 imageCopy.srcSubresource,                               // VkImageSubresourceLayers             srcSubresource;
131                 imageCopy.srcOffset,                                    // VkOffset3D                                   srcOffset;
132                 imageCopy.dstSubresource,                               // VkImageSubresourceLayers             dstSubresource;
133                 imageCopy.dstOffset,                                    // VkOffset3D                                   dstOffset;
134                 imageCopy.extent                                                // VkExtent3D                                   extent;
135         };
136         return imageCopy2;
137 }
138 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
139 {
140         const VkBufferCopy2KHR  bufferCopy2 =
141         {
142                 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,    // VkStructureType                              sType;
143                 DE_NULL,                                                                // const void*                                  pNext;
144                 bufferCopy.srcOffset,                                   // VkDeviceSize                                 srcOffset;
145                 bufferCopy.dstOffset,                                   // VkDeviceSize                                 dstOffset;
146                 bufferCopy.size,                                                // VkDeviceSize                                 size;
147         };
148         return bufferCopy2;
149 }
150
151 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
152 {
153         const VkBufferImageCopy2KHR     bufferImageCopy2 =
154         {
155                 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,      // VkStructureType                              sType;
156                 DE_NULL,                                                                        // const void*                                  pNext;
157                 bufferImageCopy.bufferOffset,                           // VkDeviceSize                                 bufferOffset;
158                 bufferImageCopy.bufferRowLength,                        // uint32_t                                             bufferRowLength;
159                 bufferImageCopy.bufferImageHeight,                      // uint32_t                                             bufferImageHeight;
160                 bufferImageCopy.imageSubresource,                       // VkImageSubresourceLayers             imageSubresource;
161                 bufferImageCopy.imageOffset,                            // VkOffset3D                                   imageOffset;
162                 bufferImageCopy.imageExtent                                     // VkExtent3D                                   imageExtent;
163         };
164         return bufferImageCopy2;
165 }
166
167 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
168 {
169         const VkImageBlit2KHR   imageBlit2 =
170         {
171                 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,                     // VkStructureType                              sType;
172                 DE_NULL,                                                                        // const void*                                  pNext;
173                 imageBlit.srcSubresource,                                       // VkImageSubresourceLayers             srcSubresource;
174                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
175                         {
176                                 imageBlit.srcOffsets[0].x,                              // VkOffset3D                   srcOffsets[0].x;
177                                 imageBlit.srcOffsets[0].y,                              // VkOffset3D                   srcOffsets[0].y;
178                                 imageBlit.srcOffsets[0].z                               // VkOffset3D                   srcOffsets[0].z;
179                         },
180                         {
181                                 imageBlit.srcOffsets[1].x,                              // VkOffset3D                   srcOffsets[1].x;
182                                 imageBlit.srcOffsets[1].y,                              // VkOffset3D                   srcOffsets[1].y;
183                                 imageBlit.srcOffsets[1].z                               // VkOffset3D                   srcOffsets[1].z;
184                         }
185                 },
186                 imageBlit.dstSubresource,                                       // VkImageSubresourceLayers             dstSubresource;
187                 {                                                                                       // VkOffset3D                                   srcOffsets[2];
188                         {
189                                 imageBlit.dstOffsets[0].x,                              // VkOffset3D                   dstOffsets[0].x;
190                                 imageBlit.dstOffsets[0].y,                              // VkOffset3D                   dstOffsets[0].y;
191                                 imageBlit.dstOffsets[0].z                               // VkOffset3D                   dstOffsets[0].z;
192                         },
193                         {
194                                 imageBlit.dstOffsets[1].x,                              // VkOffset3D                   dstOffsets[1].x;
195                                 imageBlit.dstOffsets[1].y,                              // VkOffset3D                   dstOffsets[1].y;
196                                 imageBlit.dstOffsets[1].z                               // VkOffset3D                   dstOffsets[1].z;
197                         }
198                 }
199         };
200         return imageBlit2;
201 }
202
203 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
204 {
205         const VkImageResolve2KHR        imageResolve2 =
206         {
207                 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,          // VkStructureType                              sType;
208                 DE_NULL,                                                                        // const void*                                  pNext;
209                 imageResolve.srcSubresource,                            // VkImageSubresourceLayers             srcSubresource;
210                 imageResolve.srcOffset,                                         // VkOffset3D                                   srcOffset;
211                 imageResolve.dstSubresource,                            // VkImageSubresourceLayers             dstSubresource;
212                 imageResolve.dstOffset,                                         // VkOffset3D                                   dstOffset;
213                 imageResolve.extent                                                     // VkExtent3D                                   extent;
214         };
215         return imageResolve2;
216 }
217
218 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
219 {
220         VkImageAspectFlags      aspectFlag      = 0;
221         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
222         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
223
224         if (!aspectFlag)
225                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
226
227         return aspectFlag;
228 }
229
230 VkImageAspectFlags getAspectFlags (VkFormat format)
231 {
232         if (isCompressedFormat(format))
233                 return VK_IMAGE_ASPECT_COLOR_BIT;
234         else
235                 return getAspectFlags(mapVkFormat(format));
236 }
237
238 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
239 {
240         if (isCompressedFormat(format))
241                 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
242         else
243                 return mapVkFormat(format);
244 }
245
246 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
247 // except that it supports some formats that are not mappable to VkFormat.
248 // When we are checking combined depth and stencil formats, each aspect is
249 // checked separately, and in some cases we construct PBA with a format that
250 // is not mappable to VkFormat.
251 bool isFloatFormat (tcu::TextureFormat format)
252 {
253         return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
254 }
255
256 union CopyRegion
257 {
258         VkBufferCopy                    bufferCopy;
259         VkImageCopy                             imageCopy;
260         VkBufferImageCopy               bufferImageCopy;
261         VkImageBlit                             imageBlit;
262         VkImageResolve                  imageResolve;
263 };
264
265 struct ImageParms
266 {
267         VkImageType                     imageType;
268         VkFormat                        format;
269         VkExtent3D                      extent;
270         VkImageTiling           tiling;
271         VkImageLayout           operationLayout;
272         VkImageCreateFlags      createFlags;
273         FillMode                        fillMode;
274 };
275
276 struct TestParams
277 {
278         union Data
279         {
280                 struct Buffer
281                 {
282                         VkDeviceSize    size;
283                 } buffer;
284
285                 ImageParms      image;
286         } src, dst;
287
288         std::vector<CopyRegion> regions;
289
290         union
291         {
292                 VkFilter                                filter;
293                 VkSampleCountFlagBits   samples;
294         };
295
296         AllocationKind  allocationKind;
297         ExtensionUse    extensionUse;
298         deUint32                mipLevels;
299         deBool                  singleCommand;
300         deUint32                barrierCount;
301         deBool                  separateDepthStencilLayouts;
302         deBool                  clearDestination;
303
304         TestParams (void)
305         {
306                 allocationKind                          = ALLOCATION_KIND_DEDICATED;
307                 extensionUse                            = EXTENSION_USE_NONE;
308                 mipLevels                                       = 1u;
309                 singleCommand                           = DE_TRUE;
310                 barrierCount                            = 1u;
311                 separateDepthStencilLayouts     = DE_FALSE;
312                 src.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
313                 dst.image.createFlags           = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
314                 src.image.fillMode                      = FILL_MODE_GRADIENT;
315                 dst.image.fillMode                      = FILL_MODE_WHITE;
316                 clearDestination                        = DE_FALSE;
317                 samples                                         = VK_SAMPLE_COUNT_1_BIT;
318         }
319 };
320
321 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&        vki,
322                                                                                 const DeviceInterface&          vkd,
323                                                                                 const VkPhysicalDevice&         physDevice,
324                                                                                 const VkDevice                          device,
325                                                                                 const VkBuffer&                         buffer,
326                                                                                 const MemoryRequirement         requirement,
327                                                                                 Allocator&                                      allocator,
328                                                                                 AllocationKind                          allocationKind)
329 {
330         switch (allocationKind)
331         {
332                 case ALLOCATION_KIND_SUBALLOCATED:
333                 {
334                         const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
335
336                         return allocator.allocate(memoryRequirements, requirement);
337                 }
338
339                 case ALLOCATION_KIND_DEDICATED:
340                 {
341                         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
342                 }
343
344                 default:
345                 {
346                         TCU_THROW(InternalError, "Invalid allocation kind");
347                 }
348         }
349 }
350
351 de::MovePtr<Allocation> allocateImage (const InstanceInterface&         vki,
352                                                                            const DeviceInterface&               vkd,
353                                                                            const VkPhysicalDevice&              physDevice,
354                                                                            const VkDevice                               device,
355                                                                            const VkImage&                               image,
356                                                                            const MemoryRequirement              requirement,
357                                                                            Allocator&                                   allocator,
358                                                                            AllocationKind                               allocationKind)
359 {
360         switch (allocationKind)
361         {
362                 case ALLOCATION_KIND_SUBALLOCATED:
363                 {
364                         const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
365
366                         return allocator.allocate(memoryRequirements, requirement);
367                 }
368
369                 case ALLOCATION_KIND_DEDICATED:
370                 {
371                         return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
372                 }
373
374                 default:
375                 {
376                         TCU_THROW(InternalError, "Invalid allocation kind");
377                 }
378         }
379 }
380
381
382 inline deUint32 getArraySize(const ImageParms& parms)
383 {
384         return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
385 }
386
387 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
388 {
389         if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
390                 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
391         else
392                 return parms.createFlags;
393 }
394
395 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
396 {
397         const bool                      isCompressed    = isCompressedFormat(parms.format);
398         const deUint32          blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
399         const deUint32          blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
400
401         if (isCompressed && mipLevel != 0u)
402                 DE_FATAL("Not implemented");
403
404         const VkExtent3D        extent                  =
405         {
406                 (parms.extent.width >> mipLevel) * blockWidth,
407                 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
408                 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
409         };
410         return extent;
411 }
412
413 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
414 {
415         tcu::TextureFormat format;
416         switch (combinedFormat.type)
417         {
418                 case tcu::TextureFormat::UNORM_INT16:
419                 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
420                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
421                         break;
422                 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
423                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
424                         break;
425                 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
426                 case tcu::TextureFormat::FLOAT:
427                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
428                         break;
429                 default:
430                         DE_ASSERT(false);
431                         break;
432         }
433         return format;
434 }
435
436 class CopiesAndBlittingTestInstance : public vkt::TestInstance
437 {
438 public:
439                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
440                                                                                                                                                          TestParams     testParams);
441         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
442
443 protected:
444         const TestParams                                        m_params;
445
446         Move<VkCommandPool>                                     m_cmdPool;
447         Move<VkCommandBuffer>                           m_cmdBuffer;
448         Move<VkFence>                                           m_fence;
449         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
450         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
451         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel[16];
452
453         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
454
455         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
456         virtual void                                            generateExpectedResult                          (void);
457         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
458         void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
459         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
460         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
461         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
462                                                                                 {
463                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
464                                                                                 }
465
466         de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
467                                                                                                                                                          const ImageParms&                      imageParms,
468                                                                                                                                                          const deUint32                         mipLevel = 0u);
469
470 private:
471         void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
472                                                                                                                                                          const VkImage&                                         dst,
473                                                                                                                                                          const ImageParms&                                      parms,
474                                                                                                                                                          const deUint32                                         mipLevels = 1u);
475         void                                                            readImageAspect                                         (vk::VkImage                                            src,
476                                                                                                                                                          const tcu::PixelBufferAccess&          dst,
477                                                                                                                                                          const ImageParms&                                      parms,
478                                                                                                                                                          const deUint32                                         mipLevel = 0u);
479 };
480
481 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
482         : vkt::TestInstance     (context)
483         , m_params                      (testParams)
484 {
485         const DeviceInterface&          vk                                      = context.getDeviceInterface();
486         const VkDevice                          vkDevice                        = context.getDevice();
487         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
488
489         // Create command pool
490         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
491
492         // Create command buffer
493         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
494
495         // Create fence
496         m_fence = createFence(vk, vkDevice);
497 }
498
499 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
500 {
501         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(buffer.getFormat().type);
502         tcu::Vec4                                               maxValue                (1.0f);
503
504         if (buffer.getFormat().order == tcu::TextureFormat::S)
505         {
506                 // Stencil-only is stored in the first component. Stencil is always 8 bits.
507                 maxValue.x() = 1 << 8;
508         }
509         else if (buffer.getFormat().order == tcu::TextureFormat::DS)
510         {
511                 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
512                 maxValue.w() = 1 << 8;
513         }
514         else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
515         {
516                 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
517                 const tcu::IVec4        bits    = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
518                 const int                       signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
519
520                 for (int i = 0; i < 4; ++i)
521                 {
522                         if (bits[i] != 0)
523                                 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
524                 }
525         }
526
527         if (mode == FILL_MODE_GRADIENT)
528         {
529                 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
530                 return;
531         }
532
533         const tcu::Vec4         redColor        (maxValue.x(),  0.0,                    0.0,                    maxValue.w());
534         const tcu::Vec4         greenColor      (0.0,                   maxValue.y(),   0.0,                    maxValue.w());
535         const tcu::Vec4         blueColor       (0.0,                   0.0,                    maxValue.z(),   maxValue.w());
536         const tcu::Vec4         whiteColor      (maxValue.x(),  maxValue.y(),   maxValue.z(),   maxValue.w());
537
538         for (int z = 0; z < depth;  ++z)
539         for (int y = 0; y < height; ++y)
540         for (int x = 0; x < width;  ++x)
541         {
542                 switch (mode)
543                 {
544                         case FILL_MODE_WHITE:
545                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
546                                 {
547                                         buffer.setPixDepth(1.0f, x, y, z);
548                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
549                                                 buffer.setPixStencil(255, x, y, z);
550                                 }
551                                 else
552                                         buffer.setPixel(whiteColor, x, y, z);
553                                 break;
554
555                         case FILL_MODE_RED:
556                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
557                                 {
558                                         buffer.setPixDepth(redColor[0], x, y, z);
559                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
560                                                 buffer.setPixStencil((int)redColor[3], x, y, z);
561                                 }
562                                 else
563                                         buffer.setPixel(redColor, x, y, z);
564                                 break;
565
566                         case FILL_MODE_BLUE_RED_X:
567                         case FILL_MODE_BLUE_RED_Y:
568                         case FILL_MODE_BLUE_RED_Z:
569                                 bool useBlue;
570                                 switch (mode)
571                                 {
572                                         case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
573                                         case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
574                                         case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
575                                         default: DE_ASSERT(false); break;
576                                 }
577                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
578                                 {
579                                         buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
580                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
581                                                 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
582                                 }
583                                 else
584                                         buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
585                                 break;
586
587                         case FILL_MODE_MULTISAMPLE:
588                         {
589                                 float xScaled = static_cast<float>(x) / static_cast<float>(width);
590                                 float yScaled = static_cast<float>(y) / static_cast<float>(height);
591                                 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
592                                 break;
593                         }
594
595                         default:
596                                 break;
597                 }
598         }
599 }
600
601 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
602 {
603         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
604         const VkDevice                          vkDevice        = m_context.getDevice();
605         const deUint32                          bufferSize      = calculateSize(bufferAccess);
606
607         // Write buffer data
608         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
609         flushAlloc(vk, vkDevice, bufferAlloc);
610 }
611
612 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
613 {
614         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
615         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
616         const VkPhysicalDevice                  vkPhysDevice            = m_context.getPhysicalDevice();
617         const VkDevice                                  vkDevice                        = m_context.getDevice();
618         const VkQueue                                   queue                           = m_context.getUniversalQueue();
619         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
620         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
621         Move<VkBuffer>                                  buffer;
622         const deUint32                                  bufferSize                      = calculateSize(imageAccess);
623         de::MovePtr<Allocation>                 bufferAlloc;
624         const deUint32                                  arraySize                       = getArraySize(parms);
625         const VkExtent3D                                imageExtent                     = getExtent3D(parms);
626         std::vector <VkBufferImageCopy> copyRegions;
627
628         // Create source buffer
629         {
630                 const VkBufferCreateInfo        bufferParams            =
631                 {
632                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
633                         DE_NULL,                                                                        // const void*                  pNext;
634                         0u,                                                                                     // VkBufferCreateFlags  flags;
635                         bufferSize,                                                                     // VkDeviceSize                 size;
636                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
637                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
638                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
639                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
640                 };
641
642                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
643                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
644                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
645         }
646
647         // Barriers for copying buffer to image
648         const VkBufferMemoryBarrier             preBufferBarrier        =
649         {
650                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
651                 DE_NULL,                                                                                // const void*          pNext;
652                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
653                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
654                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
655                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
656                 *buffer,                                                                                // VkBuffer                     buffer;
657                 0u,                                                                                             // VkDeviceSize         offset;
658                 bufferSize                                                                              // VkDeviceSize         size;
659         };
660
661         const VkImageAspectFlags                formatAspect            = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
662         const bool                                              skipPreImageBarrier     = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
663                                                                                                                   getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
664
665         const VkImageMemoryBarrier              preImageBarrier         =
666         {
667                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
668                 DE_NULL,                                                                                // const void*                          pNext;
669                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
670                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
671                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
672                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
673                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
674                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
675                 image,                                                                                  // VkImage                                      image;
676                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
677                         formatAspect,   // VkImageAspectFlags   aspect;
678                         0u,                             // deUint32                             baseMipLevel;
679                         mipLevels,              // deUint32                             mipLevels;
680                         0u,                             // deUint32                             baseArraySlice;
681                         arraySize,              // deUint32                             arraySize;
682                 }
683         };
684
685         const VkImageMemoryBarrier              postImageBarrier        =
686         {
687                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
688                 DE_NULL,                                                                                // const void*                          pNext;
689                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
690                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
691                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
692                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
693                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
694                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
695                 image,                                                                                  // VkImage                                      image;
696                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
697                         formatAspect,                           // VkImageAspectFlags   aspect;
698                         0u,                                                     // deUint32                             baseMipLevel;
699                         mipLevels,                                      // deUint32                             mipLevels;
700                         0u,                                                     // deUint32                             baseArraySlice;
701                         arraySize,                                      // deUint32                             arraySize;
702                 }
703         };
704
705         for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
706         {
707                 const VkExtent3D                copyExtent      =
708                 {
709                         imageExtent.width       >> mipLevelNdx,
710                         imageExtent.height      >> mipLevelNdx,
711                         imageExtent.depth
712                 };
713
714                 const bool              isCompressed    = isCompressedFormat(parms.format);
715                 const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(parms.format) : 1u;
716                 const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(parms.format) : 1u;
717                 deUint32 rowLength              = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
718                 deUint32 imageHeight    = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
719
720                 const VkBufferImageCopy copyRegion      =
721                 {
722                         0u,                                                                                             // VkDeviceSize                         bufferOffset;
723                         rowLength,                                                                              // deUint32                                     bufferRowLength;
724                         imageHeight,                                                                    // deUint32                                     bufferImageHeight;
725                         {
726                                 getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
727                                 mipLevelNdx,                                                                    // deUint32                             mipLevel;
728                                 0u,                                                                                             // deUint32                             baseArrayLayer;
729                                 arraySize,                                                                              // deUint32                             layerCount;
730                         },                                                                                              // VkImageSubresourceLayers     imageSubresource;
731                         { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
732                         copyExtent                                                                              // VkExtent3D                           imageExtent;
733                 };
734
735                 copyRegions.push_back(copyRegion);
736         }
737
738         // Write buffer data
739         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
740         flushAlloc(vk, vkDevice, *bufferAlloc);
741
742         // Copy buffer to image
743         beginCommandBuffer(vk, *m_cmdBuffer);
744         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
745                                                   1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
746         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
747         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);
748         endCommandBuffer(vk, *m_cmdBuffer);
749
750         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
751 }
752
753 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
754 {
755         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
756         {
757                 if (tcu::hasDepthComponent(src.getFormat().order))
758                 {
759                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
760                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
761                         uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
762                 }
763
764                 if (tcu::hasStencilComponent(src.getFormat().order))
765                 {
766                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
767                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
768                         uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
769                 }
770         }
771         else
772                 uploadImageAspect(src, dst, parms, mipLevels);
773 }
774
775 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
776 {
777         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel[0]->getAccess();
778
779         if (isFloatFormat(result.getFormat()))
780         {
781                 const tcu::Vec4 threshold (0.0f);
782                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
783                         return tcu::TestStatus::fail("CopiesAndBlitting test");
784         }
785         else
786         {
787                 const tcu::UVec4 threshold (0u);
788                 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
789                 {
790                         if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
791                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
792                 }
793                 else
794                 {
795                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
796                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
797                 }
798         }
799
800         return tcu::TestStatus::pass("CopiesAndBlitting test");
801 }
802
803 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
804 {
805         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
806         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
807
808         m_expectedTextureLevel[0]       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
809         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
810
811         for (deUint32 i = 0; i < m_params.regions.size(); i++)
812                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
813 }
814
815 class CopiesAndBlittingTestCase : public vkt::TestCase
816 {
817 public:
818                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
819                                                                                                                  const std::string&                     name,
820                                                                                                                  const std::string&                     description)
821                                                                 : vkt::TestCase (testCtx, name, description)
822                                                         {}
823
824         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
825 };
826
827 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                        image,
828                                                                                                          const tcu::PixelBufferAccess&  dst,
829                                                                                                          const ImageParms&                              imageParms,
830                                                                                                          const deUint32                                 mipLevel)
831 {
832         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
833         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
834         const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
835         const VkDevice                          device                          = m_context.getDevice();
836         const VkQueue                           queue                           = m_context.getUniversalQueue();
837         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
838
839         Move<VkBuffer>                          buffer;
840         de::MovePtr<Allocation>         bufferAlloc;
841         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
842         const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
843         const VkExtent3D                        imageExtent                     = getExtent3D(imageParms, mipLevel);
844
845         // Create destination buffer
846         {
847                 const VkBufferCreateInfo                        bufferParams                    =
848                 {
849                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
850                         DE_NULL,                                                                        // const void*                  pNext;
851                         0u,                                                                                     // VkBufferCreateFlags  flags;
852                         pixelDataSize,                                                          // VkDeviceSize                 size;
853                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
854                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
855                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
856                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
857                 };
858
859                 buffer          = createBuffer(vk, device, &bufferParams);
860                 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
861                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
862
863                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
864                 flushAlloc(vk, device, *bufferAlloc);
865         }
866
867         // Barriers for copying image to buffer
868         const VkImageAspectFlags                                formatAspect                    = getAspectFlags(imageParms.format);
869         const VkImageMemoryBarrier                              imageBarrier                    =
870         {
871                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
872                 DE_NULL,                                                                        // const void*                          pNext;
873                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
874                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
875                 imageParms.operationLayout,                                     // VkImageLayout                        oldLayout;
876                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
877                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
878                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
879                 image,                                                                          // VkImage                                      image;
880                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
881                         formatAspect,                   // VkImageAspectFlags   aspectMask;
882                         mipLevel,                               // deUint32                             baseMipLevel;
883                         1u,                                             // deUint32                             mipLevels;
884                         0u,                                             // deUint32                             baseArraySlice;
885                         getArraySize(imageParms)// deUint32                             arraySize;
886                 }
887         };
888
889         const VkBufferMemoryBarrier                             bufferBarrier                   =
890         {
891                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
892                 DE_NULL,                                                                        // const void*          pNext;
893                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
894                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
895                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
896                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
897                 *buffer,                                                                        // VkBuffer                     buffer;
898                 0u,                                                                                     // VkDeviceSize         offset;
899                 pixelDataSize                                                           // VkDeviceSize         size;
900         };
901
902         const VkImageMemoryBarrier                              postImageBarrier                =
903         {
904                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
905                 DE_NULL,                                                                        // const void*                          pNext;
906                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
907                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
908                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        oldLayout;
909                 imageParms.operationLayout,                                     // VkImageLayout                        newLayout;
910                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
911                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
912                 image,                                                                          // VkImage                                      image;
913                 {
914                         formatAspect,                                                           // VkImageAspectFlags   aspectMask;
915                         mipLevel,                                                                       // deUint32                             baseMipLevel;
916                         1u,                                                                                     // deUint32                             mipLevels;
917                         0u,                                                                                     // deUint32                             baseArraySlice;
918                         getArraySize(imageParms)                                        // deUint32                             arraySize;
919                 }                                                                                       // VkImageSubresourceRange      subresourceRange;
920         };
921
922         // Copy image to buffer
923         const bool              isCompressed    = isCompressedFormat(imageParms.format);
924         const deUint32  blockWidth              = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
925         const deUint32  blockHeight             = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
926         deUint32 rowLength              = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
927         deUint32 imageHeight    = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
928
929         // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
930         const VkImageAspectFlags        aspect                  = isCompressedFormat(m_params.dst.image.format) ?
931                                                                                                         static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
932         const VkBufferImageCopy         copyRegion              =
933         {
934                 0u,                                                             // VkDeviceSize                         bufferOffset;
935                 rowLength,                                              // deUint32                                     bufferRowLength;
936                 imageHeight,                                    // deUint32                                     bufferImageHeight;
937                 {
938                         aspect,                                                 // VkImageAspectFlags           aspect;
939                         mipLevel,                                               // deUint32                                     mipLevel;
940                         0u,                                                             // deUint32                                     baseArrayLayer;
941                         getArraySize(imageParms),               // deUint32                                     layerCount;
942                 },                                                              // VkImageSubresourceLayers     imageSubresource;
943                 { 0, 0, 0 },                                    // VkOffset3D                           imageOffset;
944                 imageExtent                                             // VkExtent3D                           imageExtent;
945         };
946
947         beginCommandBuffer(vk, *m_cmdBuffer);
948         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);
949         vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
950         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);
951         endCommandBuffer(vk, *m_cmdBuffer);
952
953         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
954
955         // Read buffer data
956         invalidateAlloc(vk, device, *bufferAlloc);
957         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
958 }
959
960 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage            image,
961                                                                                                                                                  const ImageParms&      parms,
962                                                                                                                                                  const deUint32         mipLevel)
963 {
964         const tcu::TextureFormat                imageFormat     = getSizeCompatibleTcuTextureFormat(parms.format);
965         de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
966
967         if (tcu::isCombinedDepthStencilType(imageFormat.type))
968         {
969                 if (tcu::hasDepthComponent(imageFormat.order))
970                 {
971                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
972                         readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
973                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
974                 }
975
976                 if (tcu::hasStencilComponent(imageFormat.order))
977                 {
978                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
979                         readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
980                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
981                 }
982         }
983         else
984                 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
985
986         return resultLevel;
987 }
988
989 // Copy from image to image.
990
991 class CopyImageToImage : public CopiesAndBlittingTestInstance
992 {
993 public:
994                                                                                 CopyImageToImage                        (Context&       context,
995                                                                                                                                          TestParams params);
996         virtual tcu::TestStatus                         iterate                                         (void);
997
998 protected:
999         virtual tcu::TestStatus                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1000
1001 private:
1002         Move<VkImage>                                           m_source;
1003         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1004         Move<VkImage>                                           m_destination;
1005         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1006
1007         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1008 };
1009
1010 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1011         : CopiesAndBlittingTestInstance(context, params)
1012 {
1013         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1014         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1015         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1016         const VkDevice                          vkDevice                        = context.getDevice();
1017         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1018         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1019
1020         // Create source image
1021         {
1022                 const VkImageCreateInfo sourceImageParams               =
1023                 {
1024                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1025                         DE_NULL,                                                                // const void*                  pNext;
1026                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1027                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1028                         m_params.src.image.format,                              // VkFormat                             format;
1029                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1030                         1u,                                                                             // deUint32                             mipLevels;
1031                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1032                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1033                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1034                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1035                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1036                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1037                         1u,                                                                             // deUint32                             queueFamilyCount;
1038                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1039                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1040                 };
1041
1042                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
1043                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1044                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1045         }
1046
1047         // Create destination image
1048         {
1049                 const VkImageCreateInfo destinationImageParams  =
1050                 {
1051                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1052                         DE_NULL,                                                                // const void*                  pNext;
1053                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1054                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1055                         m_params.dst.image.format,                              // VkFormat                             format;
1056                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1057                         1u,                                                                             // deUint32                             mipLevels;
1058                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1059                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1060                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1061                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1062                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1063                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1064                         1u,                                                                             // deUint32                             queueFamilyCount;
1065                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1066                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1067                 };
1068
1069                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1070                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1071                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1072         }
1073 }
1074
1075 tcu::TestStatus CopyImageToImage::iterate (void)
1076 {
1077         const bool                                      srcCompressed           = isCompressedFormat(m_params.src.image.format);
1078         const bool                                      dstCompressed           = isCompressedFormat(m_params.dst.image.format);
1079
1080         const tcu::TextureFormat        srcTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1081         const tcu::TextureFormat        dstTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1082
1083         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1084                                                                                                                                                                 (int)m_params.src.image.extent.width,
1085                                                                                                                                                                 (int)m_params.src.image.extent.height,
1086                                                                                                                                                                 (int)m_params.src.image.extent.depth));
1087         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);
1088         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1089                                                                                                                                                                 (int)m_params.dst.image.extent.width,
1090                                                                                                                                                                 (int)m_params.dst.image.extent.height,
1091                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
1092         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);
1093         generateExpectedResult();
1094
1095         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1096         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1097
1098         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1099         const VkDevice                          vkDevice                        = m_context.getDevice();
1100         const VkQueue                           queue                           = m_context.getUniversalQueue();
1101
1102         std::vector<VkImageCopy>                imageCopies;
1103         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
1104         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1105         {
1106                 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1107
1108                 // When copying between compressed and uncompressed formats the extent
1109                 // members represent the texel dimensions of the source image.
1110                 if (srcCompressed)
1111                 {
1112                         const deUint32  blockWidth      = getBlockWidth(m_params.src.image.format);
1113                         const deUint32  blockHeight     = getBlockHeight(m_params.src.image.format);
1114
1115                         imageCopy.srcOffset.x *= blockWidth;
1116                         imageCopy.srcOffset.y *= blockHeight;
1117                         imageCopy.extent.width *= blockWidth;
1118                         imageCopy.extent.height *= blockHeight;
1119                 }
1120
1121                 if (dstCompressed)
1122                 {
1123                         const deUint32  blockWidth      = getBlockWidth(m_params.dst.image.format);
1124                         const deUint32  blockHeight     = getBlockHeight(m_params.dst.image.format);
1125
1126                         imageCopy.dstOffset.x *= blockWidth;
1127                         imageCopy.dstOffset.y *= blockHeight;
1128                 }
1129
1130                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1131                 {
1132                         imageCopies.push_back(imageCopy);
1133                 }
1134                 else
1135                 {
1136                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1137                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1138                 }
1139         }
1140
1141         const VkImageMemoryBarrier      imageBarriers[]         =
1142         {
1143                 // source image
1144                 {
1145                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1146                         DE_NULL,                                                                        // const void*                          pNext;
1147                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1148                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1149                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1150                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1151                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1152                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1153                         m_source.get(),                                                         // VkImage                                      image;
1154                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1155                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1156                                 0u,                                                             // deUint32                             baseMipLevel;
1157                                 1u,                                                             // deUint32                             mipLevels;
1158                                 0u,                                                             // deUint32                             baseArraySlice;
1159                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
1160                         }
1161                 },
1162                 // destination image
1163                 {
1164                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1165                         DE_NULL,                                                                        // const void*                          pNext;
1166                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1167                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1168                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1169                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1170                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1171                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1172                         m_destination.get(),                                            // VkImage                                      image;
1173                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1174                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1175                                 0u,                                                             // deUint32                             baseMipLevel;
1176                                 1u,                                                             // deUint32                             mipLevels;
1177                                 0u,                                                             // deUint32                             baseArraySlice;
1178                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
1179                         }
1180                 },
1181         };
1182
1183         beginCommandBuffer(vk, *m_cmdBuffer);
1184         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);
1185
1186         if (m_params.clearDestination)
1187         {
1188                 VkImageSubresourceRange range           = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1189                 VkClearColorValue               clearColor;
1190
1191                 clearColor.float32[0] = 1.0f;
1192                 clearColor.float32[1] = 1.0f;
1193                 clearColor.float32[2] = 1.0f;
1194                 clearColor.float32[3] = 1.0f;
1195                 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1196         }
1197
1198         if (m_params.extensionUse == EXTENSION_USE_NONE)
1199         {
1200                 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());
1201         }
1202         else
1203         {
1204                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1205                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1206                 {
1207                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
1208                         DE_NULL,                                                                        // const void*                          pNext;
1209                         m_source.get(),                                                         // VkImage                                      srcImage;
1210                         m_params.src.image.operationLayout,                     // VkImageLayout                        srcImageLayout;
1211                         m_destination.get(),                                            // VkImage                                      dstImage;
1212                         m_params.dst.image.operationLayout,                     // VkImageLayout                        dstImageLayout;
1213                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
1214                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
1215                 };
1216
1217                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1218         }
1219
1220         endCommandBuffer(vk, *m_cmdBuffer);
1221
1222         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1223
1224         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
1225
1226         return checkTestResult(resultTextureLevel->getAccess());
1227 }
1228
1229 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1230 {
1231         const tcu::Vec4 fThreshold (0.0f);
1232         const tcu::UVec4 uThreshold (0u);
1233
1234         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1235         {
1236                 if (tcu::hasDepthComponent(result.getFormat().order))
1237                 {
1238                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1239                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1240                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1241
1242                         if (isFloatFormat(result.getFormat()))
1243                         {
1244                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1245                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1246                         }
1247                         else
1248                         {
1249                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1250                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1251                         }
1252                 }
1253
1254                 if (tcu::hasStencilComponent(result.getFormat().order))
1255                 {
1256                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1257                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1258                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1259
1260                         if (isFloatFormat(result.getFormat()))
1261                         {
1262                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1263                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1264                         }
1265                         else
1266                         {
1267                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1268                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1269                         }
1270                 }
1271         }
1272         else
1273         {
1274                 if (isFloatFormat(result.getFormat()))
1275                 {
1276                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1277                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1278                 }
1279                 else
1280                 {
1281                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1282                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1283                 }
1284         }
1285
1286         return tcu::TestStatus::pass("CopiesAndBlitting test");
1287 }
1288
1289 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1290 {
1291         DE_UNREF(mipLevel);
1292
1293         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1294         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1295         VkExtent3D      extent          = region.imageCopy.extent;
1296
1297         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1298         {
1299                 dstOffset.z = srcOffset.z;
1300                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1301         }
1302         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1303         {
1304                 srcOffset.z = dstOffset.z;
1305                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1306         }
1307
1308
1309         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1310         {
1311                 DE_ASSERT(src.getFormat() == dst.getFormat());
1312
1313                 // Copy depth.
1314                 if (tcu::hasDepthComponent(src.getFormat().order))
1315                 {
1316                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1317                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1318                         tcu::copy(dstSubRegion, srcSubRegion);
1319                 }
1320
1321                 // Copy stencil.
1322                 if (tcu::hasStencilComponent(src.getFormat().order))
1323                 {
1324                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1325                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1326                         tcu::copy(dstSubRegion, srcSubRegion);
1327                 }
1328         }
1329         else
1330         {
1331                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1332                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1333                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1334                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1335
1336                 tcu::copy(dstSubRegion, srcSubRegion);
1337         }
1338 }
1339
1340 class CopyImageToImageTestCase : public vkt::TestCase
1341 {
1342 public:
1343                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
1344                                                                                                                  const std::string&                             name,
1345                                                                                                                  const std::string&                             description,
1346                                                                                                                  const TestParams                               params)
1347                                                                 : vkt::TestCase (testCtx, name, description)
1348                                                                 , m_params              (params)
1349         {}
1350
1351         virtual TestInstance*   createInstance                          (Context&                                               context) const
1352         {
1353                 return new CopyImageToImage(context, m_params);
1354         }
1355
1356         virtual void                    checkSupport                            (Context&                                               context) const
1357         {
1358                 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1359                 {
1360                         if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1361                                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1362                 }
1363
1364                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1365                 {
1366                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1367                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1368                 }
1369
1370                 if (m_params.separateDepthStencilLayouts)
1371                         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1372                                 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1373
1374                 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1375                         (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1376                 {
1377                         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1378                                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1379                 }
1380
1381                 const VkPhysicalDeviceLimits    limits          = context.getDeviceProperties().limits;
1382                 VkImageFormatProperties                 properties;
1383
1384                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1385                                                                                                                                                                         m_params.src.image.format,
1386                                                                                                                                                                         m_params.src.image.imageType,
1387                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1388                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1389                                                                                                                                                                         0,
1390                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1391                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1392                                                                                                                                                                         m_params.dst.image.format,
1393                                                                                                                                                                         m_params.dst.image.imageType,
1394                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1395                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1396                                                                                                                                                                         0,
1397                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1398                 {
1399                         TCU_THROW(NotSupportedError, "Format not supported");
1400                 }
1401
1402                 // Check maxImageDimension1D
1403                 {
1404                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1405                                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1406
1407                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1408                                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1409                 }
1410
1411                 // Check maxImageDimension2D
1412                 {
1413                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1414                                 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1415                         {
1416                                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1417                         }
1418
1419                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1420                                 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1421                         {
1422                                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1423                         }
1424                 }
1425
1426                 // Check maxImageDimension3D
1427                 {
1428                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1429                                 || m_params.src.image.extent.height > limits.maxImageDimension3D
1430                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1431                         {
1432                                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1433                         }
1434
1435                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1436                                 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1437                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1438                         {
1439                                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1440                         }
1441                 }
1442         }
1443
1444 private:
1445         TestParams                              m_params;
1446 };
1447
1448 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1449 {
1450 public:
1451                                                                                 CopyImageToImageMipmap          (Context&       context,
1452                                                                                                                                          TestParams params);
1453         virtual tcu::TestStatus                         iterate                                         (void);
1454
1455 protected:
1456         tcu::TestStatus                                         checkResult                                     (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1457
1458 private:
1459         Move<VkImage>                                           m_source;
1460         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1461         Move<VkImage>                                           m_destination;
1462         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1463
1464         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1465
1466 };
1467
1468 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1469         : CopiesAndBlittingTestInstance(context, params)
1470 {
1471         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1472         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1473         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1474         const VkDevice                          vkDevice                        = context.getDevice();
1475         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1476         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1477
1478         // Create source image
1479         {
1480                 const VkImageCreateInfo sourceImageParams               =
1481                 {
1482                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1483                         DE_NULL,                                                                // const void*                  pNext;
1484                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
1485                         m_params.src.image.imageType,                   // VkImageType                  imageType;
1486                         m_params.src.image.format,                              // VkFormat                             format;
1487                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
1488                         params.mipLevels,                                               // deUint32                             mipLevels;
1489                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
1490                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1491                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1492                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1493                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1494                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1495                         1u,                                                                             // deUint32                             queueFamilyCount;
1496                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1497                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1498                 };
1499
1500                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
1501                 m_sourceImageAlloc              = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1502                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1503         }
1504
1505         // Create destination image
1506         {
1507                 const VkImageCreateInfo destinationImageParams  =
1508                 {
1509                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1510                         DE_NULL,                                                                // const void*                  pNext;
1511                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
1512                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
1513                         m_params.dst.image.format,                              // VkFormat                             format;
1514                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
1515                         params.mipLevels,                                               // deUint32                             mipLevels;
1516                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
1517                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1518                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1519                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1520                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1521                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1522                         1u,                                                                             // deUint32                             queueFamilyCount;
1523                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1524                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1525                 };
1526
1527                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1528                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1529                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1530         }
1531 }
1532
1533 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1534 {
1535         const bool                                      srcCompressed           = isCompressedFormat(m_params.src.image.format);
1536         const bool                                      dstCompressed           = isCompressedFormat(m_params.dst.image.format);
1537
1538         const tcu::TextureFormat        srcTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1539         const tcu::TextureFormat        dstTcuFormat            = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1540
1541         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1542                                                                                                                                                                 (int)m_params.src.image.extent.width,
1543                                                                                                                                                                 (int)m_params.src.image.extent.height,
1544                                                                                                                                                                 (int)m_params.src.image.extent.depth));
1545         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);
1546         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1547
1548         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1549                                                                                                                                                                          (int)m_params.dst.image.extent.width,
1550                                                                                                                                                                          (int)m_params.dst.image.extent.height,
1551                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
1552         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);
1553         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1554
1555         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1556         const VkDevice                          vkDevice                        = m_context.getDevice();
1557         const VkQueue                           queue                           = m_context.getUniversalQueue();
1558
1559         std::vector<VkImageCopy>                imageCopies;
1560         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
1561         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1562         {
1563                 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1564
1565                 // When copying between compressed and uncompressed formats the extent
1566                 // members represent the texel dimensions of the source image.
1567                 if (srcCompressed)
1568                 {
1569                         const deUint32  blockWidth      = getBlockWidth(m_params.src.image.format);
1570                         const deUint32  blockHeight     = getBlockHeight(m_params.src.image.format);
1571
1572                         imageCopy.srcOffset.x *= blockWidth;
1573                         imageCopy.srcOffset.y *= blockHeight;
1574                         imageCopy.extent.width *= blockWidth;
1575                         imageCopy.extent.height *= blockHeight;
1576                 }
1577
1578                 if (dstCompressed)
1579                 {
1580                         const deUint32  blockWidth      = getBlockWidth(m_params.dst.image.format);
1581                         const deUint32  blockHeight     = getBlockHeight(m_params.dst.image.format);
1582
1583                         imageCopy.dstOffset.x *= blockWidth;
1584                         imageCopy.dstOffset.y *= blockHeight;
1585                 }
1586
1587                 if (m_params.extensionUse == EXTENSION_USE_NONE)
1588                 {
1589                         imageCopies.push_back(imageCopy);
1590                 }
1591                 else
1592                 {
1593                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1594                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1595                 }
1596         }
1597
1598         const VkImageMemoryBarrier      imageBarriers[]         =
1599         {
1600                 // source image
1601                 {
1602                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1603                         DE_NULL,                                                                        // const void*                          pNext;
1604                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1605                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1606                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1607                         m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
1608                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1609                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1610                         m_source.get(),                                                         // VkImage                                      image;
1611                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1612                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1613                                 0u,                                                             // deUint32                             baseMipLevel;
1614                                 m_params.mipLevels,                             // deUint32                             mipLevels;
1615                                 0u,                                                             // deUint32                             baseArraySlice;
1616                                 getArraySize(m_params.src.image)// deUint32                             arraySize;
1617                         }
1618                 },
1619                 // destination image
1620                 {
1621                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1622                         DE_NULL,                                                                        // const void*                          pNext;
1623                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1624                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1625                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1626                         m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
1627                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1628                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1629                         m_destination.get(),                                            // VkImage                                      image;
1630                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
1631                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1632                                 0u,                                                             // deUint32                             baseMipLevel;
1633                                 m_params.mipLevels,                             // deUint32                             mipLevels;
1634                                 0u,                                                             // deUint32                             baseArraySlice;
1635                                 getArraySize(m_params.dst.image)// deUint32                             arraySize;
1636                         }
1637                 },
1638         };
1639
1640         beginCommandBuffer(vk, *m_cmdBuffer);
1641         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);
1642
1643         if (m_params.extensionUse == EXTENSION_USE_NONE)
1644         {
1645                 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());
1646         }
1647         else
1648         {
1649                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1650                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1651                 {
1652                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
1653                         DE_NULL,                                                                        // const void*                          pNext;
1654                         m_source.get(),                                                         // VkImage                                      srcImage;
1655                         m_params.src.image.operationLayout,                     // VkImageLayout                        srcImageLayout;
1656                         m_destination.get(),                                            // VkImage                                      dstImage;
1657                         m_params.dst.image.operationLayout,                     // VkImageLayout                        dstImageLayout;
1658                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
1659                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
1660                 };
1661
1662                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1663         }
1664
1665         endCommandBuffer(vk, *m_cmdBuffer);
1666
1667         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1668
1669         for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1670         {
1671                 de::MovePtr<tcu::TextureLevel>  resultTextureLevel              = readImage(*m_destination, m_params.dst.image, miplevel);
1672                 de::MovePtr<tcu::TextureLevel>  expectedTextureLevel    = readImage(*m_source, m_params.src.image, miplevel);
1673
1674                 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1675                 if (result.getCode() != QP_TEST_RESULT_PASS)
1676                         return result;
1677         }
1678         return tcu::TestStatus::pass("Pass");
1679 }
1680
1681 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1682 {
1683         const tcu::Vec4 fThreshold (0.0f);
1684         const tcu::UVec4 uThreshold (0u);
1685
1686         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1687         {
1688                 if (tcu::hasDepthComponent(result.getFormat().order))
1689                 {
1690                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1691                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1692                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(expected, mode);
1693
1694                         if (isFloatFormat(result.getFormat()))
1695                         {
1696                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1697                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1698                         }
1699                         else
1700                         {
1701                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1702                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1703                         }
1704                 }
1705
1706                 if (tcu::hasStencilComponent(result.getFormat().order))
1707                 {
1708                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1709                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1710                         const tcu::ConstPixelBufferAccess               expectedResult          = tcu::getEffectiveDepthStencilAccess(expected, mode);
1711
1712                         if (isFloatFormat(result.getFormat()))
1713                         {
1714                                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1715                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1716                         }
1717                         else
1718                         {
1719                                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1720                                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1721                         }
1722                 }
1723         }
1724         else
1725         {
1726                 if (isFloatFormat(result.getFormat()))
1727                 {
1728                         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1729                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1730                 }
1731                 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1732                 {
1733                         // There may be an ambiguity between two possible binary representations of 1.0.
1734                         // Get rid of that by expanding the data to floats and re-normalizing again.
1735
1736                         tcu::TextureLevel resultSnorm   (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1737                         {
1738                                 tcu::TextureLevel resultFloat   (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1739
1740                                 tcu::copy(resultFloat.getAccess(), result);
1741                                 tcu::copy(resultSnorm, resultFloat.getAccess());
1742                         }
1743
1744                         tcu::TextureLevel expectedSnorm (expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1745
1746                         {
1747                                 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1748
1749                                 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1750                                 tcu::copy(expectedSnorm, expectedFloat.getAccess());
1751                         }
1752
1753                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1754                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1755                 }
1756                 else
1757                 {
1758                         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1759                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1760                 }
1761         }
1762
1763         return tcu::TestStatus::pass("CopiesAndBlitting test");
1764 }
1765
1766 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1767 {
1768         DE_UNREF(mipLevel);
1769
1770         VkOffset3D      srcOffset       = region.imageCopy.srcOffset;
1771         VkOffset3D      dstOffset       = region.imageCopy.dstOffset;
1772         VkExtent3D      extent          = region.imageCopy.extent;
1773
1774         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1775         {
1776                 dstOffset.z = srcOffset.z;
1777                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1778         }
1779         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1780         {
1781                 srcOffset.z = dstOffset.z;
1782                 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1783         }
1784
1785
1786         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1787         {
1788                 DE_ASSERT(src.getFormat() == dst.getFormat());
1789
1790                 // Copy depth.
1791                 if (tcu::hasDepthComponent(src.getFormat().order))
1792                 {
1793                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1794                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1795                         tcu::copy(dstSubRegion, srcSubRegion);
1796                 }
1797
1798                 // Copy stencil.
1799                 if (tcu::hasStencilComponent(src.getFormat().order))
1800                 {
1801                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1802                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1803                         tcu::copy(dstSubRegion, srcSubRegion);
1804                 }
1805         }
1806         else
1807         {
1808                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1809                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1810                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1811                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1812
1813                 tcu::copy(dstSubRegion, srcSubRegion);
1814         }
1815 }
1816
1817 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1818 {
1819 public:
1820                                                         CopyImageToImageMipmapTestCase  (tcu::TestContext&                              testCtx,
1821                                                                                                                          const std::string&                             name,
1822                                                                                                                          const std::string&                             description,
1823                                                                                                                          const TestParams                               params)
1824                                                                 : vkt::TestCase (testCtx, name, description)
1825                                                                 , m_params              (params)
1826         {}
1827
1828         virtual TestInstance*   createInstance                          (Context&                                               context) const
1829         {
1830                 return new CopyImageToImageMipmap(context, m_params);
1831         }
1832
1833         virtual void                    checkSupport                            (Context&                                               context) const
1834         {
1835                 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1836                 {
1837                         if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1838                                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1839                 }
1840
1841                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1842                 {
1843                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1844                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1845                 }
1846
1847                 if (m_params.separateDepthStencilLayouts)
1848                         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1849                                 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1850
1851                 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1852                         (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1853                 {
1854                         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1855                                 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1856                 }
1857
1858                 const VkPhysicalDeviceLimits    limits          = context.getDeviceProperties().limits;
1859                 VkImageFormatProperties                 properties;
1860
1861                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1862                                                                                                                                                                         m_params.src.image.format,
1863                                                                                                                                                                         m_params.src.image.imageType,
1864                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1865                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1866                                                                                                                                                                         0,
1867                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1868                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1869                                                                                                                                                                         m_params.dst.image.format,
1870                                                                                                                                                                         m_params.dst.image.imageType,
1871                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
1872                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1873                                                                                                                                                                         0,
1874                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1875                 {
1876                         TCU_THROW(NotSupportedError, "Format not supported");
1877                 }
1878
1879                 // Check maxImageDimension1D
1880                 {
1881                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1882                                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1883
1884                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1885                                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1886                 }
1887
1888                 // Check maxImageDimension2D
1889                 {
1890                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1891                                 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1892                         {
1893                                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1894                         }
1895
1896                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1897                                 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1898                         {
1899                                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1900                         }
1901                 }
1902
1903                 // Check maxImageDimension3D
1904                 {
1905                         if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1906                                 || m_params.src.image.extent.height > limits.maxImageDimension3D
1907                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1908                         {
1909                                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1910                         }
1911
1912                         if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1913                                 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1914                                 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1915                         {
1916                                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1917                         }
1918                 }
1919         }
1920
1921 private:
1922         TestParams                              m_params;
1923 };
1924
1925 // Copy from buffer to buffer.
1926
1927 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1928 {
1929 public:
1930                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
1931         virtual tcu::TestStatus         iterate                                         (void);
1932 private:
1933         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1934         Move<VkBuffer>                          m_source;
1935         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1936         Move<VkBuffer>                          m_destination;
1937         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1938 };
1939
1940 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1941         : CopiesAndBlittingTestInstance (context, params)
1942 {
1943         const InstanceInterface&        vki                                     = context.getInstanceInterface();
1944         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1945         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
1946         const VkDevice                          vkDevice                        = context.getDevice();
1947         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1948         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1949
1950         // Create source buffer
1951         {
1952                 const VkBufferCreateInfo        sourceBufferParams              =
1953                 {
1954                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1955                         DE_NULL,                                                                        // const void*                  pNext;
1956                         0u,                                                                                     // VkBufferCreateFlags  flags;
1957                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
1958                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1959                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1960                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1961                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1962                 };
1963
1964                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1965                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1966                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1967         }
1968
1969         // Create destination buffer
1970         {
1971                 const VkBufferCreateInfo        destinationBufferParams =
1972                 {
1973                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1974                         DE_NULL,                                                                        // const void*                  pNext;
1975                         0u,                                                                                     // VkBufferCreateFlags  flags;
1976                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
1977                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1978                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1979                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1980                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1981                 };
1982
1983                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1984                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1985                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1986         }
1987 }
1988
1989 tcu::TestStatus CopyBufferToBuffer::iterate (void)
1990 {
1991         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
1992         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
1993         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
1994
1995         const int dstLevelWidth         = (int)(m_params.dst.buffer.size/4);
1996         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1997         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
1998
1999         generateExpectedResult();
2000
2001         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2002         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2003
2004         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2005         const VkDevice                          vkDevice        = m_context.getDevice();
2006         const VkQueue                           queue           = m_context.getUniversalQueue();
2007
2008         const VkBufferMemoryBarrier             srcBufferBarrier        =
2009         {
2010                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2011                 DE_NULL,                                                                        // const void*          pNext;
2012                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
2013                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
2014                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2015                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2016                 *m_source,                                                                      // VkBuffer                     buffer;
2017                 0u,                                                                                     // VkDeviceSize         offset;
2018                 m_params.src.buffer.size                                        // VkDeviceSize         size;
2019         };
2020
2021         const VkBufferMemoryBarrier             dstBufferBarrier        =
2022         {
2023                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2024                 DE_NULL,                                                                        // const void*          pNext;
2025                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
2026                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
2027                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2028                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2029                 *m_destination,                                                         // VkBuffer                     buffer;
2030                 0u,                                                                                     // VkDeviceSize         offset;
2031                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
2032         };
2033
2034         std::vector<VkBufferCopy>               bufferCopies;
2035         std::vector<VkBufferCopy2KHR>   bufferCopies2KHR;
2036         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2037         {
2038                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2039                 {
2040                         bufferCopies.push_back(m_params.regions[i].bufferCopy);
2041                 }
2042                 else
2043                 {
2044                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2045                         bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2046                 }
2047         }
2048
2049         beginCommandBuffer(vk, *m_cmdBuffer);
2050         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);
2051
2052         if (m_params.extensionUse == EXTENSION_USE_NONE)
2053         {
2054                 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2055         }
2056         else
2057         {
2058                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2059                 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2060                 {
2061                         VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,       // VkStructureType                      sType;
2062                         DE_NULL,                                                                        // const void*                          pNext;
2063                         m_source.get(),                                                         // VkBuffer                                     srcBuffer;
2064                         m_destination.get(),                                            // VkBuffer                                     dstBuffer;
2065                         (deUint32)m_params.regions.size(),                      // uint32_t                                     regionCount;
2066                         &bufferCopies2KHR[0]                                            // const VkBufferCopy2KHR*      pRegions;
2067                 };
2068
2069                 vk.cmdCopyBuffer2KHR(*m_cmdBuffer, &copyBufferInfo2KHR);
2070         }
2071
2072         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);
2073         endCommandBuffer(vk, *m_cmdBuffer);
2074         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2075
2076         // Read buffer data
2077         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2078         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2079         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2080
2081         return checkTestResult(resultLevel->getAccess());
2082 }
2083
2084 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2085 {
2086         DE_UNREF(mipLevel);
2087
2088         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2089                          (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2090                          (size_t)region.bufferCopy.size);
2091 }
2092
2093 class BufferToBufferTestCase : public vkt::TestCase
2094 {
2095 public:
2096                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
2097                                                                                                          const std::string&     name,
2098                                                                                                          const std::string&     description,
2099                                                                                                          const TestParams       params)
2100                                                                 : vkt::TestCase (testCtx, name, description)
2101                                                                 , m_params              (params)
2102                                                         {}
2103
2104         virtual TestInstance*   createInstance                  (Context& context) const
2105                                                         {
2106                                                                 return new CopyBufferToBuffer(context, m_params);
2107                                                         }
2108
2109         virtual void                    checkSupport(Context&   context) const
2110         {
2111                                                         if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2112                                                         {
2113                                                                 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2114                                                                 {
2115                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2116                                                                 }
2117                                                         }
2118         }
2119
2120         private:
2121         TestParams                              m_params;
2122 };
2123
2124 // Copy from image to buffer.
2125
2126 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2127 {
2128 public:
2129                                                                 CopyImageToBuffer                       (Context&       context,
2130                                                                                                                          TestParams     testParams);
2131         virtual tcu::TestStatus         iterate                                         (void);
2132 private:
2133         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2134
2135         tcu::TextureFormat                      m_textureFormat;
2136         VkDeviceSize                            m_bufferSize;
2137
2138         Move<VkImage>                           m_source;
2139         de::MovePtr<Allocation>         m_sourceImageAlloc;
2140         Move<VkBuffer>                          m_destination;
2141         de::MovePtr<Allocation>         m_destinationBufferAlloc;
2142 };
2143
2144 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2145         : CopiesAndBlittingTestInstance(context, testParams)
2146         , m_textureFormat(mapVkFormat(testParams.src.image.format))
2147         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2148 {
2149         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2150         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2151         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2152         const VkDevice                          vkDevice                        = context.getDevice();
2153         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2154         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2155
2156         // Create source image
2157         {
2158                 const VkImageCreateInfo         sourceImageParams               =
2159                 {
2160                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2161                         DE_NULL,                                                                // const void*                  pNext;
2162                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
2163                         m_params.src.image.imageType,                   // VkImageType                  imageType;
2164                         m_params.src.image.format,                              // VkFormat                             format;
2165                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
2166                         1u,                                                                             // deUint32                             mipLevels;
2167                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
2168                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2169                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2170                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2171                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2172                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2173                         1u,                                                                             // deUint32                             queueFamilyCount;
2174                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2175                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2176                 };
2177
2178                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
2179                 m_sourceImageAlloc      = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2180                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2181         }
2182
2183         // Create destination buffer
2184         {
2185                 const VkBufferCreateInfo        destinationBufferParams =
2186                 {
2187                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2188                         DE_NULL,                                                                        // const void*                  pNext;
2189                         0u,                                                                                     // VkBufferCreateFlags  flags;
2190                         m_bufferSize,                                                           // VkDeviceSize                 size;
2191                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
2192                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2193                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2194                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2195                 };
2196
2197                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
2198                 m_destinationBufferAlloc        = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2199                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2200         }
2201 }
2202
2203 tcu::TestStatus CopyImageToBuffer::iterate (void)
2204 {
2205         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2206                                                                                                                                                                 m_params.src.image.extent.width,
2207                                                                                                                                                                 m_params.src.image.extent.height,
2208                                                                                                                                                                 m_params.src.image.extent.depth));
2209         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2210         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2211         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2212
2213         generateExpectedResult();
2214
2215         uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2216         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2217
2218         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2219         const VkDevice                          vkDevice        = m_context.getDevice();
2220         const VkQueue                           queue           = m_context.getUniversalQueue();
2221
2222         // Barriers for copying image to buffer
2223         const VkImageMemoryBarrier              imageBarrier            =
2224         {
2225                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2226                 DE_NULL,                                                                        // const void*                          pNext;
2227                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2228                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
2229                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2230                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
2231                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2232                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2233                 *m_source,                                                                      // VkImage                                      image;
2234                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2235                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2236                         0u,                                                                     // deUint32                             baseMipLevel;
2237                         1u,                                                                     // deUint32                             mipLevels;
2238                         0u,                                                                     // deUint32                             baseArraySlice;
2239                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
2240                 }
2241         };
2242
2243         const VkBufferMemoryBarrier             bufferBarrier           =
2244         {
2245                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
2246                 DE_NULL,                                                                        // const void*          pNext;
2247                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
2248                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
2249                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
2250                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
2251                 *m_destination,                                                         // VkBuffer                     buffer;
2252                 0u,                                                                                     // VkDeviceSize         offset;
2253                 m_bufferSize                                                            // VkDeviceSize         size;
2254         };
2255
2256         // Copy from image to buffer
2257         std::vector<VkBufferImageCopy>          bufferImageCopies;
2258         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2259         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2260         {
2261                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2262                 {
2263                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2264                 }
2265                 else
2266                 {
2267                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2268                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2269                 }
2270         }
2271
2272         beginCommandBuffer(vk, *m_cmdBuffer);
2273         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);
2274
2275         if (m_params.extensionUse == EXTENSION_USE_NONE)
2276         {
2277                 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2278         }
2279         else
2280         {
2281                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2282                 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2283                 {
2284                         VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,      // VkStructureType                              sType;
2285                         DE_NULL,                                                                                        // const void*                                  pNext;
2286                         m_source.get(),                                                                         // VkImage                                              srcImage;
2287                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                                srcImageLayout;
2288                         m_destination.get(),                                                            // VkBuffer                                             dstBuffer;
2289                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2290                         &bufferImageCopies2KHR[0]                                                       // const VkBufferImageCopy2KHR* pRegions;
2291                 };
2292
2293                 vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
2294         }
2295
2296         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);
2297         endCommandBuffer(vk, *m_cmdBuffer);
2298
2299         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2300
2301         // Read buffer data
2302         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2303         invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2304         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2305
2306         return checkTestResult(resultLevel->getAccess());
2307 }
2308
2309 class CopyImageToBufferTestCase : public vkt::TestCase
2310 {
2311 public:
2312                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
2313                                                                                                                  const std::string&             name,
2314                                                                                                                  const std::string&             description,
2315                                                                                                                  const TestParams               params)
2316                                                                 : vkt::TestCase (testCtx, name, description)
2317                                                                 , m_params              (params)
2318                                                         {}
2319
2320         virtual TestInstance*   createInstance                          (Context&                               context) const
2321                                                         {
2322                                                                 return new CopyImageToBuffer(context, m_params);
2323                                                         }
2324
2325         virtual void                    checkSupport                            (Context&                               context) const
2326                                                         {
2327                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2328                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2329                                                                 {
2330                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2331                                                                 }
2332                                                         }
2333
2334 private:
2335         TestParams                              m_params;
2336 };
2337
2338 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2339 {
2340         DE_UNREF(mipLevel);
2341
2342         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2343         if (!rowLength)
2344                 rowLength = region.bufferImageCopy.imageExtent.width;
2345
2346         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
2347         if (!imageHeight)
2348                 imageHeight = region.bufferImageCopy.imageExtent.height;
2349
2350         const int                       texelSize               = src.getFormat().getPixelSize();
2351         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
2352         const VkOffset3D        srcOffset               = region.bufferImageCopy.imageOffset;
2353         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
2354         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2355
2356         for (deUint32 z = 0; z < extent.depth; z++)
2357         {
2358                 for (deUint32 y = 0; y < extent.height; y++)
2359                 {
2360                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
2361                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2362                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
2363                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2364                         tcu::copy(dstSubRegion, srcSubRegion);
2365                 }
2366         }
2367 }
2368
2369 // Copy from buffer to image.
2370
2371 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2372 {
2373 public:
2374                                                                 CopyBufferToImage                       (Context&       context,
2375                                                                                                                          TestParams     testParams);
2376         virtual tcu::TestStatus         iterate                                         (void);
2377
2378 private:
2379         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2380
2381         tcu::TextureFormat                      m_textureFormat;
2382         VkDeviceSize                            m_bufferSize;
2383
2384         Move<VkBuffer>                          m_source;
2385         de::MovePtr<Allocation>         m_sourceBufferAlloc;
2386         Move<VkImage>                           m_destination;
2387         de::MovePtr<Allocation>         m_destinationImageAlloc;
2388 };
2389
2390 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2391         : CopiesAndBlittingTestInstance(context, testParams)
2392         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2393         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2394 {
2395         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2396         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2397         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2398         const VkDevice                          vkDevice                        = context.getDevice();
2399         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2400         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2401
2402         // Create source buffer
2403         {
2404                 const VkBufferCreateInfo        sourceBufferParams              =
2405                 {
2406                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2407                         DE_NULL,                                                                        // const void*                  pNext;
2408                         0u,                                                                                     // VkBufferCreateFlags  flags;
2409                         m_bufferSize,                                                           // VkDeviceSize                 size;
2410                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
2411                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2412                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2413                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2414                 };
2415
2416                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
2417                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2418                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2419         }
2420
2421         // Create destination image
2422         {
2423                 const VkImageCreateInfo         destinationImageParams  =
2424                 {
2425                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2426                         DE_NULL,                                                                // const void*                  pNext;
2427                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2428                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2429                         m_params.dst.image.format,                              // VkFormat                             format;
2430                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2431                         1u,                                                                             // deUint32                             mipLevels;
2432                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2433                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2434                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2435                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2436                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2437                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2438                         1u,                                                                             // deUint32                             queueFamilyCount;
2439                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2440                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2441                 };
2442
2443                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
2444                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2445                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2446         }
2447 }
2448
2449 tcu::TestStatus CopyBufferToImage::iterate (void)
2450 {
2451         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2452         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2453         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2454                                                                                                                                                                         m_params.dst.image.extent.width,
2455                                                                                                                                                                         m_params.dst.image.extent.height,
2456                                                                                                                                                                         m_params.dst.image.extent.depth));
2457
2458         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2459
2460         generateExpectedResult();
2461
2462         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2463         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2464
2465         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
2466         const VkDevice                          vkDevice        = m_context.getDevice();
2467         const VkQueue                           queue           = m_context.getUniversalQueue();
2468
2469         const VkImageMemoryBarrier      imageBarrier    =
2470         {
2471                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2472                 DE_NULL,                                                                        // const void*                          pNext;
2473                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2474                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2475                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2476                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2477                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2478                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2479                 *m_destination,                                                         // VkImage                                      image;
2480                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2481                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2482                         0u,                                                             // deUint32                             baseMipLevel;
2483                         1u,                                                             // deUint32                             mipLevels;
2484                         0u,                                                             // deUint32                             baseArraySlice;
2485                         getArraySize(m_params.dst.image)                                                                // deUint32                             arraySize;
2486                 }
2487         };
2488
2489         // Copy from buffer to image
2490         std::vector<VkBufferImageCopy>          bufferImageCopies;
2491         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2492         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2493         {
2494                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2495                 {
2496                         bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2497                 }
2498                 else
2499                 {
2500                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2501                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2502                 }
2503         }
2504
2505         beginCommandBuffer(vk, *m_cmdBuffer);
2506         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);
2507
2508         if (m_params.extensionUse == EXTENSION_USE_NONE)
2509         {
2510                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2511         }
2512         else
2513         {
2514                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2515                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2516                 {
2517                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2518                         DE_NULL,                                                                                        // const void*                                  pNext;
2519                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2520                         m_destination.get(),                                                            // VkImage                                              dstImage;
2521                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2522                         (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2523                         bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2524                 };
2525
2526                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2527         }
2528
2529
2530         endCommandBuffer(vk, *m_cmdBuffer);
2531
2532         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2533
2534         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
2535
2536         return checkTestResult(resultLevel->getAccess());
2537 }
2538
2539 class CopyBufferToImageTestCase : public vkt::TestCase
2540 {
2541 public:
2542                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
2543                                                                                                                  const std::string&             name,
2544                                                                                                                  const std::string&             description,
2545                                                                                                                  const TestParams               params)
2546                                                                 : vkt::TestCase (testCtx, name, description)
2547                                                                 , m_params              (params)
2548                                                         {}
2549
2550         virtual                                 ~CopyBufferToImageTestCase      (void) {}
2551
2552         virtual TestInstance*   createInstance                          (Context&                               context) const
2553                                                         {
2554                                                                 return new CopyBufferToImage(context, m_params);
2555                                                         }
2556
2557         virtual void                    checkSupport                            (Context&                               context) const
2558                                                         {
2559                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2560                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2561                                                                 {
2562                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2563                                                                 }
2564                                                         }
2565
2566
2567 private:
2568         TestParams                              m_params;
2569 };
2570
2571 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2572 {
2573         DE_UNREF(mipLevel);
2574
2575         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2576         if (!rowLength)
2577                 rowLength = region.bufferImageCopy.imageExtent.width;
2578
2579         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
2580         if (!imageHeight)
2581                 imageHeight = region.bufferImageCopy.imageExtent.height;
2582
2583         const int                       texelSize               = dst.getFormat().getPixelSize();
2584         const VkExtent3D        extent                  = region.bufferImageCopy.imageExtent;
2585         const VkOffset3D        dstOffset               = region.bufferImageCopy.imageOffset;
2586         const int                       texelOffset             = (int) region.bufferImageCopy.bufferOffset / texelSize;
2587         const deUint32          baseArrayLayer  = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2588
2589         for (deUint32 z = 0; z < extent.depth; z++)
2590         {
2591                 for (deUint32 y = 0; y < extent.height; y++)
2592                 {
2593                         int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2594                         const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2595                         const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2596                                                                                                                                                   region.bufferImageCopy.imageExtent.width, 1, 1);
2597                         tcu::copy(dstSubRegion, srcSubRegion);
2598                 }
2599         }
2600 }
2601
2602 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2603 {
2604 public:
2605                                                                 CopyBufferToDepthStencil        (Context& context,
2606                                                                                                                          TestParams     testParams);
2607         virtual tcu::TestStatus         iterate                                         (void);
2608 private:
2609         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2610
2611         tcu::TextureFormat                      m_textureFormat;
2612         VkDeviceSize                            m_bufferSize;
2613
2614         Move<VkBuffer>                          m_source;
2615         de::MovePtr<Allocation>         m_sourceBufferAlloc;
2616         Move<VkImage>                           m_destination;
2617         de::MovePtr<Allocation>         m_destinationImageAlloc;
2618 };
2619
2620 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2621 {
2622         DE_UNREF(mipLevel);
2623
2624         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
2625         if (!rowLength)
2626                 rowLength = region.bufferImageCopy.imageExtent.width;
2627
2628         deUint32                        imageHeight = region.bufferImageCopy.bufferImageHeight;
2629         if (!imageHeight)
2630                 imageHeight = region.bufferImageCopy.imageExtent.height;
2631
2632         const int                       texelSize       = dst.getFormat().getPixelSize();
2633         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
2634         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
2635         const int                       texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2636
2637         for (deUint32 z = 0; z < extent.depth; z++)
2638         {
2639                 for (deUint32 y = 0; y < extent.height; y++)
2640                 {
2641                         int                                                                     texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2642                         const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2643                         const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2644                                 region.bufferImageCopy.imageExtent.width, 1, 1);
2645
2646                         if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2647                         {
2648                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2649                         }
2650                         else
2651                         {
2652                                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2653                         }
2654                 }
2655         }
2656 }
2657
2658 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2659 {
2660         VkFormatProperties formatProps;
2661         vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2662         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2663 }
2664
2665 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2666         : CopiesAndBlittingTestInstance(context, testParams)
2667         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2668         , m_bufferSize(0)
2669 {
2670         const InstanceInterface&        vki                                     = context.getInstanceInterface();
2671         const DeviceInterface&          vk                                      = context.getDeviceInterface();
2672         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
2673         const VkDevice                          vkDevice                        = context.getDevice();
2674         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
2675         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
2676         const bool                                      hasDepth                        = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2677         const bool                                      hasStencil                      = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2678
2679         if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2680         {
2681                 TCU_THROW(NotSupportedError, "Image format not supported.");
2682         }
2683
2684         if (hasDepth)
2685         {
2686                 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2687                 if (texelSize > sizeof(float))
2688                 {
2689                         // We must have D32F_S8 format, depth must be packed so we only need
2690                         // to allocate space for the D32F part. Stencil will be separate
2691                         texelSize = sizeof(float);
2692                 }
2693                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2694         }
2695         if (hasStencil)
2696         {
2697                 // Stencil is always 8bits and packed.
2698                 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2699         }
2700
2701         // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2702         {
2703                 const VkBufferCreateInfo        sourceBufferParams              =
2704                 {
2705                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2706                         DE_NULL,                                                                        // const void*                  pNext;
2707                         0u,                                                                                     // VkBufferCreateFlags  flags;
2708                         m_bufferSize,                                                           // VkDeviceSize                 size;
2709                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
2710                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2711                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2712                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
2713                 };
2714
2715                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
2716                 m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2717                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2718         }
2719
2720         // Create destination image
2721         {
2722                 const VkImageCreateInfo         destinationImageParams  =
2723                 {
2724                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2725                         DE_NULL,                                                                // const void*                  pNext;
2726                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
2727                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2728                         m_params.dst.image.format,                              // VkFormat                             format;
2729                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2730                         1u,                                                                             // deUint32                             mipLevels;
2731                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2732                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2733                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2734                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2735                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2736                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2737                         1u,                                                                             // deUint32                             queueFamilyCount;
2738                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2739                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2740                 };
2741
2742                 m_destination                           = createImage(vk, vkDevice, &destinationImageParams);
2743                 m_destinationImageAlloc         = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2744                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2745         }
2746 }
2747
2748 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2749 {
2750         // Create source depth/stencil content. Treat as 1D texture to get different pattern
2751         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2752         // Fill buffer with linear gradiant
2753         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2754
2755         // Create image layer for depth/stencil
2756         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2757                 m_params.dst.image.extent.width,
2758                 m_params.dst.image.extent.height,
2759                 m_params.dst.image.extent.depth));
2760
2761         // Fill image layer with 2D gradiant
2762         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2763
2764         // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2765         // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2766         // This emulates what the HW will be doing.
2767         generateExpectedResult();
2768
2769         // Upload our source depth/stencil content to the source buffer
2770         // This is the buffer that will be used by region commands
2771         std::vector<VkBufferImageCopy>          bufferImageCopies;
2772         std::vector<VkBufferImageCopy2KHR>      bufferImageCopies2KHR;
2773         VkDeviceSize                                    bufferOffset    = 0;
2774         const VkDevice                                  vkDevice                = m_context.getDevice();
2775         const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
2776         const VkQueue                                   queue                   = m_context.getUniversalQueue();
2777         char*                                                   dstPtr                  = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2778         bool                                                    depthLoaded             = DE_FALSE;
2779         bool                                                    stencilLoaded   = DE_FALSE;
2780         VkDeviceSize                                    depthOffset             = 0;
2781         VkDeviceSize                                    stencilOffset   = 0;
2782
2783         // To be able to test ordering depth & stencil differently
2784         // we take the given copy regions and use that as the desired order
2785         // and copy the appropriate data into place and compute the appropriate
2786         // data offsets to be used in the copy command.
2787         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2788         {
2789                 tcu::ConstPixelBufferAccess bufferAccess        = m_sourceTextureLevel->getAccess();
2790                 deUint32                                        bufferSize              = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2791                 VkBufferImageCopy                       copyData                = m_params.regions[i].bufferImageCopy;
2792                 char*                                           srcPtr;
2793
2794                 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2795                 {
2796                         // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2797                         tcu::TextureLevel       depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2798                         bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2799                         // Copy depth component only from source data. This gives us packed depth-only data.
2800                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2801                         srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2802                         // Copy packed depth-only data to output buffer
2803                         deMemcpy(dstPtr, srcPtr, bufferSize);
2804                         depthLoaded = DE_TRUE;
2805                         depthOffset = bufferOffset;
2806                         dstPtr += bufferSize;
2807                         bufferOffset += bufferSize;
2808                         copyData.bufferOffset += depthOffset;
2809                 }
2810                 else if (!stencilLoaded)
2811                 {
2812                         // Create level that is same component as stencil buffer (always 8-bits)
2813                         tcu::TextureLevel       stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2814                         // Copy stencil component only from source data. This gives us packed stencil-only data.
2815                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2816                         srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2817                         // Copy packed stencil-only data to output buffer
2818                         deMemcpy(dstPtr, srcPtr, bufferSize);
2819                         stencilLoaded = DE_TRUE;
2820                         stencilOffset = bufferOffset;
2821                         dstPtr += bufferSize;
2822                         bufferOffset += bufferSize;
2823
2824                         // Reference image generation uses pixel offsets based on buffer offset.
2825                         // We need to adjust the offset now that the stencil data is not interleaved.
2826                         copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2827
2828                         copyData.bufferOffset += stencilOffset;
2829                 }
2830
2831                 if (m_params.extensionUse == EXTENSION_USE_NONE)
2832                 {
2833                         bufferImageCopies.push_back(copyData);
2834                 }
2835                 else
2836                 {
2837                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2838                         bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2839                 }
2840         }
2841
2842         flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2843
2844         // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2845         // depth and stencil to known values.
2846         // Uses uploadImageAspect so makes its own buffers for depth and stencil
2847         // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2848         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2849
2850         const VkImageMemoryBarrier      imageBarrier    =
2851         {
2852                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2853                 DE_NULL,                                                                        // const void*                          pNext;
2854                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2855                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2856                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2857                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2858                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2859                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2860                 *m_destination,                                                         // VkImage                                      image;
2861                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2862                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
2863                         0u,                                                             // deUint32                             baseMipLevel;
2864                         1u,                                                             // deUint32                             mipLevels;
2865                         0u,                                                             // deUint32                             baseArraySlice;
2866                         1u                                                              // deUint32                             arraySize;
2867                 }
2868         };
2869
2870         // Copy from buffer to depth/stencil image
2871
2872         beginCommandBuffer(vk, *m_cmdBuffer);
2873         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);
2874
2875         if (m_params.extensionUse == EXTENSION_USE_NONE)
2876         {
2877                 if (m_params.singleCommand)
2878                 {
2879                         // Issue a single copy command with regions defined by the test.
2880                         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2881                 }
2882                 else
2883                 {
2884                         // Issue a a copy command per region defined by the test.
2885                         for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2886                         {
2887                                 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2888                         }
2889                 }
2890         }
2891         else
2892         {
2893                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2894
2895                 if (m_params.singleCommand)
2896                 {
2897                         // Issue a single copy command with regions defined by the test.
2898                         const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2899                         {
2900                                 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2901                                 DE_NULL,                                                                                        // const void*                                  pNext;
2902                                 m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2903                                 m_destination.get(),                                                            // VkImage                                              dstImage;
2904                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2905                                 (deUint32)m_params.regions.size(),                                      // uint32_t                                             regionCount;
2906                                 bufferImageCopies2KHR.data()                                            // const VkBufferImageCopy2KHR* pRegions;
2907                         };
2908                         vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2909                 }
2910                 else
2911                 {
2912                         // Issue a a copy command per region defined by the test.
2913                         for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2914                         {
2915                                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2916                                 {
2917                                         VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,      // VkStructureType                              sType;
2918                                         DE_NULL,                                                                                        // const void*                                  pNext;
2919                                         m_source.get(),                                                                         // VkBuffer                                             srcBuffer;
2920                                         m_destination.get(),                                                            // VkImage                                              dstImage;
2921                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                                dstImageLayout;
2922                                         1,                                                                                                      // uint32_t                                             regionCount;
2923                                         &bufferImageCopies2KHR[i]                                                       // const VkBufferImageCopy2KHR* pRegions;
2924                                 };
2925                                 // Issue a single copy command with regions defined by the test.
2926                                 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2927                         }
2928                 }
2929         }
2930         endCommandBuffer(vk, *m_cmdBuffer);
2931
2932         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2933
2934         de::MovePtr<tcu::TextureLevel>  resultLevel = readImage(*m_destination, m_params.dst.image);
2935
2936         // For combined depth/stencil formats both aspects are checked even when the test only
2937         // copies one. Clear such aspects here for both the result and the reference.
2938         if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2939         {
2940                 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2941                 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2942         }
2943         if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2944         {
2945                 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2946                 tcu::clearStencil(resultLevel->getAccess(), 0);
2947         }
2948
2949         return checkTestResult(resultLevel->getAccess());
2950 }
2951
2952 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
2953 {
2954 public:
2955                                                         CopyBufferToDepthStencilTestCase        (tcu::TestContext&              testCtx,
2956                                                                                                                                  const std::string&             name,
2957                                                                                                                                  const std::string&             description,
2958                                                                                                                                  const TestParams               params)
2959                                                                 : vkt::TestCase(testCtx, name, description)
2960                                                                 , m_params(params)
2961                                                         {}
2962
2963         virtual                                 ~CopyBufferToDepthStencilTestCase       (void) {}
2964
2965         virtual TestInstance*   createInstance                                          (Context&                               context) const
2966                                                         {
2967                                                                 return new CopyBufferToDepthStencil(context, m_params);
2968                                                         }
2969
2970         virtual void                    checkSupport                                            (Context&                               context) const
2971                                                         {
2972                                                                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2973                                                                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2974                                                                 {
2975                                                                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2976                                                                 }
2977                                                         }
2978
2979 private:
2980         TestParams                              m_params;
2981 };
2982
2983 // CompressedTextureForBlit is a helper class that stores compressed texture data.
2984 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
2985 // and has special cases needed for blits to some formats.
2986
2987 class CompressedTextureForBlit
2988 {
2989 public:
2990         CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat);
2991
2992         tcu::PixelBufferAccess                  getDecompressedAccess() const;
2993         const tcu::CompressedTexture&   getCompressedTexture() const;
2994
2995 protected:
2996
2997         tcu::CompressedTexture          m_compressedTexture;
2998         de::ArrayBuffer<deUint8>        m_decompressedData;
2999         tcu::PixelBufferAccess          m_decompressedAccess;
3000 };
3001
3002 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat)
3003         : m_compressedTexture(srcFormat, width, height, depth)
3004 {
3005         de::Random                      random                                  (123);
3006
3007         const int                       compressedDataSize              (m_compressedTexture.getDataSize());
3008         deUint8*                        compressedData                  ((deUint8*)m_compressedTexture.getData());
3009
3010         tcu::TextureFormat      decompressedSrcFormat   (tcu::getUncompressedFormat(srcFormat));
3011         const int                       decompressedDataSize    (tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3012
3013         // generate random data for compresed textre
3014         if (tcu::isAstcFormat(srcFormat))
3015         {
3016                 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3017                 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3018                                                                                          srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3019         }
3020         else if ((dstFormat == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
3021                         ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3022                          (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)))
3023         {
3024                 // special case - when we are blitting compressed image to RGB999E5 image we can't have both big and small values
3025                 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3026                 // blocks that after decompression will have components in proper range
3027
3028                 struct BC6HBlock
3029                 {
3030                         deUint32 data[4];
3031                 };
3032                 std::vector<BC6HBlock> validBlocks;
3033
3034                 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3035                 {
3036                         // define set of few valid blocks that contain values from <0; 1> range
3037                         validBlocks =
3038                         {
3039                                 { 1686671500, 3957317723, 3010132342, 2420137890 },
3040                                 { 3538027716, 298848033, 1925786021, 2022072301 },
3041                                 { 2614043466, 1636155440, 1023731774, 1894349986 },
3042                                 { 3433039318, 1294346072, 1587319645, 1738449906 },
3043                                 { 1386298160, 1639492154, 1273285776, 361562050 },
3044                                 { 1310110688, 526460754, 3630858047, 537617591 },
3045                                 { 3270356556, 2432993217, 2415924417, 1792488857 },
3046                                 { 1204947583, 353249154, 3739153467, 2068076443 },
3047                         };
3048                 }
3049                 else
3050                 {
3051                         // define set of few valid blocks that contain values from <-1; 1> range
3052                         validBlocks =
3053                         {
3054                                 { 2120678840, 3264271120, 4065378848, 3479743703 },
3055                                 { 1479697556, 3480872527, 3369382558, 568252340 },
3056                                 { 1301480032, 1607738094, 3055221704, 3663953681 },
3057                                 { 3531657186, 2285472028, 1429601507, 1969308187 },
3058                                 { 73229044, 650504649, 1120954865, 2626631975 },
3059                                 { 3872486086, 15326178, 2565171269, 2857722432 },
3060                                 { 1301480032, 1607738094, 3055221704, 3663953681 },
3061                                 { 73229044, 650504649, 1120954865, 2626631975 },
3062                         };
3063                 }
3064
3065                 deUint32*       compressedDataUint32    = reinterpret_cast<deUint32*>(compressedData);
3066                 const int       blocksCount                             = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3067
3068                 // fill data using randomly selected valid blocks
3069                 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3070                 {
3071                         deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3072                         deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3073                         compressedDataUint32 += 4;
3074                 }
3075         }
3076         else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3077         {
3078                 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3079                 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3080                         compressedData[byteNdx] = 0xFF & random.getUint32();
3081         }
3082
3083         // alocate space for decompressed texture
3084         m_decompressedData.setStorage(decompressedDataSize);
3085         m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3086
3087         // store decompressed data
3088         m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3089 }
3090
3091 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3092 {
3093         return m_decompressedAccess;
3094 }
3095
3096 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3097 {
3098         return m_compressedTexture;
3099 }
3100
3101 // Copy from image to image with scaling.
3102
3103 class BlittingImages : public CopiesAndBlittingTestInstance
3104 {
3105 public:
3106                                                                                         BlittingImages                                  (Context&       context,
3107                                                                                                                                                          TestParams params);
3108         virtual tcu::TestStatus                                 iterate                                                 (void);
3109 protected:
3110         virtual tcu::TestStatus                                 checkTestResult                                                 (tcu::ConstPixelBufferAccess    result);
3111         virtual void                                                    copyRegionToTextureLevel                                (tcu::ConstPixelBufferAccess    src,
3112                                                                                                                                                                          tcu::PixelBufferAccess                 dst,
3113                                                                                                                                                                          CopyRegion                                             region,
3114                                                                                                                                                                          deUint32                                               mipLevel = 0u);
3115         virtual void                                                    generateExpectedResult                                  (void);
3116         void                                                                    uploadCompressedImage                                   (const VkImage& image, const ImageParms& parms);
3117 private:
3118         bool                                                                    checkNonNearestFilteredResult                   (const tcu::ConstPixelBufferAccess&     result,
3119                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3120                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3121                                                                                                                                                                          const tcu::TextureFormat&                      sourceFormat);
3122         bool                                                                    checkNearestFilteredResult                              (const tcu::ConstPixelBufferAccess&     result,
3123                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     source);
3124
3125         bool                                                                    checkCompressedNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
3126                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3127                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3128                                                                                                                                                                          const tcu::CompressedTexFormat         format);
3129         bool                                                                    checkCompressedNearestFilteredResult    (const tcu::ConstPixelBufferAccess&     result,
3130                                                                                                                                                                          const tcu::ConstPixelBufferAccess&     source,
3131                                                                                                                                                                          const tcu::CompressedTexFormat         format);
3132
3133
3134         Move<VkImage>                                           m_source;
3135         de::MovePtr<Allocation>                         m_sourceImageAlloc;
3136         Move<VkImage>                                           m_destination;
3137         de::MovePtr<Allocation>                         m_destinationImageAlloc;
3138
3139         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel;
3140
3141         // helper used only when bliting from compressed formats
3142         typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3143         CompressedTextureForBlitSp                      m_sourceCompressedTexture;
3144         CompressedTextureForBlitSp                      m_destinationCompressedTexture;
3145 };
3146
3147 BlittingImages::BlittingImages (Context& context, TestParams params)
3148         : CopiesAndBlittingTestInstance(context, params)
3149 {
3150         const InstanceInterface&        vki                                     = context.getInstanceInterface();
3151         const DeviceInterface&          vk                                      = context.getDeviceInterface();
3152         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
3153         const VkDevice                          vkDevice                        = context.getDevice();
3154         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
3155         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
3156
3157         // Create source image
3158         {
3159                 const VkImageCreateInfo         sourceImageParams               =
3160                 {
3161                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3162                         DE_NULL,                                                                // const void*                  pNext;
3163                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
3164                         m_params.src.image.imageType,                   // VkImageType                  imageType;
3165                         m_params.src.image.format,                              // VkFormat                             format;
3166                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
3167                         1u,                                                                             // deUint32                             mipLevels;
3168                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
3169                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3170                         m_params.src.image.tiling,                              // VkImageTiling                tiling;
3171                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3172                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3173                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3174                         1u,                                                                             // deUint32                             queueFamilyCount;
3175                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3176                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3177                 };
3178
3179                 m_source = createImage(vk, vkDevice, &sourceImageParams);
3180                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3181                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3182         }
3183
3184         // Create destination image
3185         {
3186                 const VkImageCreateInfo         destinationImageParams  =
3187                 {
3188                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
3189                         DE_NULL,                                                                // const void*                  pNext;
3190                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
3191                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
3192                         m_params.dst.image.format,                              // VkFormat                             format;
3193                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
3194                         1u,                                                                             // deUint32                             mipLevels;
3195                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
3196                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
3197                         m_params.dst.image.tiling,                              // VkImageTiling                tiling;
3198                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3199                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
3200                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
3201                         1u,                                                                             // deUint32                             queueFamilyCount;
3202                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
3203                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
3204                 };
3205
3206                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3207                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3208                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3209         }
3210 }
3211
3212 tcu::TestStatus BlittingImages::iterate (void)
3213 {
3214         const DeviceInterface&          vk                              = m_context.getDeviceInterface();
3215         const VkDevice                          vkDevice                = m_context.getDevice();
3216         const VkQueue                           queue                   = m_context.getUniversalQueue();
3217
3218         const ImageParms&                       srcImageParams  = m_params.src.image;
3219         const int                                       srcWidth                = static_cast<int>(srcImageParams.extent.width);
3220         const int                                       srcHeight               = static_cast<int>(srcImageParams.extent.height);
3221         const int                                       srcDepth                = static_cast<int>(srcImageParams.extent.depth);
3222         const ImageParms&                       dstImageParams  = m_params.dst.image;
3223         const int                                       dstWidth                = static_cast<int>(dstImageParams.extent.width);
3224         const int                                       dstHeight               = static_cast<int>(dstImageParams.extent.height);
3225         const int                                       dstDepth                = static_cast<int>(dstImageParams.extent.depth);
3226
3227         std::vector<VkImageBlit>                regions;
3228         std::vector<VkImageBlit2KHR>    regions2KHR;
3229
3230         // setup blit regions - they are also needed for reference generation
3231         if (m_params.extensionUse == EXTENSION_USE_NONE)
3232         {
3233                 regions.reserve(m_params.regions.size());
3234                 for (const auto& r : m_params.regions)
3235                         regions.push_back(r.imageBlit);
3236         }
3237         else
3238         {
3239                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3240                 regions2KHR.reserve(m_params.regions.size());
3241                 for (const auto& r : m_params.regions)
3242                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3243         }
3244
3245         // generate source image
3246         if (isCompressedFormat(srcImageParams.format))
3247         {
3248                 // for compressed images srcImageParams.fillMode is not used - we are using random data
3249                 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3250                 m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, dstImageParams.format));
3251                 uploadCompressedImage(m_source.get(), srcImageParams);
3252         }
3253         else
3254         {
3255                 // non-compressed image is filled with selected fillMode
3256                 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3257                 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3258                 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3259                 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3260         }
3261
3262         // generate destination image
3263         if (isCompressedFormat(dstImageParams.format))
3264         {
3265                 // compressed images are filled with random data
3266                 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3267                 m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, VK_FORMAT_UNDEFINED));
3268                 uploadCompressedImage(m_destination.get(), dstImageParams);
3269         }
3270         else
3271         {
3272                 // non-compressed image is filled with white background
3273                 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3274                 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3275                 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3276                 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3277         }
3278
3279         generateExpectedResult();
3280
3281         // Barriers for copying images to buffer
3282         const VkImageMemoryBarrier imageBarriers[]
3283         {
3284                 {
3285                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3286                         DE_NULL,                                                                        // const void*                          pNext;
3287                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3288                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
3289                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3290                         srcImageParams.operationLayout,                         // VkImageLayout                        newLayout;
3291                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3292                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3293                         m_source.get(),                                                         // VkImage                                      image;
3294                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3295                                 getAspectFlags(srcImageParams.format),  //   VkImageAspectFlags         aspectMask;
3296                                 0u,                                                                             //   deUint32                           baseMipLevel;
3297                                 1u,                                                                             //   deUint32                           mipLevels;
3298                                 0u,                                                                             //   deUint32                           baseArraySlice;
3299                                 1u                                                                              //   deUint32                           arraySize;
3300                         }
3301                 },
3302                 {
3303                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
3304                         DE_NULL,                                                                        // const void*                          pNext;
3305                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
3306                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
3307                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
3308                         dstImageParams.operationLayout,                         // VkImageLayout                        newLayout;
3309                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
3310                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
3311                         m_destination.get(),                                            // VkImage                                      image;
3312                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
3313                                 getAspectFlags(dstImageParams.format),  //   VkImageAspectFlags         aspectMask;
3314                                 0u,                                                                             //   deUint32                           baseMipLevel;
3315                                 1u,                                                                             //   deUint32                           mipLevels;
3316                                 0u,                                                                             //   deUint32                           baseArraySlice;
3317                                 1u                                                                              //   deUint32                           arraySize;
3318                         }
3319                 }
3320         };
3321
3322         beginCommandBuffer(vk, *m_cmdBuffer);
3323         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);
3324
3325         if (m_params.extensionUse == EXTENSION_USE_NONE)
3326         {
3327                 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
3328         }
3329         else
3330         {
3331                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3332                 const VkBlitImageInfo2KHR blitImageInfo2KHR
3333                 {
3334                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
3335                         DE_NULL,                                                                        // const void*                                  pNext;
3336                         m_source.get(),                                                         // VkImage                                              srcImage;
3337                         srcImageParams.operationLayout,                         // VkImageLayout                                srcImageLayout;
3338                         m_destination.get(),                                            // VkImage                                              dstImage;
3339                         dstImageParams.operationLayout,                         // VkImageLayout                                dstImageLayout;
3340                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
3341                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
3342                         m_params.filter,                                                        // VkFilter                                             filter;
3343                 };
3344                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &blitImageInfo2KHR);
3345         }
3346
3347         endCommandBuffer(vk, *m_cmdBuffer);
3348         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3349
3350         de::MovePtr<tcu::TextureLevel>  resultLevel             = readImage(*m_destination, dstImageParams);
3351         tcu::PixelBufferAccess                  resultAccess    = resultLevel->getAccess();
3352
3353         // if blit was done to a compressed format we need to decompress it to be able to verify it
3354         if (m_destinationCompressedTexture)
3355         {
3356                 deUint8* const                                  compressedDataSrc       (static_cast<deUint8*>(resultAccess.getDataPtr()));
3357                 const tcu::CompressedTexFormat  dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3358                 tcu::TextureLevel                               decompressedLevel       (getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3359                 tcu::PixelBufferAccess                  decompressedAccess      (decompressedLevel.getAccess());
3360
3361                 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3362
3363                 return checkTestResult(decompressedAccess);
3364         }
3365
3366         return checkTestResult(resultAccess);
3367 }
3368
3369 static float calculateFloatConversionError (int srcBits)
3370 {
3371         if (srcBits > 0)
3372         {
3373                 const int       clampedBits     = de::clamp<int>(srcBits, 0, 32);
3374                 const float     srcMaxValue     = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3375                 const float     error           = 1.0f / srcMaxValue;
3376
3377                 return de::clamp<float>(error, 0.0f, 1.0f);
3378         }
3379         else
3380                 return 1.0f;
3381 }
3382
3383 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3384 {
3385         tcu::Vec4 threshold(0.01f);
3386
3387         switch (format.type)
3388         {
3389         case tcu::TextureFormat::HALF_FLOAT:
3390                 threshold = tcu::Vec4(0.005f);
3391                 break;
3392
3393         case tcu::TextureFormat::FLOAT:
3394         case tcu::TextureFormat::FLOAT64:
3395                 threshold = tcu::Vec4(0.001f);
3396                 break;
3397
3398         case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3399                 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3400                 break;
3401
3402         case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3403                 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3404                 break;
3405
3406         case tcu::TextureFormat::UNORM_INT_1010102_REV:
3407                 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3408                 break;
3409
3410         case tcu:: TextureFormat::UNORM_INT8:
3411                 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3412                 break;
3413
3414         default:
3415                 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3416                 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3417                                       calculateFloatConversionError(bits.y()),
3418                                       calculateFloatConversionError(bits.z()),
3419                                       calculateFloatConversionError(bits.w()));
3420         }
3421
3422         // Return value matching the channel order specified by the format
3423         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3424                 return threshold.swizzle(2, 1, 0, 3);
3425         else
3426                 return threshold;
3427 }
3428
3429 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3430 {
3431         bool            isSigned(false);
3432         tcu::IVec4      bitDepth(0);
3433
3434         switch (format)
3435         {
3436         case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3437                 bitDepth = { 7, 0, 0, 0 };
3438                 isSigned = true;
3439                 break;
3440
3441         case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3442                 bitDepth = { 8, 0, 0, 0 };
3443                 break;
3444
3445         case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3446                 bitDepth = { 7, 7, 0, 0 };
3447                 isSigned = true;
3448                 break;
3449
3450         case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3451                 bitDepth = { 8, 8, 0, 0 };
3452                 break;
3453
3454         case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3455         case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3456         case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3457                 bitDepth = { 8, 8, 8, 0 };
3458                 break;
3459
3460         case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3461         case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3462                 bitDepth = { 8, 8, 8, 1 };
3463                 break;
3464
3465         case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3466         case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3467                 bitDepth = { 8, 8, 8, 8 };
3468                 break;
3469
3470         case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3471         case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3472         case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3473         case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3474         case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3475         case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3476                 bitDepth = { 5, 6, 5, 0 };
3477                 break;
3478
3479         case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3480         case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3481         case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3482         case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3483                 bitDepth = { 5, 5, 5, 1 };
3484                 break;
3485
3486         case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3487                 bitDepth = { 7, 0, 0, 0 };
3488                 isSigned = true;
3489                 break;
3490
3491         case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3492                 bitDepth = { 8, 0, 0, 0 };
3493                 break;
3494
3495         case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3496                 bitDepth = { 7, 7, 0, 0 };
3497                 isSigned = true;
3498                 break;
3499
3500         case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3501                 bitDepth = { 8, 8, 0, 0 };
3502                 break;
3503
3504         case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3505                 return tcu::Vec4(0.01f);
3506         case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3507                 return tcu::Vec4(0.005f);
3508
3509         default:
3510                 DE_ASSERT(DE_FALSE);
3511         }
3512
3513         const float     range = isSigned ? 1.0f - (-1.0f)
3514                                                                  : 1.0f - 0.0f;
3515         tcu::Vec4 v;
3516         for (int i = 0; i < 4; ++i)
3517         {
3518                 if (bitDepth[i] == 0)
3519                         v[i] = 1.0f;
3520                 else
3521                         v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3522         }
3523         return v;
3524 }
3525
3526 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&  result,
3527                                                                                                         const tcu::ConstPixelBufferAccess&      clampedExpected,
3528                                                                                                         const tcu::ConstPixelBufferAccess&      unclampedExpected,
3529                                                                                                         const tcu::TextureFormat&                       srcFormat)
3530 {
3531         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
3532         const tcu::TextureFormat                dstFormat               = result.getFormat();
3533         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3534         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3535         bool                                                    isOk                    = false;
3536
3537         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3538
3539         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3540         // the other must also store values a signed/unsigned integer
3541         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3542         // despite the fact that both formats are sampled as floats
3543         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3544                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3545         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3546                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3547         if (dstImageIsIntClass != srcImageIsIntClass)
3548         {
3549                 log << tcu::TestLog::EndSection;
3550                 return false;
3551         }
3552
3553         if (isFloatFormat(dstFormat))
3554         {
3555                 const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
3556                 const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3557                 const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
3558                 const tcu::Vec4 threshold       = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3559
3560                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3561                 log << tcu::TestLog::EndSection;
3562
3563                 if (!isOk)
3564                 {
3565                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3566                         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3567                         log << tcu::TestLog::EndSection;
3568                 }
3569         }
3570         else
3571         {
3572                 tcu::UVec4      threshold;
3573                 // Calculate threshold depending on channel width of destination format.
3574                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
3575                 const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3576                 for (deUint32 i = 0; i < 4; ++i)
3577                         threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3578
3579                 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3580                 log << tcu::TestLog::EndSection;
3581
3582                 if (!isOk)
3583                 {
3584                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3585                         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3586                         log << tcu::TestLog::EndSection;
3587                 }
3588         }
3589
3590         return isOk;
3591 }
3592
3593 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess& result,
3594                                                                                                                          const tcu::ConstPixelBufferAccess&     clampedReference,
3595                                                                                                                          const tcu::ConstPixelBufferAccess&     unclampedReference,
3596                                                                                                                          const tcu::CompressedTexFormat         format)
3597 {
3598         tcu::TestLog&                           log                     = m_context.getTestContext().getLog();
3599         const tcu::TextureFormat        dstFormat       = result.getFormat();
3600
3601         // there are rare cases wher one or few pixels have slightly bigger error
3602         // in one of channels this accepted error allows those casses to pass
3603         const tcu::Vec4                         acceptedError(0.04f);
3604
3605         const tcu::Vec4                         srcMaxDiff      = getCompressedFormatThreshold(format);
3606         const tcu::Vec4                         dstMaxDiff      = m_destinationCompressedTexture ?
3607                                                                                                 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3608                                                                                                 getFormatThreshold(dstFormat);
3609         const tcu::Vec4                         threshold       = (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3610
3611         bool                                            filteredResultVerification(false);
3612         tcu::Vec4                                       filteredResultMinValue(-6e6);
3613         tcu::Vec4                                       filteredResultMaxValue(6e6);
3614         tcu::TextureLevel                       filteredResult;
3615         tcu::TextureLevel                       filteredClampedReference;
3616         tcu::TextureLevel                       filteredUnclampedReference;
3617
3618         if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3619                 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3620         {
3621                 if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3622                         (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3623                 {
3624                         // for compressed formats we are using random data and for bc6h formats
3625                         // this will give us also large color values; when we are bliting to
3626                         // a format that accepts large values we can end up with large diferences
3627                         // betwean filtered result and reference; to avoid that we need to remove
3628                         // values that are to big from verification
3629                         filteredResultVerification      = true;
3630                         filteredResultMinValue          = tcu::Vec4(-10.0f);
3631                         filteredResultMaxValue          = tcu::Vec4( 10.0f);
3632                 }
3633                 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3634                 {
3635                         // we need to clamp some formats to <0;1> range as it has
3636                         // small precision for big numbers compared to reference
3637                         filteredResultVerification      = true;
3638                         filteredResultMinValue          = tcu::Vec4(0.0f);
3639                         filteredResultMaxValue          = tcu::Vec4(1.0f);
3640                 }
3641                 // else don't use filtered verification
3642         }
3643
3644         if (filteredResultVerification)
3645         {
3646                 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3647                 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3648
3649                 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3650                 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3651
3652                 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3653                 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3654
3655                 for (deInt32 z = 0; z < result.getDepth(); z++)
3656                 for (deInt32 y = 0; y < result.getHeight(); y++)
3657                 for (deInt32 x = 0; x < result.getWidth(); x++)
3658                 {
3659                         tcu::Vec4 resultTexel                           = result.getPixel(x, y, z);
3660                         tcu::Vec4 clampedReferenceTexel         = clampedReference.getPixel(x, y, z);
3661                         tcu::Vec4 unclampedReferenceTexel       = unclampedReference.getPixel(x, y, z);
3662
3663                         resultTexel                             = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3664                         clampedReferenceTexel   = tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3665                         unclampedReferenceTexel = tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3666
3667                         filteredResultAcccess.setPixel(resultTexel, x, y, z);
3668                         filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3669                         filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3670                 }
3671         }
3672
3673         const tcu::ConstPixelBufferAccess clampedRef    = filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3674         const tcu::ConstPixelBufferAccess res                   = filteredResultVerification ? filteredResult.getAccess() : result;
3675
3676         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3677         bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3678         log << tcu::TestLog::EndSection;
3679
3680         if (!isOk)
3681         {
3682                 const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3683
3684                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3685                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3686                 log << tcu::TestLog::EndSection;
3687         }
3688
3689         return isOk;
3690 }
3691
3692 //! Utility to encapsulate coordinate computation and loops.
3693 struct CompareEachPixelInEachRegion
3694 {
3695         virtual          ~CompareEachPixelInEachRegion  (void) {}
3696         virtual bool compare                                                            (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3697
3698         bool forEach (const void*                                                       pUserData,
3699                                   const std::vector<CopyRegion>&                regions,
3700                                   const int                                                             sourceWidth,
3701                                   const int                                                             sourceHeight,
3702                                   const int                                                             sourceDepth,
3703                                   const tcu::PixelBufferAccess&                 errorMask) const
3704         {
3705                 bool compareOk = true;
3706
3707                 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3708                 {
3709                         const VkImageBlit& blit = regionIter->imageBlit;
3710
3711                         const int       xStart  = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3712                         const int       yStart  = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3713                         const int       zStart  = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3714                         const int       xEnd    = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3715                         const int       yEnd    = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3716                         const int       zEnd    = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3717                         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);
3718                         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);
3719                         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);
3720                         const float srcInvW     = 1.0f / static_cast<float>(sourceWidth);
3721                         const float srcInvH     = 1.0f / static_cast<float>(sourceHeight);
3722                         const float srcInvD     = 1.0f / static_cast<float>(sourceDepth);
3723
3724                         for (int z = zStart; z < zEnd; z++)
3725                         for (int y = yStart; y < yEnd; y++)
3726                         for (int x = xStart; x < xEnd; x++)
3727                         {
3728                                 const tcu::Vec3 srcNormCoord
3729                                 (
3730                                         (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3731                                         (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3732                                         (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3733                                 );
3734
3735                                 if (!compare(pUserData, x, y, z, srcNormCoord))
3736                                 {
3737                                         errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3738                                         compareOk = false;
3739                                 }
3740                         }
3741                 }
3742                 return compareOk;
3743         }
3744 };
3745
3746 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3747 {
3748         const tcu::TextureChannelClass  channelClass    = tcu::getTextureChannelClass(format.type);
3749         const tcu::IVec4                                bitDepth                = tcu::getTextureFormatBitDepth(format);
3750
3751         if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3752         {
3753                 return getFormatThreshold(format);
3754         }
3755         else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3756                          channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3757         {
3758                 const bool      isSigned        = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3759                 const float     range           = isSigned ? 1.0f - (-1.0f)
3760                                                                                    : 1.0f -   0.0f;
3761
3762                 tcu::Vec4 v;
3763                 for (int i = 0; i < 4; ++i)
3764                 {
3765                         if (bitDepth[i] == 0)
3766                                 v[i] = 1.0f;
3767                         else
3768                                 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3769                 }
3770                 return v;
3771         }
3772         else
3773         {
3774                 DE_ASSERT(0);
3775                 return tcu::Vec4();
3776         }
3777 }
3778
3779 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&        source,
3780                                                           const tcu::ConstPixelBufferAccess&    result,
3781                                                           const tcu::Vec4&                                              sourceThreshold,
3782                                                           const tcu::Vec4&                                              resultThreshold,
3783                                                           const tcu::PixelBufferAccess&                 errorMask,
3784                                                           const std::vector<CopyRegion>&                regions)
3785 {
3786         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);
3787         const tcu::IVec4                dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3788         tcu::LookupPrecision    precision;
3789
3790         precision.colorMask              = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3791         precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3792
3793         const struct Capture
3794         {
3795                 const tcu::ConstPixelBufferAccess&      source;
3796                 const tcu::ConstPixelBufferAccess&      result;
3797                 const tcu::Sampler&                                     sampler;
3798                 const tcu::LookupPrecision&                     precision;
3799                 const bool                                                      isSRGB;
3800         } capture =
3801         {
3802                 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3803         };
3804
3805         const struct Loop : CompareEachPixelInEachRegion
3806         {
3807                 Loop (void) {}
3808
3809                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3810                 {
3811                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
3812                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
3813                         tcu::Vec4                                               dstColor                        = c.result.getPixel(x, y, z);
3814
3815                         // TexLookupVerifier performs a conversion to linear space, so we have to as well
3816                         if (c.isSRGB)
3817                                 dstColor = tcu::sRGBToLinear(dstColor);
3818
3819                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3820                 }
3821         } loop;
3822
3823         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3824 }
3825
3826 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&  source,
3827                                                         const tcu::ConstPixelBufferAccess&      result,
3828                                                         const tcu::PixelBufferAccess&           errorMask,
3829                                                         const std::vector<CopyRegion>&          regions)
3830 {
3831         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);
3832         tcu::IntLookupPrecision precision;
3833
3834         {
3835                 const tcu::IVec4        srcBitDepth     = tcu::getTextureFormatBitDepth(source.getFormat());
3836                 const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(result.getFormat());
3837
3838                 for (deUint32 i = 0; i < 4; ++i) {
3839                         precision.colorThreshold[i]     = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3840                         precision.colorMask[i]          = dstBitDepth[i] != 0;
3841                 }
3842         }
3843
3844         // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3845         // does the conversion on the fly without wasting memory, but this approach is more straightforward.
3846         tcu::TextureLevel                               convertedSourceTexture  (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3847         const tcu::PixelBufferAccess    convertedSource                 = convertedSourceTexture.getAccess();
3848
3849         for (int z = 0; z < source.getDepth();  ++z)
3850         for (int y = 0; y < source.getHeight(); ++y)
3851         for (int x = 0; x < source.getWidth();  ++x)
3852                 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3853
3854         const struct Capture
3855         {
3856                 const tcu::ConstPixelBufferAccess&      source;
3857                 const tcu::ConstPixelBufferAccess&      result;
3858                 const tcu::Sampler&                                     sampler;
3859                 const tcu::IntLookupPrecision&          precision;
3860         } capture =
3861         {
3862                 convertedSource, result, sampler, precision
3863         };
3864
3865         const struct Loop : CompareEachPixelInEachRegion
3866         {
3867                 Loop (void) {}
3868
3869                 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3870                 {
3871                         const Capture&                                  c                                       = *static_cast<const Capture*>(pUserData);
3872                         const tcu::TexLookupScaleMode   lookupScaleDontCare     = tcu::TEX_LOOKUP_SCALE_MINIFY;
3873                         const tcu::IVec4                                dstColor                        = c.result.getPixelInt(x, y, z);
3874
3875                         return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3876                 }
3877         } loop;
3878
3879         return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3880 }
3881
3882 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&     result,
3883                                                                                                  const tcu::ConstPixelBufferAccess& source)
3884 {
3885         tcu::TestLog&                                   log                             (m_context.getTestContext().getLog());
3886         const tcu::TextureFormat                dstFormat               = result.getFormat();
3887         const tcu::TextureFormat                srcFormat               = source.getFormat();
3888         const tcu::TextureChannelClass  dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3889         const tcu::TextureChannelClass  srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3890
3891         tcu::TextureLevel               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3892         tcu::PixelBufferAccess  errorMask                       = errorMaskStorage.getAccess();
3893         tcu::Vec4                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3894         tcu::Vec4                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3895         bool                                    ok                                      = false;
3896
3897         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3898
3899         // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3900         // the other must also store values a signed/unsigned integer
3901         // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3902         // despite the fact that both formats are sampled as floats
3903         bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3904                                                           dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3905         bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3906                                                           srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3907         if (dstImageIsIntClass != srcImageIsIntClass)
3908                 return false;
3909
3910         if (dstImageIsIntClass)
3911         {
3912                 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3913         }
3914         else
3915         {
3916                 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3917                 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
3918                 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
3919         }
3920
3921         if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3922                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3923
3924         if (!ok)
3925         {
3926                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3927                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3928                         << tcu::TestLog::Image("ErrorMask",     "Error mask", errorMask)
3929                         << tcu::TestLog::EndImageSet;
3930         }
3931         else
3932         {
3933                 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3934                         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3935                         << tcu::TestLog::EndImageSet;
3936         }
3937
3938         return ok;
3939 }
3940
3941 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess&   result,
3942                                                                                                                    const tcu::ConstPixelBufferAccess&   source,
3943                                                                                                                    const tcu::CompressedTexFormat               format)
3944 {
3945         tcu::TestLog&                           log                                     (m_context.getTestContext().getLog());
3946         tcu::TextureFormat                      errorMaskFormat         (tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
3947         tcu::TextureLevel                       errorMaskStorage        (errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
3948         tcu::PixelBufferAccess          errorMask                       (errorMaskStorage.getAccess());
3949         tcu::Vec4                                       pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
3950         tcu::Vec4                                       pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
3951         const tcu::TextureFormat&       resultFormat            (result.getFormat());
3952         VkFormat                                        nativeResultFormat      (mapTextureFormat(resultFormat));
3953
3954         // there are rare cases wher one or few pixels have slightly bigger error
3955         // in one of channels this accepted error allows those casses to pass
3956         const tcu::Vec4                         acceptedError           (0.04f);
3957         const tcu::Vec4                         srcMaxDiff                      (acceptedError + getCompressedFormatThreshold(format));
3958         const tcu::Vec4                         dstMaxDiff                      (acceptedError + (m_destinationCompressedTexture ?
3959                                                                                                                 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3960                                                                                                                 getFloatOrFixedPointFormatThreshold(resultFormat)));
3961
3962         tcu::TextureLevel                       clampedSourceLevel;
3963         bool                                            clampSource                     (false);
3964         tcu::Vec4                                       clampSourceMinValue     (-1.0f);
3965         tcu::Vec4                                       clampSourceMaxValue     (1.0f);
3966         tcu::TextureLevel                       clampedResultLevel;
3967         bool                                            clampResult                     (false);
3968
3969         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3970
3971         if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3972                 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3973
3974         log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3975                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
3976
3977         // for compressed formats source buffer access is not actual compressed format
3978         // but equivalent uncompressed format that is some cases needs additional
3979         // modifications so that sampling it will produce valid reference
3980         if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3981                 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
3982         {
3983                 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3984                 {
3985                         // for compressed formats we are using random data and for some formats it
3986                         // can be outside of <-1;1> range - for cases where result is not a float
3987                         // format we need to clamp source to <-1;1> range as this will be done on
3988                         // the device but not in software sampler in framework
3989                         clampSource = true;
3990                         // for this format we also need to clamp the result as precision of
3991                         // this format is smaller then precision of calculations in framework;
3992                         // the biger color valus are the bigger errors can be
3993                         clampResult = true;
3994
3995                         if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
3996                                 clampSourceMinValue = tcu::Vec4(0.0f);
3997                 }
3998                 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
3999                                  (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4000                 {
4001                         // clamp source for all non float formats
4002                         clampSource = true;
4003                 }
4004         }
4005
4006         if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4007         {
4008                 // when tested compressed format is signed but the result format
4009                 // is unsigned we need to clamp source to <0; x> so that proper
4010                 // reference is calculated
4011                 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4012                         (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4013                         (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4014                         (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4015                         (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4016                 {
4017                         clampSource                     = true;
4018                         clampSourceMinValue     = tcu::Vec4(0.0f);
4019                 }
4020         }
4021
4022         if (clampSource || clampResult)
4023         {
4024                 if (clampSource)
4025                 {
4026                         clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4027                         tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4028
4029                         for (deInt32 z = 0; z < source.getDepth() ; z++)
4030                         for (deInt32 y = 0; y < source.getHeight() ; y++)
4031                         for (deInt32 x = 0; x < source.getWidth() ; x++)
4032                         {
4033                                 tcu::Vec4 texel = source.getPixel(x, y, z);
4034                                 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4035                                 clampedSourceAcccess.setPixel(texel, x, y, z);
4036                         }
4037                 }
4038
4039                 if (clampResult)
4040                 {
4041                         clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4042                         tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4043
4044                         for (deInt32 z = 0; z < result.getDepth() ; z++)
4045                         for (deInt32 y = 0; y < result.getHeight() ; y++)
4046                         for (deInt32 x = 0; x < result.getWidth() ; x++)
4047                         {
4048                                 tcu::Vec4 texel = result.getPixel(x, y, z);
4049                                 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4050                                 clampedResultAcccess.setPixel(texel, x, y, z);
4051                         }
4052                 }
4053         }
4054
4055         const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4056         const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4057
4058         if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4059         {
4060                 log << tcu::TestLog::EndImageSet;
4061                 return true;
4062         }
4063
4064         log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4065                 << tcu::TestLog::EndImageSet;
4066         return false;
4067 }
4068
4069 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4070 {
4071         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4072         const std::string failMessage("Result image is incorrect");
4073
4074         if (m_params.filter != VK_FILTER_NEAREST)
4075         {
4076                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4077                 {
4078                         if (tcu::hasDepthComponent(result.getFormat().order))
4079                         {
4080                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
4081                                 const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
4082                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4083                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4084                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4085
4086                                 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4087                                         return tcu::TestStatus::fail(failMessage);
4088                         }
4089
4090                         if (tcu::hasStencilComponent(result.getFormat().order))
4091                         {
4092                                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
4093                                 const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
4094                                 const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4095                                 const tcu::ConstPixelBufferAccess               unclampedExpected       = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4096                                 const tcu::TextureFormat                                sourceFormat            = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4097
4098                                 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4099                                         return tcu::TestStatus::fail(failMessage);
4100                         }
4101                 }
4102                 else if (m_sourceCompressedTexture)
4103                 {
4104                         const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4105                         if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4106                                 return tcu::TestStatus::fail(failMessage);
4107                 }
4108                 else
4109                 {
4110                         const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4111                         if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4112                                 return tcu::TestStatus::fail(failMessage);
4113                 }
4114         }
4115         else // NEAREST filtering
4116         {
4117                 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4118                 {
4119                         if (tcu::hasDepthComponent(result.getFormat().order))
4120                         {
4121                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_DEPTH;
4122                                 const tcu::ConstPixelBufferAccess               depthResult             = tcu::getEffectiveDepthStencilAccess(result, mode);
4123                                 const tcu::ConstPixelBufferAccess               depthSource             = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4124
4125                                 if (!checkNearestFilteredResult(depthResult, depthSource))
4126                                         return tcu::TestStatus::fail(failMessage);
4127                         }
4128
4129                         if (tcu::hasStencilComponent(result.getFormat().order))
4130                         {
4131                                 const tcu::Sampler::DepthStencilMode    mode                    = tcu::Sampler::MODE_STENCIL;
4132                                 const tcu::ConstPixelBufferAccess               stencilResult   = tcu::getEffectiveDepthStencilAccess(result, mode);
4133                                 const tcu::ConstPixelBufferAccess               stencilSource   = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4134
4135                                 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4136                                         return tcu::TestStatus::fail(failMessage);
4137                         }
4138                 }
4139                 else if (m_sourceCompressedTexture)
4140                 {
4141                         const tcu::CompressedTexture& compressedLevel   = m_sourceCompressedTexture->getCompressedTexture();
4142                         const tcu::PixelBufferAccess& decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4143
4144                         if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4145                                 return tcu::TestStatus::fail(failMessage);
4146                 }
4147                 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4148                         return tcu::TestStatus::fail(failMessage);
4149         }
4150
4151         return tcu::TestStatus::pass("Pass");
4152 }
4153
4154 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4155 {
4156         return isSRGB(format) ? linearToSRGB(color) : color;
4157 }
4158
4159 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4160 {
4161         DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4162
4163         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4164                                         filter, filter, 0.0f, false);
4165
4166         float sX = (float)regionExtent.x / (float)dst.getWidth();
4167         float sY = (float)regionExtent.y / (float)dst.getHeight();
4168         float sZ = (float)regionExtent.z / (float)dst.getDepth();
4169
4170         for (int z = 0; z < dst.getDepth(); z++)
4171         for (int y = 0; y < dst.getHeight(); y++)
4172         for (int x = 0; x < dst.getWidth(); x++)
4173         {
4174                 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;
4175                 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;
4176                 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;
4177                 if (dst.getDepth() > 1)
4178                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4179                 else
4180                         dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4181         }
4182 }
4183
4184 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4185 {
4186         DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4187
4188         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4189                         filter, filter, 0.0f, false);
4190
4191         const float sX = (float)src.getWidth() / (float)dst.getWidth();
4192         const float sY = (float)src.getHeight() / (float)dst.getHeight();
4193         const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4194
4195         const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4196         const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4197         const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4198
4199         const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4200         const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4201         const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4202
4203         for (int z = 0; z < dst.getDepth(); ++z)
4204         for (int y = 0; y < dst.getHeight(); ++y)
4205         for (int x = 0; x < dst.getWidth(); ++x)
4206         {
4207                 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);
4208         }
4209 }
4210
4211 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4212 {
4213         const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4214         const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4215         const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4216         const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4217
4218         if (mirrorMode != 0u)
4219         {
4220                 //sourceRegion
4221                 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4222                 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4223                 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4224
4225                 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4226                 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4227                 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4228
4229                 //destinationRegion
4230                 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4231                 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4232                 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4233
4234                 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4235                 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4236                 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4237         }
4238 }
4239
4240 // Mirror X, Y and Z as required by the offset values in the 3 axes.
4241 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4242 {
4243         MirrorMode mode = 0u;
4244
4245         if (from.x > to.x)
4246                 mode |= MIRROR_MODE_X;
4247
4248         if (from.y > to.y)
4249                 mode |= MIRROR_MODE_Y;
4250
4251         if (from.z > to.z)
4252                 mode |= MIRROR_MODE_Z;
4253
4254         return mode;
4255 }
4256
4257 // Mirror the axes that are mirrored either in the source or destination, but not both.
4258 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4259 {
4260         static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4261
4262         const MirrorMode source          = getMirrorMode(s1, s2);
4263         const MirrorMode destination = getMirrorMode(d1, d2);
4264
4265         MirrorMode mode = 0u;
4266
4267         for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4268         {
4269                 const MirrorModeBits bit = kBits[i];
4270                 if ((source & bit) != (destination & bit))
4271                         mode |= bit;
4272         }
4273
4274         return mode;
4275 }
4276
4277 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4278 {
4279         DE_UNREF(mipLevel);
4280
4281         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4282                                                                                                 region.imageBlit.srcOffsets[1],
4283                                                                                                 region.imageBlit.dstOffsets[0],
4284                                                                                                 region.imageBlit.dstOffsets[1]);
4285
4286         flipCoordinates(region, mirrorMode);
4287
4288         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
4289         const VkOffset3D                                        srcExtent               =
4290         {
4291                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4292                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4293                 region.imageBlit.srcOffsets[1].z - srcOffset.z,
4294         };
4295         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
4296         const VkOffset3D                                        dstExtent               =
4297         {
4298                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4299                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4300                 region.imageBlit.dstOffsets[1].z - dstOffset.z,
4301         };
4302
4303         tcu::Sampler::FilterMode                filter;
4304         switch (m_params.filter)
4305         {
4306                 case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
4307                 case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
4308                 case VK_FILTER_NEAREST:
4309                 default:                                        filter = tcu::Sampler::NEAREST;  break;
4310         }
4311
4312         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4313         {
4314                 DE_ASSERT(src.getFormat() == dst.getFormat());
4315
4316                 // Scale depth.
4317                 if (tcu::hasDepthComponent(src.getFormat().order))
4318                 {
4319                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4320                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4321                         tcu::scale(dstSubRegion, srcSubRegion, filter);
4322
4323                         if (filter != tcu::Sampler::NEAREST)
4324                         {
4325                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4326                                 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);
4327                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4328                         }
4329                 }
4330
4331                 // Scale stencil.
4332                 if (tcu::hasStencilComponent(src.getFormat().order))
4333                 {
4334                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4335                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4336                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4337
4338                         if (filter != tcu::Sampler::NEAREST)
4339                         {
4340                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4341                                 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);
4342                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4343                         }
4344                 }
4345         }
4346         else
4347         {
4348                 const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4349                 const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4350                 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4351
4352                 if (filter != tcu::Sampler::NEAREST)
4353                 {
4354                         const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4355                         scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4356                 }
4357         }
4358 }
4359
4360 void BlittingImages::generateExpectedResult (void)
4361 {
4362         const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4363         const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4364
4365         m_expectedTextureLevel[0]               = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4366         tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4367
4368         if (m_params.filter != VK_FILTER_NEAREST)
4369         {
4370                 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4371                 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4372         }
4373
4374         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4375         {
4376                 CopyRegion region = m_params.regions[i];
4377                 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4378         }
4379 }
4380
4381 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4382 {
4383         DE_ASSERT(m_sourceCompressedTexture);
4384
4385         const InstanceInterface&                vki                                     = m_context.getInstanceInterface();
4386         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
4387         const VkPhysicalDevice                  vkPhysDevice            = m_context.getPhysicalDevice();
4388         const VkDevice                                  vkDevice                        = m_context.getDevice();
4389         const VkQueue                                   queue                           = m_context.getUniversalQueue();
4390         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
4391         Allocator&                                              memAlloc                        = m_context.getDefaultAllocator();
4392         Move<VkBuffer>                                  buffer;
4393         const deUint32                                  bufferSize                      = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4394         de::MovePtr<Allocation>                 bufferAlloc;
4395         const deUint32                                  arraySize                       = getArraySize(parms);
4396         const VkExtent3D                                imageExtent
4397         {
4398                 parms.extent.width,
4399                 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4400                 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4401         };
4402
4403         // Create source buffer
4404         {
4405                 const VkBufferCreateInfo bufferParams
4406                 {
4407                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
4408                         DE_NULL,                                                                        // const void*                  pNext;
4409                         0u,                                                                                     // VkBufferCreateFlags  flags;
4410                         bufferSize,                                                                     // VkDeviceSize                 size;
4411                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
4412                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
4413                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
4414                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
4415                 };
4416
4417                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
4418                 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4419                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4420         }
4421
4422         // Barriers for copying buffer to image
4423         const VkBufferMemoryBarrier preBufferBarrier
4424         {
4425                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
4426                 DE_NULL,                                                                                // const void*          pNext;
4427                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
4428                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
4429                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
4430                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
4431                 *buffer,                                                                                // VkBuffer                     buffer;
4432                 0u,                                                                                             // VkDeviceSize         offset;
4433                 bufferSize                                                                              // VkDeviceSize         size;
4434         };
4435
4436         const VkImageMemoryBarrier preImageBarrier
4437         {
4438                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4439                 DE_NULL,                                                                                // const void*                          pNext;
4440                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
4441                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
4442                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
4443                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
4444                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4445                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4446                 image,                                                                                  // VkImage                                      image;
4447                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
4448                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspect;
4449                         0u,                                                     // deUint32                             baseMipLevel;
4450                         1u,                                                     // deUint32                             mipLevels;
4451                         0u,                                                     // deUint32                             baseArraySlice;
4452                         arraySize,                                      // deUint32                             arraySize;
4453                 }
4454         };
4455
4456         const VkImageMemoryBarrier postImageBarrier
4457         {
4458                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4459                 DE_NULL,                                                                                // const void*                          pNext;
4460                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
4461                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
4462                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
4463                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
4464                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4465                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4466                 image,                                                                                  // VkImage                                      image;
4467                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
4468                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspect;
4469                         0u,                                                             // deUint32                             baseMipLevel;
4470                         1u,                                                             // deUint32                             mipLevels;
4471                         0u,                                                             // deUint32                             baseArraySlice;
4472                         arraySize,                                              // deUint32                             arraySize;
4473                 }
4474         };
4475
4476         const VkExtent3D copyExtent
4477         {
4478                 imageExtent.width,
4479                 imageExtent.height,
4480                 imageExtent.depth
4481         };
4482
4483         VkBufferImageCopy copyRegion
4484         {
4485                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
4486                 copyExtent.width,                                                               // deUint32                                     bufferRowLength;
4487                 copyExtent.height,                                                              // deUint32                                     bufferImageHeight;
4488                 {
4489                         VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspect;
4490                         0u,                                                                                             // deUint32                             mipLevel;
4491                         0u,                                                                                             // deUint32                             baseArrayLayer;
4492                         arraySize,                                                                              // deUint32                             layerCount;
4493                 },                                                                                              // VkImageSubresourceLayers     imageSubresource;
4494                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
4495                 copyExtent                                                                              // VkExtent3D                           imageExtent;
4496         };
4497
4498         // Write buffer data
4499         deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4500         flushAlloc(vk, vkDevice, *bufferAlloc);
4501
4502         // Copy buffer to image
4503         beginCommandBuffer(vk, *m_cmdBuffer);
4504         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4505                                                   1, &preBufferBarrier, 1, &preImageBarrier);
4506         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
4507         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);
4508         endCommandBuffer(vk, *m_cmdBuffer);
4509
4510         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4511 }
4512
4513
4514 class BlitImageTestCase : public vkt::TestCase
4515 {
4516 public:
4517                                                         BlitImageTestCase               (tcu::TestContext&                              testCtx,
4518                                                                                                          const std::string&                             name,
4519                                                                                                          const std::string&                             description,
4520                                                                                                          const TestParams                               params)
4521                                                                 : vkt::TestCase (testCtx, name, description)
4522                                                                 , m_params              (params)
4523         {}
4524
4525         virtual TestInstance*   createInstance                  (Context&                                               context) const
4526         {
4527                 return new BlittingImages(context, m_params);
4528         }
4529
4530         virtual void                    checkSupport                    (Context&                                               context) const
4531         {
4532                 VkImageFormatProperties properties;
4533                 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4534                                                                                                                                                                         m_params.src.image.format,
4535                                                                                                                                                                         m_params.src.image.imageType,
4536                                                                                                                                                                         m_params.src.image.tiling,
4537                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4538                                                                                                                                                                         0,
4539                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4540                 {
4541                         TCU_THROW(NotSupportedError, "Source format not supported");
4542                 }
4543                 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4544                                                                                                                                                                         m_params.dst.image.format,
4545                                                                                                                                                                         m_params.dst.image.imageType,
4546                                                                                                                                                                         m_params.dst.image.tiling,
4547                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4548                                                                                                                                                                         0,
4549                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4550                 {
4551                         TCU_THROW(NotSupportedError, "Destination format not supported");
4552                 }
4553
4554                 VkFormatProperties srcFormatProperties;
4555                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4556                 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4557                 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4558                 {
4559                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4560                 }
4561
4562                 VkFormatProperties dstFormatProperties;
4563                 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4564                 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4565                 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4566                 {
4567                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4568                 }
4569
4570                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4571                 {
4572                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4573                 }
4574
4575                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4576                 {
4577                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4578
4579                         if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4580                         {
4581                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4582                         }
4583                 }
4584
4585                 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4586                 {
4587                         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4588                         {
4589                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4590                         }
4591                 }
4592         }
4593
4594 private:
4595         TestParams                              m_params;
4596 };
4597
4598 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4599 {
4600 public:
4601                                                                                 BlittingMipmaps                                 (Context&   context,
4602                                                                                                                                                  TestParams params);
4603         virtual tcu::TestStatus                         iterate                                                 (void);
4604 protected:
4605         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4606         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4607         virtual void                                            generateExpectedResult                  (void);
4608 private:
4609         bool                                                            checkNonNearestFilteredResult   (void);
4610         bool                                                            checkNearestFilteredResult              (void);
4611
4612         Move<VkImage>                                           m_source;
4613         de::MovePtr<Allocation>                         m_sourceImageAlloc;
4614         Move<VkImage>                                           m_destination;
4615         de::MovePtr<Allocation>                         m_destinationImageAlloc;
4616
4617         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel[16];
4618 };
4619
4620 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4621         : CopiesAndBlittingTestInstance (context, params)
4622 {
4623         const InstanceInterface&        vki                                     = context.getInstanceInterface();
4624         const DeviceInterface&          vk                                      = context.getDeviceInterface();
4625         const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
4626         const VkDevice                          vkDevice                        = context.getDevice();
4627         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
4628         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
4629
4630         // Create source image
4631         {
4632                 const VkImageCreateInfo         sourceImageParams               =
4633                 {
4634                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
4635                         DE_NULL,                                                                // const void*                  pNext;
4636                         getCreateFlags(m_params.src.image),             // VkImageCreateFlags   flags;
4637                         m_params.src.image.imageType,                   // VkImageType                  imageType;
4638                         m_params.src.image.format,                              // VkFormat                             format;
4639                         getExtent3D(m_params.src.image),                // VkExtent3D                   extent;
4640                         1u,                                                                             // deUint32                             mipLevels;
4641                         getArraySize(m_params.src.image),               // deUint32                             arraySize;
4642                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
4643                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
4644                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4645                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
4646                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
4647                         1u,                                                                             // deUint32                             queueFamilyCount;
4648                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
4649                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
4650                 };
4651
4652                 m_source = createImage(vk, vkDevice, &sourceImageParams);
4653                 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4654                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4655         }
4656
4657         // Create destination image
4658         {
4659                 const VkImageCreateInfo         destinationImageParams  =
4660                 {
4661                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
4662                         DE_NULL,                                                                // const void*                  pNext;
4663                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
4664                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
4665                         m_params.dst.image.format,                              // VkFormat                             format;
4666                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
4667                         m_params.mipLevels,                                             // deUint32                             mipLevels;
4668                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
4669                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
4670                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
4671                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4672                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
4673                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
4674                         1u,                                                                             // deUint32                             queueFamilyCount;
4675                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
4676                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
4677                 };
4678
4679                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
4680                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4681                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4682         }
4683 }
4684
4685 tcu::TestStatus BlittingMipmaps::iterate (void)
4686 {
4687         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
4688         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
4689         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4690                                                                                                                                                                 m_params.src.image.extent.width,
4691                                                                                                                                                                 m_params.src.image.extent.height,
4692                                                                                                                                                                 m_params.src.image.extent.depth));
4693         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);
4694         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4695                                                                                                                                                                                 (int)m_params.dst.image.extent.width,
4696                                                                                                                                                                                 (int)m_params.dst.image.extent.height,
4697                                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
4698         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);
4699         generateExpectedResult();
4700
4701         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4702
4703         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4704
4705         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
4706         const VkDevice                          vkDevice                        = m_context.getDevice();
4707         const VkQueue                           queue                           = m_context.getUniversalQueue();
4708
4709         std::vector<VkImageBlit>                regions;
4710         std::vector<VkImageBlit2KHR>    regions2KHR;
4711         for (deUint32 i = 0; i < m_params.regions.size(); i++)
4712         {
4713                 if (m_params.extensionUse == EXTENSION_USE_NONE)
4714                 {
4715                         regions.push_back(m_params.regions[i].imageBlit);
4716                 }
4717                 else
4718                 {
4719                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4720                         regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4721                 }
4722         }
4723
4724         // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4725         if (!m_params.singleCommand)
4726                 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4727
4728         beginCommandBuffer(vk, *m_cmdBuffer);
4729
4730         // Blit all mip levels with a single blit command
4731         if (m_params.singleCommand)
4732         {
4733                 {
4734                         // Source image layout
4735                         const VkImageMemoryBarrier              srcImageBarrier         =
4736                         {
4737                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4738                                 DE_NULL,                                                                        // const void*                          pNext;
4739                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4740                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
4741                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
4742                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
4743                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4744                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4745                                 m_source.get(),                                                         // VkImage                                      image;
4746                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4747                                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
4748                                         0u,                                                                     // deUint32                             baseMipLevel;
4749                                         1u,                                                                     // deUint32                             mipLevels;
4750                                         0u,                                                                     // deUint32                             baseArraySlice;
4751                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
4752                                 }
4753                         };
4754
4755                         // Destination image layout
4756                         const VkImageMemoryBarrier              dstImageBarrier         =
4757                         {
4758                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4759                                 DE_NULL,                                                                        // const void*                          pNext;
4760                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4761                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4762                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
4763                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4764                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4765                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4766                                 m_destination.get(),                                            // VkImage                                      image;
4767                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4768                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4769                                         0u,                                                                     // deUint32                             baseMipLevel;
4770                                         m_params.mipLevels,                                     // deUint32                             mipLevels;
4771                                         0u,                                                                     // deUint32                             baseArraySlice;
4772                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4773                                 }
4774                         };
4775
4776                         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);
4777                         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);
4778
4779                         if (m_params.extensionUse == EXTENSION_USE_NONE)
4780                         {
4781                                 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);
4782                         }
4783                         else
4784                         {
4785                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4786                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4787                                 {
4788                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
4789                                         DE_NULL,                                                                        // const void*                                  pNext;
4790                                         m_source.get(),                                                         // VkImage                                              srcImage;
4791                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
4792                                         m_destination.get(),                                            // VkImage                                              dstImage;
4793                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
4794                                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
4795                                         &regions2KHR[0],                                                        // const VkImageBlit2KHR*               pRegions;
4796                                         m_params.filter                                                         // VkFilter                                             filter;
4797                                 };
4798                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4799                         }
4800                 }
4801         }
4802         // Blit mip levels with multiple blit commands
4803         else
4804         {
4805                 // Prepare all mip levels for reading
4806                 {
4807                         for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4808                         {
4809                                 VkImageMemoryBarrier preImageBarrier =
4810                                 {
4811                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType      sType;
4812                                         DE_NULL,                                                                                                                                // const void*          pNext;
4813                                         VK_ACCESS_TRANSFER_WRITE_BIT,                                                                                   // VkAccessFlags        srcAccessMask;
4814                                         VK_ACCESS_TRANSFER_READ_BIT,                                                                                    // VkAccessFlags        dstAccessMask;
4815                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                                                                   // VkImageLayout        oldLayout;
4816                                         m_params.src.image.operationLayout,                                                                             // VkImageLayout        newLayout;
4817                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     srcQueueFamilyIndex;
4818                                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // deUint32                     dstQueueFamilyIndex;
4819                                         m_destination.get(),                                                                                                    // VkImage                      image;
4820                                         {                                                                                                                                               // VkImageSubresourceRange      subresourceRange;
4821                                                 getAspectFlags(dstTcuFormat),                                                                           // VkImageAspectFlags   aspectMask;
4822                                                         0u,                                                                                                                             // deUint32                             baseMipLevel;
4823                                                         VK_REMAINING_MIP_LEVELS,                                                                                // deUint32                             mipLevels;
4824                                                         0u,                                                                                                                             // deUint32                             baseArraySlice;
4825                                                         getArraySize(m_params.src.image)                                                                // deUint32                             arraySize;
4826                                         }
4827                                 };
4828
4829                                 if (getArraySize(m_params.src.image) == 1)
4830                                 {
4831                                         DE_ASSERT(barrierno < m_params.mipLevels);
4832                                         preImageBarrier.subresourceRange.baseMipLevel   = barrierno;
4833                                         preImageBarrier.subresourceRange.levelCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4834                                 }
4835                                 else
4836                                 {
4837                                         preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
4838                                         preImageBarrier.subresourceRange.layerCount             = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4839                                 }
4840                                 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);
4841                         }
4842                 }
4843
4844                 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4845                 {
4846                         const deUint32  mipLevel        = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4847
4848                         // Prepare single mip level for writing
4849                         const VkImageMemoryBarrier              preImageBarrier         =
4850                         {
4851                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4852                                 DE_NULL,                                                                        // const void*                                  pNext;
4853                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
4854                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4855                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
4856                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4857                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4858                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4859                                 m_destination.get(),                                            // VkImage                                      image;
4860                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4861                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4862                                         mipLevel,                                                       // deUint32                             baseMipLevel;
4863                                         1u,                                                                     // deUint32                             mipLevels;
4864                                         0u,                                                                     // deUint32                             baseArraySlice;
4865                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4866                                 }
4867                         };
4868
4869                         // Prepare single mip level for reading
4870                         const VkImageMemoryBarrier              postImageBarrier        =
4871                         {
4872                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4873                                 DE_NULL,                                                                        // const void*                          pNext;
4874                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
4875                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
4876                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        oldLayout;
4877                                 m_params.src.image.operationLayout,                     // VkImageLayout                        newLayout;
4878                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4879                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4880                                 m_destination.get(),                                            // VkImage                                      image;
4881                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4882                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4883                                         mipLevel,                                                       // deUint32                             baseMipLevel;
4884                                         1u,                                                                     // deUint32                             mipLevels;
4885                                         0u,                                                                     // deUint32                             baseArraySlice;
4886                                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
4887                                 }
4888                         };
4889
4890                         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);
4891
4892                         if (m_params.extensionUse == EXTENSION_USE_NONE)
4893                         {
4894                                 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);
4895                         }
4896                         else
4897                         {
4898                                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4899                                 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4900                                 {
4901                                         VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,        // VkStructureType                              sType;
4902                                         DE_NULL,                                                                        // const void*                                  pNext;
4903                                         m_destination.get(),                                            // VkImage                                              srcImage;
4904                                         m_params.src.image.operationLayout,                     // VkImageLayout                                srcImageLayout;
4905                                         m_destination.get(),                                            // VkImage                                              dstImage;
4906                                         m_params.dst.image.operationLayout,                     // VkImageLayout                                dstImageLayout;
4907                                         1u,                                                                                     // uint32_t                                             regionCount;
4908                                         &regions2KHR[regionNdx],                                        // const VkImageBlit2KHR*               pRegions;
4909                                         m_params.filter                                                         // VkFilter                                             filter;
4910                                 };
4911                                 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4912                         }
4913
4914                         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);
4915                 }
4916
4917                 // Prepare all mip levels for writing
4918                 {
4919                         const VkImageMemoryBarrier              postImageBarrier                =
4920                         {
4921                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
4922                                 DE_NULL,                                                                        // const void*                          pNext;
4923                                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        srcAccessMask;
4924                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
4925                                 m_params.src.image.operationLayout,                     // VkImageLayout                        oldLayout;
4926                                 m_params.dst.image.operationLayout,                     // VkImageLayout                        newLayout;
4927                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
4928                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
4929                                 m_destination.get(),                                            // VkImage                                      image;
4930                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
4931                                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
4932                                         0u,                                                                     // deUint32                             baseMipLevel;
4933                                         VK_REMAINING_MIP_LEVELS,                        // deUint32                             mipLevels;
4934                                         0u,                                                                     // deUint32                             baseArraySlice;
4935                                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
4936                                 }
4937                         };
4938
4939                         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);
4940                 }
4941         }
4942
4943         endCommandBuffer(vk, *m_cmdBuffer);
4944         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4945
4946         return checkTestResult();
4947 }
4948
4949 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
4950 {
4951         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
4952         bool                                            allLevelsOk             = true;
4953
4954         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4955         {
4956                 // Update reference results with previous results that have been verified.
4957                 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
4958                 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4959                 {
4960                         const CopyRegion region = m_params.regions[i];
4961                         const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
4962                         const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
4963                         de::MovePtr<tcu::TextureLevel>  prevResultLevel;
4964                         tcu::ConstPixelBufferAccess src;
4965                         if (srcMipLevel < mipLevelNdx)
4966                         {
4967                                 // Generate expected result from rendered result that was previously verified
4968                                 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
4969                                 src = prevResultLevel->getAccess();
4970                         }
4971                         else
4972                         {
4973                                 // Previous reference mipmaps might have changed, so recompute expected result
4974                                 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
4975                         }
4976                         copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
4977                 }
4978
4979                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
4980                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
4981
4982                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
4983                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
4984                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
4985                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
4986                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
4987                                                                                                                                                                                                                                                                         resultAccess;
4988                 const tcu::ConstPixelBufferAccess               clampedLevel            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
4989                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
4990                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx]->getAccess();
4991                 const tcu::ConstPixelBufferAccess               unclampedLevel          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
4992                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
4993                                                                                                                                                                                                                                                                         m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
4994                 const tcu::TextureFormat                                srcFormat                       = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
4995                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
4996                                                                                                                                                                                                                                                                         mapVkFormat(m_params.src.image.format);
4997
4998                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
4999                 bool                                                                    singleLevelOk           = false;
5000                 std::vector <CopyRegion>                                mipLevelRegions;
5001
5002                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5003                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5004                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5005
5006                 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5007
5008                 if (isFloatFormat(dstFormat))
5009                 {
5010                         const bool              srcIsSRGB   = tcu::isSRGB(srcFormat);
5011                         const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5012                         const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
5013                         const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5014
5015                         singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5016                         log << tcu::TestLog::EndSection;
5017
5018                         if (!singleLevelOk)
5019                         {
5020                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5021                                 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5022                                 log << tcu::TestLog::EndSection;
5023                         }
5024                 }
5025                 else
5026                 {
5027                         tcu::UVec4  threshold;
5028                         // Calculate threshold depending on channel width of destination format.
5029                         const tcu::IVec4        dstBitDepth     = tcu::getTextureFormatBitDepth(dstFormat);
5030                         const tcu::IVec4        srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5031                         for (deUint32 i = 0; i < 4; ++i)
5032                                 threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5033
5034                         singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5035                         log << tcu::TestLog::EndSection;
5036
5037                         if (!singleLevelOk)
5038                         {
5039                                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5040                                 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5041                                 log << tcu::TestLog::EndSection;
5042                         }
5043                 }
5044                 allLevelsOk &= singleLevelOk;
5045         }
5046
5047         return allLevelsOk;
5048 }
5049
5050 bool BlittingMipmaps::checkNearestFilteredResult (void)
5051 {
5052         bool                                            allLevelsOk             = true;
5053         tcu::TestLog&                           log                             (m_context.getTestContext().getLog());
5054
5055         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5056         {
5057                 de::MovePtr<tcu::TextureLevel>                  resultLevel                     = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5058                 const tcu::ConstPixelBufferAccess&              resultAccess            = resultLevel->getAccess();
5059
5060                 const tcu::Sampler::DepthStencilMode    mode                            = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::Sampler::MODE_DEPTH :
5061                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5062                                                                                                                                                                                                                                                                         tcu::Sampler::MODE_LAST;
5063                 const tcu::ConstPixelBufferAccess               result                          = tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5064                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5065                                                                                                                                                                                                                                                                         resultAccess;
5066                 const tcu::ConstPixelBufferAccess               source                          = (m_params.singleCommand || mipLevelNdx == 0) ?                        //  Read from source image
5067                                                                                                                                           tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5068                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5069                                                                                                                                                                                                                                                                         m_sourceTextureLevel->getAccess()
5070                                                                                                                                                                                                                                                                 //  Read from destination image
5071                                                                                                                                         : tcu::hasDepthComponent(resultAccess.getFormat().order)        ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5072                                                                                                                                           tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5073                                                                                                                                                                                                                                                                         m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5074                 const tcu::TextureFormat                                dstFormat                       = result.getFormat();
5075                 const tcu::TextureChannelClass                  dstChannelClass         = tcu::getTextureChannelClass(dstFormat.type);
5076                 bool                                                                    singleLevelOk           = false;
5077                 std::vector <CopyRegion>                                mipLevelRegions;
5078
5079                 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5080                         if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5081                                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5082
5083                 tcu::TextureLevel                               errorMaskStorage        (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5084                 tcu::PixelBufferAccess                  errorMask                       = errorMaskStorage.getAccess();
5085                 tcu::Vec4                                               pixelBias                       (0.0f, 0.0f, 0.0f, 0.0f);
5086                 tcu::Vec4                                               pixelScale                      (1.0f, 1.0f, 1.0f, 1.0f);
5087
5088                 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5089
5090                 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5091                         dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5092                 {
5093                         singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5094                 }
5095                 else
5096                 {
5097                         const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5098                         const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5099
5100                         singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5101                 }
5102
5103                 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5104                         tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5105
5106                 if (!singleLevelOk)
5107                 {
5108                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5109                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5110                                 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5111                                 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5112                                 << tcu::TestLog::EndImageSet;
5113                 }
5114                 else
5115                 {
5116                         log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5117                                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5118                                 << tcu::TestLog::EndImageSet;
5119                 }
5120
5121                 allLevelsOk &= singleLevelOk;
5122         }
5123
5124         return allLevelsOk;
5125 }
5126
5127 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5128 {
5129         DE_UNREF(result);
5130         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5131         const std::string failMessage("Result image is incorrect");
5132
5133         if (m_params.filter != VK_FILTER_NEAREST)
5134         {
5135                 if (!checkNonNearestFilteredResult())
5136                         return tcu::TestStatus::fail(failMessage);
5137         }
5138         else // NEAREST filtering
5139         {
5140                 if (!checkNearestFilteredResult())
5141                         return tcu::TestStatus::fail(failMessage);
5142         }
5143
5144         return tcu::TestStatus::pass("Pass");
5145 }
5146
5147 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5148 {
5149         DE_ASSERT(src.getDepth() == dst.getDepth());
5150
5151         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5152                                                                                                 region.imageBlit.srcOffsets[1],
5153                                                                                                 region.imageBlit.dstOffsets[0],
5154                                                                                                 region.imageBlit.dstOffsets[1]);
5155
5156         flipCoordinates(region, mirrorMode);
5157
5158         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
5159         const VkOffset3D                                        srcExtent               =
5160         {
5161                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5162                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5163                 region.imageBlit.srcOffsets[1].z - srcOffset.z
5164         };
5165         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
5166         const VkOffset3D                                        dstExtent               =
5167         {
5168                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5169                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5170                 region.imageBlit.dstOffsets[1].z - dstOffset.z
5171         };
5172
5173         tcu::Sampler::FilterMode                filter;
5174         switch (m_params.filter)
5175         {
5176         case VK_FILTER_LINEAR:          filter = tcu::Sampler::LINEAR; break;
5177         case VK_FILTER_CUBIC_EXT:       filter = tcu::Sampler::CUBIC;  break;
5178         case VK_FILTER_NEAREST:
5179         default:                                        filter = tcu::Sampler::NEAREST;  break;
5180         }
5181
5182         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5183         {
5184                 DE_ASSERT(src.getFormat() == dst.getFormat());
5185                 // Scale depth.
5186                 if (tcu::hasDepthComponent(src.getFormat().order))
5187                 {
5188                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5189                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5190                         tcu::scale(dstSubRegion, srcSubRegion, filter);
5191
5192                         if (filter != tcu::Sampler::NEAREST)
5193                         {
5194                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5195                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5196                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5197                         }
5198                 }
5199
5200                 // Scale stencil.
5201                 if (tcu::hasStencilComponent(src.getFormat().order))
5202                 {
5203                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5204                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5205                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5206
5207                         if (filter != tcu::Sampler::NEAREST)
5208                         {
5209                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5210                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5211                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5212                         }
5213                 }
5214         }
5215         else
5216         {
5217                 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5218                 {
5219                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5220                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5221                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5222
5223                         if (filter != tcu::Sampler::NEAREST)
5224                         {
5225                                 const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5226                                 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5227                         }
5228                 }
5229         }
5230 }
5231
5232 void BlittingMipmaps::generateExpectedResult (void)
5233 {
5234         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
5235         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
5236
5237         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5238                 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5239
5240         tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5241
5242         if (m_params.filter != VK_FILTER_NEAREST)
5243         {
5244                 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5245                         m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5246
5247                 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5248         }
5249
5250         for (deUint32 i = 0; i < m_params.regions.size(); i++)
5251         {
5252                 CopyRegion region = m_params.regions[i];
5253                 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);
5254         }
5255 }
5256
5257 class BlitMipmapTestCase : public vkt::TestCase
5258 {
5259 public:
5260                                                         BlitMipmapTestCase              (tcu::TestContext&                              testCtx,
5261                                                                                                          const std::string&                             name,
5262                                                                                                          const std::string&                             description,
5263                                                                                                          const TestParams                               params)
5264                                                                 : vkt::TestCase (testCtx, name, description)
5265                                                                 , m_params              (params)
5266         {}
5267
5268         virtual TestInstance*   createInstance                  (Context&                                               context) const
5269         {
5270                 return new BlittingMipmaps(context, m_params);
5271         }
5272
5273         virtual void                    checkSupport                    (Context&                                               context) const
5274         {
5275                 const InstanceInterface&        vki                                     = context.getInstanceInterface();
5276                 const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
5277                 {
5278                         VkImageFormatProperties properties;
5279                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5280                                                                                                                                                                                 m_params.src.image.format,
5281                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
5282                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
5283                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5284                                                                                                                                                                                 0,
5285                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5286                         {
5287                                 TCU_THROW(NotSupportedError, "Format not supported");
5288                         }
5289                         else if ((m_params.src.image.extent.width       > properties.maxExtent.width)   ||
5290                                                 (m_params.src.image.extent.height       > properties.maxExtent.height)  ||
5291                                                 (m_params.src.image.extent.depth        > properties.maxArrayLayers))
5292                         {
5293                                 TCU_THROW(NotSupportedError, "Image size not supported");
5294                         }
5295                 }
5296
5297                 {
5298                         VkImageFormatProperties properties;
5299                         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5300                                                                                                                                                                                 m_params.dst.image.format,
5301                                                                                                                                                                                 VK_IMAGE_TYPE_2D,
5302                                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
5303                                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5304                                                                                                                                                                                 0,
5305                                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5306                         {
5307                                 TCU_THROW(NotSupportedError, "Format not supported");
5308                         }
5309                         else if ((m_params.dst.image.extent.width       > properties.maxExtent.width)   ||
5310                                                 (m_params.dst.image.extent.height       > properties.maxExtent.height)  ||
5311                                                 (m_params.dst.image.extent.depth        > properties.maxArrayLayers))
5312                         {
5313                                 TCU_THROW(NotSupportedError, "Image size not supported");
5314                         }
5315                         else if (m_params.mipLevels > properties.maxMipLevels)
5316                         {
5317                                 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5318                         }
5319                         else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)        &&
5320                                          (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5321                         {
5322                                 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5323                         }
5324                 }
5325
5326                 const VkFormatProperties        srcFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5327                 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5328                 {
5329                         TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5330                 }
5331
5332                 const VkFormatProperties        dstFormatProperties     = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5333                 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5334                 {
5335                         TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5336                 }
5337
5338                 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5339                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5340
5341                 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5342                 {
5343                         context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5344
5345                         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5346                         {
5347                                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5348                         }
5349                 }
5350         }
5351
5352 private:
5353         TestParams                              m_params;
5354 };
5355
5356 // Resolve image to image.
5357
5358 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
5359 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5360 {
5361 public:
5362                                                                                                 ResolveImageToImage                     (Context&                                                       context,
5363                                                                                                                                                          TestParams                                                     params,
5364                                                                                                                                                          const ResolveImageToImageOptions       options);
5365         virtual tcu::TestStatus                                         iterate                                         (void);
5366 protected:
5367         virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
5368         void                                                                            copyMSImageToMSImage            (deUint32 copyArraySize);
5369         tcu::TestStatus                                                         checkIntermediateCopy           (void);
5370 private:
5371         Move<VkImage>                                                           m_multisampledImage;
5372         de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
5373
5374         Move<VkImage>                                                           m_destination;
5375         de::MovePtr<Allocation>                                         m_destinationImageAlloc;
5376
5377         Move<VkImage>                                                           m_multisampledCopyImage;
5378         de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
5379
5380         const ResolveImageToImageOptions                        m_options;
5381
5382         virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
5383                                                                                                                                                          tcu::PixelBufferAccess                 dst,
5384                                                                                                                                                          CopyRegion                                             region,
5385                                                                                                                                                          deUint32                                               mipLevel = 0u);
5386 };
5387
5388 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5389         : CopiesAndBlittingTestInstance (context, params)
5390         , m_options                                             (options)
5391 {
5392         const InstanceInterface&        vki                                             = m_context.getInstanceInterface();
5393         const DeviceInterface&          vk                                              = m_context.getDeviceInterface();
5394         const VkPhysicalDevice          vkPhysDevice                    = m_context.getPhysicalDevice();
5395         const VkDevice                          vkDevice                                = m_context.getDevice();
5396         const deUint32                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
5397         Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
5398
5399         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5400         Move<VkRenderPass>                      renderPass;
5401
5402         Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5403         Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5404         std::vector<tcu::Vec4>          vertices;
5405
5406         Move<VkBuffer>                          vertexBuffer;
5407         de::MovePtr<Allocation>         vertexBufferAlloc;
5408
5409         Move<VkPipelineLayout>          pipelineLayout;
5410         Move<VkPipeline>                        graphicsPipeline;
5411
5412         const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
5413
5414         // Create color image.
5415         {
5416                 VkImageCreateInfo       colorImageParams        =
5417                 {
5418                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
5419                         DE_NULL,                                                                                                                                // const void*                          pNext;
5420                         getCreateFlags(m_params.src.image),                                                                             // VkImageCreateFlags           flags;
5421                         m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
5422                         m_params.src.image.format,                                                                                              // VkFormat                                     format;
5423                         getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
5424                         1u,                                                                                                                                             // deUint32                                     mipLevels;
5425                         getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
5426                         rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
5427                         VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
5428                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                                                                             // VkImageUsageFlags            usage;
5429                                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5430                                 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5431                         VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
5432                         1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
5433                         &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
5434                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
5435                 };
5436
5437                 m_multisampledImage                                             = createImage(vk, vkDevice, &colorImageParams);
5438
5439                 // Allocate and bind color image memory.
5440                 m_multisampledImageAlloc                                = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5441                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
5442
5443                 switch (m_options)
5444                 {
5445                         case COPY_MS_IMAGE_TO_MS_IMAGE:
5446                         {
5447                                 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;
5448                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
5449                                 // Allocate and bind color image memory.
5450                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5451                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5452                                 break;
5453                         }
5454
5455                         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5456                         {
5457                                 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;
5458                                 colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
5459                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
5460                                 // Allocate and bind color image memory.
5461                                 m_multisampledCopyImageAlloc    = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5462                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5463                                 break;
5464                         }
5465
5466                         default :
5467                                 break;
5468                 }
5469         }
5470
5471         // Create destination image.
5472         {
5473                 const VkImageCreateInfo destinationImageParams  =
5474                 {
5475                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
5476                         DE_NULL,                                                                // const void*                  pNext;
5477                         getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
5478                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
5479                         m_params.dst.image.format,                              // VkFormat                             format;
5480                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
5481                         1u,                                                                             // deUint32                             mipLevels;
5482                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
5483                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
5484                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
5485                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5486                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
5487                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
5488                         1u,                                                                             // deUint32                             queueFamilyCount;
5489                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
5490                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
5491                 };
5492
5493                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
5494                 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5495                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5496         }
5497
5498         // Barriers for copying image to buffer
5499         VkImageMemoryBarrier            srcImageBarrier         =
5500         {
5501                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5502                 DE_NULL,                                                                        // const void*                          pNext;
5503                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
5504                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
5505                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
5506                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
5507                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5508                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5509                 m_multisampledImage.get(),                                      // VkImage                                      image;
5510                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
5511                         VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
5512                         0u,                                                                     // deUint32                             baseMipLevel;
5513                         1u,                                                                     // deUint32                             mipLevels;
5514                         0u,                                                                     // deUint32                             baseArraySlice;
5515                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
5516                 }
5517         };
5518
5519         // Create render pass.
5520         {
5521                 const VkAttachmentDescription   attachmentDescriptions[1]       =
5522                 {
5523                         {
5524                                 0u,                                                                                     // VkAttachmentDescriptionFlags         flags;
5525                                 m_params.src.image.format,                                      // VkFormat                                                     format;
5526                                 rasterizationSamples,                                           // VkSampleCountFlagBits                        samples;
5527                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
5528                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
5529                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
5530                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
5531                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
5532                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
5533                         },
5534                 };
5535
5536                 const VkAttachmentReference             colorAttachmentReference        =
5537                 {
5538                         0u,                                                                                                     // deUint32                     attachment;
5539                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
5540                 };
5541
5542                 const VkSubpassDescription              subpassDescription                      =
5543                 {
5544                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
5545                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
5546                         0u,                                                                     // deUint32                                             inputAttachmentCount;
5547                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
5548                         1u,                                                                     // deUint32                                             colorAttachmentCount;
5549                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
5550                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
5551                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
5552                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
5553                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
5554                 };
5555
5556                 const VkRenderPassCreateInfo    renderPassParams                        =
5557                 {
5558                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
5559                         DE_NULL,                                                                        // const void*                                          pNext;
5560                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
5561                         1u,                                                                                     // deUint32                                                     attachmentCount;
5562                         attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments;
5563                         1u,                                                                                     // deUint32                                                     subpassCount;
5564                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
5565                         0u,                                                                                     // deUint32                                                     dependencyCount;
5566                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
5567                 };
5568
5569                 renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
5570         }
5571
5572         // Create pipeline layout
5573         {
5574                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
5575                 {
5576                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
5577                         DE_NULL,                                                                                        // const void*                                          pNext;
5578                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
5579                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
5580                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
5581                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
5582                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
5583                 };
5584
5585                 pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5586         }
5587
5588         // Create upper half triangle.
5589         {
5590                 const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
5591                 const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
5592                 const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
5593                 // Add triangle.
5594                 vertices.push_back(a);
5595                 vertices.push_back(c);
5596                 vertices.push_back(b);
5597         }
5598
5599         // Create vertex buffer.
5600         {
5601                 const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
5602                 const VkBufferCreateInfo        vertexBufferParams      =
5603                 {
5604                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
5605                         DE_NULL,                                                                        // const void*                  pNext;
5606                         0u,                                                                                     // VkBufferCreateFlags  flags;
5607                         vertexDataSize,                                                         // VkDeviceSize                 size;
5608                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
5609                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
5610                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
5611                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
5612                 };
5613
5614                 vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
5615                 vertexBufferAlloc       = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
5616                 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
5617
5618                 // Load vertices into vertex buffer.
5619                 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
5620                 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
5621         }
5622
5623         {
5624                 Move<VkFramebuffer>             framebuffer;
5625                 Move<VkImageView>               sourceAttachmentView;
5626
5627                 // Create color attachment view.
5628                 {
5629                         const VkImageViewCreateInfo     colorAttachmentViewParams       =
5630                         {
5631                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
5632                                 DE_NULL,                                                                                                // const void*                          pNext;
5633                                 0u,                                                                                                             // VkImageViewCreateFlags       flags;
5634                                 *m_multisampledImage,                                                                   // VkImage                                      image;
5635                                 VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
5636                                 m_params.src.image.format,                                                              // VkFormat                                     format;
5637                                 componentMappingRGBA,                                                                   // VkComponentMapping           components;
5638                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
5639                         };
5640                         sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
5641                 }
5642
5643                 // Create framebuffer
5644                 {
5645                         const VkImageView                               attachments[1]          =
5646                         {
5647                                         *sourceAttachmentView,
5648                         };
5649
5650                         const VkFramebufferCreateInfo   framebufferParams       =
5651                         {
5652                                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
5653                                         DE_NULL,                                                                                        // const void*                                  pNext;
5654                                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
5655                                         *renderPass,                                                                            // VkRenderPass                                 renderPass;
5656                                         1u,                                                                                                     // deUint32                                             attachmentCount;
5657                                         attachments,                                                                            // const VkImageView*                   pAttachments;
5658                                         m_params.src.image.extent.width,                                        // deUint32                                             width;
5659                                         m_params.src.image.extent.height,                                       // deUint32                                             height;
5660                                         1u                                                                                                      // deUint32                                             layers;
5661                         };
5662
5663                         framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
5664                 }
5665
5666                 // Create pipeline
5667                 {
5668                         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
5669                         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
5670
5671                         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
5672                         {
5673                                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
5674                                 DE_NULL,                                                                                                        // const void*                                                          pNext;
5675                                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
5676                                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
5677                                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
5678                                 0.0f,                                                                                                           // float                                                                        minSampleShading;
5679                                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
5680                                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
5681                                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
5682                         };
5683
5684                         graphicsPipeline = makeGraphicsPipeline(vk,                                                                             // const DeviceInterface&                        vk
5685                                                                                                         vkDevice,                                                               // const VkDevice                                device
5686                                                                                                         *pipelineLayout,                                                // const VkPipelineLayout                        pipelineLayout
5687                                                                                                         *vertexShaderModule,                                    // const VkShaderModule                          vertexShaderModule
5688                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
5689                                                                                                         DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
5690                                                                                                         DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
5691                                                                                                         *fragmentShaderModule,                                  // const VkShaderModule                          fragmentShaderModule
5692                                                                                                         *renderPass,                                                    // const VkRenderPass                            renderPass
5693                                                                                                         viewports,                                                              // const std::vector<VkViewport>&                viewports
5694                                                                                                         scissors,                                                               // const std::vector<VkRect2D>&                  scissors
5695                                                                                                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
5696                                                                                                         0u,                                                                             // const deUint32                                subpass
5697                                                                                                         0u,                                                                             // const deUint32                                patchControlPoints
5698                                                                                                         DE_NULL,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
5699                                                                                                         DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5700                                                                                                         &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
5701                 }
5702
5703                 // Create command buffer
5704                 {
5705                         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
5706                         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);
5707                         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));
5708
5709                         const VkDeviceSize      vertexBufferOffset      = 0u;
5710
5711                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5712                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5713                         vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
5714
5715                         endRenderPass(vk, *m_cmdBuffer);
5716                         endCommandBuffer(vk, *m_cmdBuffer);
5717                 }
5718
5719                 // Queue submit.
5720                 {
5721                         const VkQueue   queue   = m_context.getUniversalQueue();
5722                         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
5723                 }
5724         }
5725 }
5726
5727 tcu::TestStatus ResolveImageToImage::iterate (void)
5728 {
5729         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
5730         const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
5731
5732         // upload the destination image
5733         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
5734                                                                                                                                                         (int)m_params.dst.image.extent.width,
5735                                                                                                                                                         (int)m_params.dst.image.extent.height,
5736                                                                                                                                                         (int)m_params.dst.image.extent.depth));
5737         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
5738         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
5739
5740         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
5741                                                                                                                                         (int)m_params.src.image.extent.width,
5742                                                                                                                                         (int)m_params.src.image.extent.height,
5743                                                                                                                                         (int)m_params.dst.image.extent.depth));
5744
5745         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);
5746         generateExpectedResult();
5747
5748         VkImage         sourceImage             = m_multisampledImage.get();
5749         deUint32        sourceArraySize = getArraySize(m_params.src.image);
5750
5751         switch (m_options)
5752         {
5753                 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5754                         // Duplicate the multisampled image to a multisampled image array
5755                         sourceArraySize = getArraySize(m_params.dst.image); // fall through
5756                 case COPY_MS_IMAGE_TO_MS_IMAGE:
5757                         copyMSImageToMSImage(sourceArraySize);
5758                         sourceImage     = m_multisampledCopyImage.get();
5759                         break;
5760                 default:
5761                         break;
5762         }
5763
5764         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
5765         const VkDevice                                  vkDevice                        = m_context.getDevice();
5766         const VkQueue                                   queue                           = m_context.getUniversalQueue();
5767
5768         std::vector<VkImageResolve>             imageResolves;
5769         std::vector<VkImageResolve2KHR> imageResolves2KHR;
5770         for (deUint32 i = 0; i < m_params.regions.size(); i++)
5771         {
5772                 if (m_params.extensionUse == EXTENSION_USE_NONE)
5773                 {
5774                         imageResolves.push_back(m_params.regions[i].imageResolve);
5775                 }
5776                 else
5777                 {
5778                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5779                         imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(m_params.regions[i].imageResolve));
5780                 }
5781         }
5782
5783         const VkImageMemoryBarrier      imageBarriers[]         =
5784         {
5785                 // source image
5786                 {
5787                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5788                         DE_NULL,                                                                        // const void*                          pNext;
5789                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
5790                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
5791                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
5792                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
5793                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5794                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5795                         sourceImage,                                                            // VkImage                                      image;
5796                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5797                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
5798                                 0u,                                                                     // deUint32                             baseMipLevel;
5799                                 1u,                                                                     // deUint32                             mipLevels;
5800                                 0u,                                                                     // deUint32                             baseArraySlice;
5801                                 sourceArraySize                                         // deUint32                             arraySize;
5802                         }
5803                 },
5804                 // destination image
5805                 {
5806                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
5807                         DE_NULL,                                                                        // const void*                          pNext;
5808                         0u,                                                                                     // VkAccessFlags                        srcAccessMask;
5809                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
5810                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
5811                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
5812                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
5813                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
5814                         m_destination.get(),                                            // VkImage                                      image;
5815                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
5816                                 getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
5817                                 0u,                                                                     // deUint32                             baseMipLevel;
5818                                 1u,                                                                     // deUint32                             mipLevels;
5819                                 0u,                                                                     // deUint32                             baseArraySlice;
5820                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
5821                         }
5822                 },
5823         };
5824
5825         const VkImageMemoryBarrier postImageBarrier =
5826         {
5827                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
5828                 DE_NULL,                                                                // const void*                          pNext;
5829                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask;
5830                 VK_ACCESS_HOST_READ_BIT,                                // VkAccessFlags                        dstAccessMask;
5831                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        oldLayout;
5832                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
5833                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
5834                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
5835                 m_destination.get(),                                    // VkImage                                      image;
5836                 {                                                                               // VkImageSubresourceRange      subresourceRange;
5837                         getAspectFlags(dstTcuFormat),           // VkImageAspectFlags           aspectMask;
5838                         0u,                                                                     // deUint32                                     baseMipLevel;
5839                         1u,                                                                     // deUint32                                     mipLevels;
5840                         0u,                                                                     // deUint32                                     baseArraySlice;
5841                         getArraySize(m_params.dst.image)        // deUint32                                     arraySize;
5842                 }
5843         };
5844
5845         beginCommandBuffer(vk, *m_cmdBuffer);
5846         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);
5847
5848         if (m_params.extensionUse == EXTENSION_USE_NONE)
5849         {
5850                 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());
5851         }
5852         else
5853         {
5854                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5855                 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
5856                 {
5857                         VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,     // VkStructureType                              sType;
5858                         DE_NULL,                                                                        // const void*                                  pNext;
5859                         sourceImage,                                                            // VkImage                                              srcImage;
5860                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                                srcImageLayout;
5861                         m_destination.get(),                                            // VkImage                                              dstImage;
5862                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                                dstImageLayout;
5863                         (deUint32)m_params.regions.size(),                      // uint32_t                                             regionCount;
5864                         imageResolves2KHR.data()                                        // const  VkImageResolve2KHR*   pRegions;
5865                 };
5866                 vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
5867         }
5868
5869         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);
5870         endCommandBuffer(vk, *m_cmdBuffer);
5871         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5872
5873         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
5874
5875         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
5876         {
5877                 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
5878                 // resolving the image and giving every sample the same value.
5879                 const auto intermediateResult = checkIntermediateCopy();
5880                 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
5881                         return intermediateResult;
5882         }
5883
5884         return checkTestResult(resultTextureLevel->getAccess());
5885 }
5886
5887 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
5888 {
5889         const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel[0]->getAccess();
5890         const float                                                     fuzzyThreshold  = 0.01f;
5891
5892         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
5893         {
5894                 const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
5895                 const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
5896                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
5897                         return tcu::TestStatus::fail("CopiesAndBlitting test");
5898         }
5899
5900         return tcu::TestStatus::pass("CopiesAndBlitting test");
5901 }
5902
5903 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5904 {
5905         DE_UNREF(mipLevel);
5906
5907         VkOffset3D srcOffset    = region.imageResolve.srcOffset;
5908                         srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
5909         VkOffset3D dstOffset    = region.imageResolve.dstOffset;
5910                         dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
5911         VkExtent3D extent               = region.imageResolve.extent;
5912                         extent.depth            = region.imageResolve.srcSubresource.layerCount;
5913
5914         const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
5915         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
5916         const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
5917         const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
5918
5919         tcu::copy(dstSubRegion, srcSubRegion);
5920 }
5921
5922 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
5923 {
5924         const           auto&   vkd                                     = m_context.getDeviceInterface();
5925         const           auto    device                          = m_context.getDevice();
5926         const           auto    queue                           = m_context.getUniversalQueue();
5927         const           auto    queueIndex                      = m_context.getUniversalQueueFamilyIndex();
5928                                 auto&   alloc                           = m_context.getDefaultAllocator();
5929         const           auto    currentLayout           = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5930         const           auto    numDstLayers            = getArraySize(m_params.dst.image);
5931         const           auto    numInputAttachments     = numDstLayers + 1u; // For the source image.
5932         constexpr       auto    numSets                         = 2u; // 1 for the output buffer, 1 for the input attachments.
5933         const           auto    fbWidth                         = m_params.src.image.extent.width;
5934         const           auto    fbHeight                        = m_params.src.image.extent.height;
5935
5936         // Push constants.
5937         const std::array<int, 3> pushConstantData =
5938         {{
5939                 static_cast<int>(fbWidth),
5940                 static_cast<int>(fbHeight),
5941                 static_cast<int>(m_params.samples),
5942         }};
5943         const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
5944
5945         // Shader modules.
5946         const auto vertexModule                 = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
5947         const auto verificationModule   = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
5948
5949         // Descriptor sets.
5950         DescriptorPoolBuilder poolBuilder;
5951         poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
5952         poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
5953         const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
5954
5955         DescriptorSetLayoutBuilder layoutBuilderBuffer;
5956         layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
5957         const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
5958
5959         DescriptorSetLayoutBuilder layoutBuilderAttachments;
5960         for (deUint32 i = 0u; i < numInputAttachments; ++i)
5961                 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
5962         const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
5963
5964         const auto descriptorSetBuffer          = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
5965         const auto descriptorSetAttachments     = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
5966
5967         // Array with raw descriptor sets.
5968         const std::array<VkDescriptorSet, numSets> descriptorSets =
5969         {{
5970                 descriptorSetBuffer.get(),
5971                 descriptorSetAttachments.get(),
5972         }};
5973
5974         // Pipeline layout.
5975         const std::array<VkDescriptorSetLayout, numSets> setLayouts =
5976         {{
5977                 outputBufferSetLayout.get(),
5978                 inputAttachmentsSetLayout.get(),
5979         }};
5980
5981         const VkPushConstantRange pushConstantRange =
5982         {
5983                 VK_SHADER_STAGE_FRAGMENT_BIT,   //      VkShaderStageFlags      stageFlags;
5984                 0u,                                                             //      deUint32                        offset;
5985                 pushConstantSize,                               //      deUint32                        size;
5986         };
5987
5988         const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
5989         {
5990                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  //      VkStructureType                                 sType;
5991                 nullptr,                                                                                //      const void*                                             pNext;
5992                 0u,                                                                                             //      VkPipelineLayoutCreateFlags             flags;
5993                 static_cast<deUint32>(setLayouts.size()),               //      deUint32                                                setLayoutCount;
5994                 setLayouts.data(),                                                              //      const VkDescriptorSetLayout*    pSetLayouts;
5995                 1u,                                                                                             //      deUint32                                                pushConstantRangeCount;
5996                 &pushConstantRange,                                                             //      const VkPushConstantRange*              pPushConstantRanges;
5997         };
5998
5999         const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6000
6001         // Render pass.
6002         const VkAttachmentDescription commonAttachmentDescription =
6003         {
6004                 0u,                                                                     //      VkAttachmentDescriptionFlags    flags;
6005                 m_params.src.image.format,                      //      VkFormat                                                format;
6006                 m_params.samples,                                       //      VkSampleCountFlagBits                   samples;
6007                 VK_ATTACHMENT_LOAD_OP_LOAD,                     //      VkAttachmentLoadOp                              loadOp;
6008                 VK_ATTACHMENT_STORE_OP_STORE,           //      VkAttachmentStoreOp                             storeOp;
6009                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,        //      VkAttachmentLoadOp                              stencilLoadOp;
6010                 VK_ATTACHMENT_STORE_OP_DONT_CARE,       //      VkAttachmentStoreOp                             stencilStoreOp;
6011                 currentLayout,                                          //      VkImageLayout                                   initialLayout;
6012                 currentLayout,                                          //      VkImageLayout                                   finalLayout;
6013         };
6014         const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6015
6016         std::vector<VkAttachmentReference> inputAttachmentReferences;
6017         inputAttachmentReferences.reserve(numInputAttachments);
6018         for (deUint32 i = 0u; i < numInputAttachments; ++i)
6019         {
6020                 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6021                 inputAttachmentReferences.push_back(reference);
6022         }
6023
6024         const VkSubpassDescription subpassDescription =
6025         {
6026                 0u,                                                                                                                     //      VkSubpassDescriptionFlags               flags;
6027                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                                        //      VkPipelineBindPoint                             pipelineBindPoint;
6028                 static_cast<deUint32>(inputAttachmentReferences.size()),        //      deUint32                                                inputAttachmentCount;
6029                 inputAttachmentReferences.data(),                                                       //      const VkAttachmentReference*    pInputAttachments;
6030                 0u,                                                                                                                     //      deUint32                                                colorAttachmentCount;
6031                 nullptr,                                                                                                        //      const VkAttachmentReference*    pColorAttachments;
6032                 nullptr,                                                                                                        //      const VkAttachmentReference*    pResolveAttachments;
6033                 nullptr,                                                                                                        //      const VkAttachmentReference*    pDepthStencilAttachment;
6034                 0u,                                                                                                                     //      deUint32                                                preserveAttachmentCount;
6035                 nullptr,                                                                                                        //      const deUint32*                                 pPreserveAttachments;
6036         };
6037
6038         const VkRenderPassCreateInfo renderPassInfo =
6039         {
6040                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                              //      VkStructureType                                 sType;
6041                 nullptr,                                                                                                //      const void*                                             pNext;
6042                 0u,                                                                                                             //      VkRenderPassCreateFlags                 flags;
6043                 static_cast<deUint32>(attachmentDescriptions.size()),   //      deUint32                                                attachmentCount;
6044                 attachmentDescriptions.data(),                                                  //      const VkAttachmentDescription*  pAttachments;
6045                 1u,                                                                                                             //      deUint32                                                subpassCount;
6046                 &subpassDescription,                                                                    //      const VkSubpassDescription*             pSubpasses;
6047                 0u,                                                                                                             //      deUint32                                                dependencyCount;
6048                 nullptr,                                                                                                //      const VkSubpassDependency*              pDependencies;
6049         };
6050
6051         const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6052
6053         // Framebuffer.
6054         std::vector<Move<VkImageView>>  imageViews;
6055         std::vector<VkImageView>                imageViewsRaw;
6056
6057         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)));
6058         for (deUint32 i = 0u; i < numDstLayers; ++i)
6059         {
6060                 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6061                 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6062         }
6063
6064         imageViewsRaw.reserve(imageViews.size());
6065         std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6066
6067         const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6068
6069         // Storage buffer.
6070         const auto                      bufferCount     = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6071         const auto                      bufferSize      = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6072         BufferWithMemory        buffer          (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6073         auto&                           bufferAlloc     = buffer.getAllocation();
6074         void*                           bufferData      = bufferAlloc.getHostPtr();
6075
6076         // Update descriptor sets.
6077         DescriptorSetUpdateBuilder updater;
6078
6079         const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6080         updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6081
6082         std::vector<VkDescriptorImageInfo> imageInfos;
6083         imageInfos.reserve(imageViewsRaw.size());
6084         for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6085                 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6086
6087         for (size_t i = 0; i < imageInfos.size(); ++i)
6088                 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6089
6090         updater.update(vkd, device);
6091
6092         // Vertex buffer.
6093         std::vector<tcu::Vec4> fullScreenQuad;
6094         {
6095                 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6096                 const tcu::Vec4 topLeft         (-1.0f, -1.0f, 0.0f, 1.0f);
6097                 const tcu::Vec4 topRight        ( 1.0f, -1.0f, 0.0f, 1.0f);
6098                 const tcu::Vec4 bottomLeft      (-1.0f,  1.0f, 0.0f, 1.0f);
6099                 const tcu::Vec4 bottomRight     ( 1.0f,  1.0f, 0.0f, 1.0f);
6100
6101                 fullScreenQuad.reserve(6u);
6102                 fullScreenQuad.push_back(topLeft);
6103                 fullScreenQuad.push_back(topRight);
6104                 fullScreenQuad.push_back(bottomRight);
6105                 fullScreenQuad.push_back(topLeft);
6106                 fullScreenQuad.push_back(bottomRight);
6107                 fullScreenQuad.push_back(bottomLeft);
6108         }
6109
6110         const auto                              vertexBufferSize        = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6111         const auto                              vertexBufferInfo        = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6112         const BufferWithMemory  vertexBuffer            (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6113         const auto                              vertexBufferHandler     = vertexBuffer.get();
6114         auto&                                   vertexBufferAlloc       = vertexBuffer.getAllocation();
6115         void*                                   vertexBufferData        = vertexBufferAlloc.getHostPtr();
6116         const VkDeviceSize              vertexBufferOffset      = 0ull;
6117
6118         deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6119         flushAlloc(vkd, device, vertexBufferAlloc);
6120
6121         // Graphics pipeline.
6122         const std::vector<VkViewport>   viewports       (1, makeViewport(m_params.src.image.extent));
6123         const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_params.src.image.extent));
6124
6125         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
6126         {
6127                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
6128                 nullptr,                                                                                                        // const void*                                                          pNext;
6129                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
6130                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
6131                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
6132                 0.0f,                                                                                                           // float                                                                        minSampleShading;
6133                 nullptr,                                                                                                        // const VkSampleMask*                                          pSampleMask;
6134                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
6135                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
6136         };
6137
6138         const auto graphicsPipeline = makeGraphicsPipeline(
6139                 vkd,                                                                    // const DeviceInterface&                        vk
6140                 device,                                                                 // const VkDevice                                device
6141                 pipelineLayout.get(),                                   // const VkPipelineLayout                        pipelineLayout
6142                 vertexModule.get(),                                             // const VkShaderModule                          vertexShaderModule
6143                 DE_NULL,                                                                // const VkShaderModule                          tessellationControlModule
6144                 DE_NULL,                                                                // const VkShaderModule                          tessellationEvalModule
6145                 DE_NULL,                                                                // const VkShaderModule                          geometryShaderModule
6146                 verificationModule.get(),                               // const VkShaderModule                          fragmentShaderModule
6147                 renderPass.get(),                                               // const VkRenderPass                            renderPass
6148                 viewports,                                                              // const std::vector<VkViewport>&                viewports
6149                 scissors,                                                               // const std::vector<VkRect2D>&                  scissors
6150                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                     topology
6151                 0u,                                                                             // const deUint32                                subpass
6152                 0u,                                                                             // const deUint32                                patchControlPoints
6153                 nullptr,                                                                // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6154                 nullptr,                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6155                 &multisampleStateParams);                               // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6156
6157         // Command buffer.
6158         const auto cmdPool              = makeCommandPool(vkd, device, queueIndex);
6159         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6160         const auto cmdBuffer    = cmdBufferPtr.get();
6161
6162         // Make sure multisample copy data is available to the fragment shader.
6163         const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6164
6165         // Make sure verification buffer data is available on the host.
6166         const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6167
6168         // Record and submit command buffer.
6169         beginCommandBuffer(vkd, cmdBuffer);
6170         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6171         beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6172         vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6173         vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6174         vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6175         vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6176         vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6177         endRenderPass(vkd, cmdBuffer);
6178         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6179         endCommandBuffer(vkd, cmdBuffer);
6180         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6181
6182         // Verify intermediate results.
6183         invalidateAlloc(vkd, device, bufferAlloc);
6184         std::vector<deInt32> outputFlags (bufferCount, 0);
6185         deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6186
6187         auto& log = m_context.getTestContext().getLog();
6188         log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6189
6190         const auto sampleCount = static_cast<deUint32>(m_params.samples);
6191
6192         for (deUint32 x = 0u; x < fbWidth; ++x)
6193         for (deUint32 y = 0u; y < fbHeight; ++y)
6194         for (deUint32 s = 0u; s < sampleCount; ++s)
6195         {
6196                 const auto index = (y * fbWidth + x) * sampleCount + s;
6197                 if (!outputFlags[index])
6198                 {
6199                         std::ostringstream msg;
6200                         msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6201                         return tcu::TestStatus::fail(msg.str());
6202                 }
6203         }
6204
6205         log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6206         return tcu::TestStatus::pass("Pass");
6207 }
6208
6209 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6210 {
6211         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
6212         const VkDevice                                  vkDevice                        = m_context.getDevice();
6213         const VkQueue                                   queue                           = m_context.getUniversalQueue();
6214         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
6215         std::vector<VkImageCopy>                imageCopies;
6216         std::vector<VkImageCopy2KHR>    imageCopies2KHR;
6217
6218         for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6219         {
6220                 const VkImageSubresourceLayers  sourceSubresourceLayers =
6221                 {
6222                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
6223                         0u,                                                             // deUint32                             mipLevel;
6224                         0u,                                                             // deUint32                             baseArrayLayer;
6225                         1u                                                              // deUint32                             layerCount;
6226                 };
6227
6228                 const VkImageSubresourceLayers  destinationSubresourceLayers    =
6229                 {
6230                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
6231                         0u,                                                             // deUint32                             mipLevel;
6232                         layerNdx,                                               // deUint32                             baseArrayLayer;
6233                         1u                                                              // deUint32                             layerCount;
6234                 };
6235
6236                 const VkImageCopy                               imageCopy       =
6237                 {
6238                         sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
6239                         {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
6240                         destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
6241                         {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
6242                          getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
6243                 };
6244
6245                 if (m_params.extensionUse == EXTENSION_USE_NONE)
6246                 {
6247                         imageCopies.push_back(imageCopy);
6248                 }
6249                 else
6250                 {
6251                         DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6252                         imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6253                 }
6254         }
6255
6256         const VkImageMemoryBarrier              imageBarriers[]         =
6257         {
6258                 // source image
6259                 {
6260                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6261                         DE_NULL,                                                                        // const void*                          pNext;
6262                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
6263                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
6264                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
6265                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
6266                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6267                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6268                         m_multisampledImage.get(),                                      // VkImage                                      image;
6269                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
6270                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6271                                 0u,                                                                     // deUint32                             baseMipLevel;
6272                                 1u,                                                                     // deUint32                             mipLevels;
6273                                 0u,                                                                     // deUint32                             baseArraySlice;
6274                                 getArraySize(m_params.src.image)        // deUint32                             arraySize;
6275                         }
6276                 },
6277                 // destination image
6278                 {
6279                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6280                         DE_NULL,                                                                        // const void*                          pNext;
6281                         0,                                                                                      // VkAccessFlags                        srcAccessMask;
6282                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
6283                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
6284                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
6285                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6286                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6287                         m_multisampledCopyImage.get(),                          // VkImage                                      image;
6288                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
6289                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6290                                 0u,                                                                     // deUint32                             baseMipLevel;
6291                                 1u,                                                                     // deUint32                             mipLevels;
6292                                 0u,                                                                     // deUint32                             baseArraySlice;
6293                                 copyArraySize                                           // deUint32                             arraySize;
6294                         }
6295                 },
6296         };
6297
6298         const VkImageMemoryBarrier      postImageBarriers               =
6299         // destination image
6300         {
6301                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
6302                 DE_NULL,                                                                        // const void*                          pNext;
6303                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
6304                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
6305                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
6306                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
6307                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
6308                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
6309                 m_multisampledCopyImage.get(),                          // VkImage                                      image;
6310                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
6311                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
6312                         0u,                                                                     // deUint32                             baseMipLevel;
6313                         1u,                                                                     // deUint32                             mipLevels;
6314                         0u,                                                                     // deUint32                             baseArraySlice;
6315                         copyArraySize                                           // deUint32                             arraySize;
6316                 }
6317         };
6318
6319         beginCommandBuffer(vk, *m_cmdBuffer);
6320         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);
6321
6322         if (m_params.extensionUse == EXTENSION_USE_NONE)
6323         {
6324                 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());
6325         }
6326         else
6327         {
6328                 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6329                 const VkCopyImageInfo2KHR copyImageInfo2KHR =
6330                 {
6331                         VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,        // VkStructureType                      sType;
6332                         DE_NULL,                                                                        // const void*                          pNext;
6333                         m_multisampledImage.get(),                                      // VkImage                                      srcImage;
6334                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        srcImageLayout;
6335                         m_multisampledCopyImage.get(),                          // VkImage                                      dstImage;
6336                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        dstImageLayout;
6337                         (deUint32)imageCopies2KHR.size(),                       // uint32_t                                     regionCount;
6338                         imageCopies2KHR.data()                                          // const VkImageCopy2KHR*       pRegions;
6339                 };
6340
6341                 vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
6342         }
6343
6344         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);
6345         endCommandBuffer(vk, *m_cmdBuffer);
6346
6347         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
6348 }
6349
6350 class ResolveImageToImageTestCase : public vkt::TestCase
6351 {
6352 public:
6353                                                         ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
6354                                                                                                                  const std::string&                                     name,
6355                                                                                                                  const std::string&                                     description,
6356                                                                                                                  const TestParams                                       params,
6357                                                                                                                  const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
6358                                                                 : vkt::TestCase (testCtx, name, description)
6359                                                                 , m_params              (params)
6360                                                                 , m_options             (options)
6361         {}
6362
6363                                                         virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
6364
6365         virtual TestInstance*   createInstance                          (Context&                               context) const
6366         {
6367                 return new ResolveImageToImage(context, m_params, m_options);
6368         }
6369
6370         virtual void                    checkSupport                            (Context&                               context) const
6371         {
6372                 const VkSampleCountFlagBits     rasterizationSamples = m_params.samples;
6373
6374                 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
6375                         throw tcu::NotSupportedError("Unsupported number of rasterization samples");
6376
6377                 VkImageFormatProperties properties;
6378                 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6379                                                                                                                                                                         m_params.src.image.format,
6380                                                                                                                                                                         m_params.src.image.imageType,
6381                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
6382                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
6383                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
6384                         (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6385                                                                                                                                                                         m_params.dst.image.format,
6386                                                                                                                                                                         m_params.dst.image.imageType,
6387                                                                                                                                                                         VK_IMAGE_TILING_OPTIMAL,
6388                                                                                                                                                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
6389                                                                                                                                                                         &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
6390                 {
6391                         TCU_THROW(NotSupportedError, "Format not supported");
6392                 }
6393
6394                 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)     &&
6395                         (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
6396                 {
6397                         TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
6398                 }
6399         }
6400
6401 private:
6402         TestParams                                                      m_params;
6403         const ResolveImageToImageOptions        m_options;
6404 };
6405
6406 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
6407 {
6408         programCollection.glslSources.add("vert") << glu::VertexSource(
6409                 "#version 310 es\n"
6410                 "layout (location = 0) in highp vec4 a_position;\n"
6411                 "void main()\n"
6412                 "{\n"
6413                 "       gl_Position = a_position;\n"
6414                 "}\n");
6415
6416
6417         programCollection.glslSources.add("frag") << glu::FragmentSource(
6418                 "#version 310 es\n"
6419                 "layout (location = 0) out highp vec4 o_color;\n"
6420                 "void main()\n"
6421                 "{\n"
6422                 "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6423                 "}\n");
6424
6425         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE)
6426         {
6427                 // The shader verifies all layers in the copied image are the same as the source image.
6428                 // This needs an image view per layer in the copied image.
6429                 // Set 0 contains the output buffer.
6430                 // Set 1 contains the input attachments.
6431
6432                 std::ostringstream verificationShader;
6433
6434                 verificationShader
6435                         << "#version 450\n"
6436                         << "\n"
6437                         << "layout (push_constant, std430) uniform PushConstants {\n"
6438                         << "    int width;\n"
6439                         << "    int height;\n"
6440                         << "    int samples;\n"
6441                         << "};\n"
6442                         << "layout (set=0, binding=0) buffer VerificationResults {\n"
6443                         << "    int verificationFlags[];\n"
6444                         << "};\n"
6445                         << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
6446                         ;
6447
6448                 const auto dstLayers = getArraySize(m_params.dst.image);
6449                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6450                 {
6451                         const auto i = layerNdx + 1u;
6452                         verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
6453                 }
6454
6455                 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
6456                 // created with a single sample.
6457                 verificationShader
6458                         << "\n"
6459                         << "void main() {\n"
6460                         << "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
6461                         << "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
6462                         ;
6463
6464                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6465                 {
6466                         const auto i = layerNdx + 1u;
6467                         verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
6468                 }
6469
6470                 std::ostringstream testCondition;
6471                 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6472                 {
6473                         const auto i = layerNdx + 1u;
6474                         testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
6475                 }
6476
6477                 verificationShader
6478                         << "\n"
6479                         << "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
6480                         << "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
6481                         << "\n"
6482                         << "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
6483                         << "    }\n"
6484                         << "}\n"
6485                         ;
6486
6487                 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
6488         }
6489 }
6490
6491 struct BufferOffsetParams
6492 {
6493         static constexpr deUint32 kMaxOffset = 8u;
6494
6495         deUint32 srcOffset;
6496         deUint32 dstOffset;
6497 };
6498
6499 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
6500 {
6501         constexpr deUint8 zero{0};
6502         for (deUint32 i = 0; i < count; ++i)
6503         {
6504                 const auto& val = bufferData[from + i];
6505                 if (val != zero)
6506                 {
6507                         std::ostringstream msg;
6508                         msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
6509                         TCU_FAIL(msg.str());
6510                 }
6511         }
6512 }
6513
6514 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
6515 {
6516         // 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.
6517         constexpr auto kMaxOffset       = BufferOffsetParams::kMaxOffset;
6518         constexpr auto kBlockSize       = kMaxOffset * 2u;
6519         constexpr auto kBufferSize      = kMaxOffset * kBlockSize;
6520
6521         DE_ASSERT(params.srcOffset < kMaxOffset);
6522         DE_ASSERT(params.dstOffset < kMaxOffset);
6523
6524         const auto&     vkd             = ctx.getDeviceInterface();
6525         const auto      device  = ctx.getDevice();
6526         auto&           alloc   = ctx.getDefaultAllocator();
6527         const auto      qIndex  = ctx.getUniversalQueueFamilyIndex();
6528         const auto      queue   = ctx.getUniversalQueue();
6529
6530         const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
6531         const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6532
6533         BufferWithMemory        srcBuffer       (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
6534         BufferWithMemory        dstBuffer       (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
6535         auto&                           srcAlloc        = srcBuffer.getAllocation();
6536         auto&                           dstAlloc        = dstBuffer.getAllocation();
6537
6538         // Zero-out destination buffer.
6539         deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
6540         flushAlloc(vkd, device, dstAlloc);
6541
6542         // Fill source buffer with nonzero bytes.
6543         std::vector<deUint8> srcData;
6544         srcData.reserve(kBufferSize);
6545         for (deUint32 i = 0; i < kBufferSize; ++i)
6546                 srcData.push_back(static_cast<deUint8>(100u + i));
6547         deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
6548         flushAlloc(vkd, device, srcAlloc);
6549
6550         // Copy regions.
6551         std::vector<VkBufferCopy> copies;
6552         copies.reserve(kMaxOffset);
6553         for (deUint32 i = 0; i < kMaxOffset; ++i)
6554         {
6555                 const auto blockStart   = kBlockSize * i;
6556                 const auto copySize             = i + 1u;
6557                 const auto bufferCopy   = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
6558                 copies.push_back(bufferCopy);
6559         }
6560
6561         const auto cmdPool              = makeCommandPool(vkd, device, qIndex);
6562         const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6563         const auto cmdBuffer    = cmdBufferPtr.get();
6564
6565         beginCommandBuffer(vkd, cmdBuffer);
6566         vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
6567         const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6568         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
6569         endCommandBuffer(vkd, cmdBuffer);
6570         submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6571         invalidateAlloc(vkd, device, dstAlloc);
6572
6573         // Verify destination buffer data.
6574         std::vector<deUint8> dstData(kBufferSize);
6575         deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
6576
6577         for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
6578         {
6579                 const auto blockStart   = kBlockSize * blockIdx;
6580                 const auto copySize             = blockIdx + 1u;
6581
6582                 // Verify no data has been written before dstOffset.
6583                 checkZerosAt(dstData, blockStart, params.dstOffset);
6584
6585                 // Verify copied block.
6586                 for (deUint32 i = 0; i < copySize; ++i)
6587                 {
6588                         const auto& dstVal = dstData[blockStart + params.dstOffset + i];
6589                         const auto& srcVal = srcData[blockStart + params.srcOffset + i];
6590                         if (dstVal != srcVal)
6591                         {
6592                                 std::ostringstream msg;
6593                                 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
6594                                 TCU_FAIL(msg.str());
6595                         }
6596                 }
6597
6598                 // Verify no data has been written after copy block.
6599                 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
6600         }
6601
6602         return tcu::TestStatus::pass("Pass");
6603 }
6604
6605 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
6606 {
6607         return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
6608 }
6609
6610 std::string getFormatCaseName (VkFormat format)
6611 {
6612         return de::toLower(de::toString(getFormatStr(format)).substr(10));
6613 }
6614
6615 std::string getImageLayoutCaseName (VkImageLayout layout)
6616 {
6617         switch (layout)
6618         {
6619                 case VK_IMAGE_LAYOUT_GENERAL:
6620                         return "general";
6621                 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
6622                 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
6623                         return "optimal";
6624                 default:
6625                         DE_ASSERT(false);
6626                         return "";
6627         }
6628 }
6629
6630 const deInt32                                   defaultSize                             = 64;
6631 const deInt32                                   defaultHalfSize                 = defaultSize / 2;
6632 const deInt32                                   defaultFourthSize               = defaultSize / 4;
6633 const deInt32                                   defaultSixteenthSize    = defaultSize / 16;
6634 const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
6635 const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
6636 const VkExtent3D                                default1dExtent                 = {defaultSize, 1, 1};
6637 const VkExtent3D                                default3dExtent                 = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
6638
6639 const VkImageSubresourceLayers  defaultSourceLayer              =
6640 {
6641         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
6642         0u,                                                     // deUint32                             mipLevel;
6643         0u,                                                     // deUint32                             baseArrayLayer;
6644         1u,                                                     // deUint32                             layerCount;
6645 };
6646
6647 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
6648 {
6649         tcu::TestContext& testCtx       = group->getTestContext();
6650
6651         {
6652                 TestParams      params;
6653                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6654                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6655                 params.src.image.extent                         = defaultExtent;
6656                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6657                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6658                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6659                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6660                 params.dst.image.extent                         = defaultExtent;
6661                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6662                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6663                 params.allocationKind                           = allocationKind;
6664                 params.extensionUse                                     = extensionUse;
6665
6666                 {
6667                         const VkImageCopy                               testCopy        =
6668                         {
6669                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6670                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
6671                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6672                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6673                                 defaultExtent,          // VkExtent3D                           extent;
6674                         };
6675
6676                         CopyRegion      imageCopy;
6677                         imageCopy.imageCopy     = testCopy;
6678                         params.regions.push_back(imageCopy);
6679                 }
6680
6681                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
6682         }
6683
6684         {
6685                 TestParams      params;
6686                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6687                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6688                 params.src.image.extent                         = defaultExtent;
6689                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6690                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6691                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6692                 params.dst.image.format                         = VK_FORMAT_R32_UINT;
6693                 params.dst.image.extent                         = defaultExtent;
6694                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6695                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6696                 params.allocationKind                           = allocationKind;
6697                 params.extensionUse                                     = extensionUse;
6698
6699                 {
6700                         const VkImageCopy                               testCopy        =
6701                         {
6702                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6703                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
6704                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6705                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6706                                 defaultExtent,          // VkExtent3D                           extent;
6707                         };
6708
6709                         CopyRegion      imageCopy;
6710                         imageCopy.imageCopy = testCopy;
6711                         params.regions.push_back(imageCopy);
6712                 }
6713
6714                 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
6715         }
6716
6717         {
6718                 TestParams      params;
6719                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6720                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6721                 params.src.image.extent                         = defaultExtent;
6722                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6723                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6724                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6725                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
6726                 params.dst.image.extent                         = defaultExtent;
6727                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6728                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6729                 params.allocationKind                           = allocationKind;
6730                 params.extensionUse                                     = extensionUse;
6731
6732                 {
6733                         const VkImageCopy                               testCopy        =
6734                         {
6735                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     srcSubresource;
6736                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6737                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     dstSubresource;
6738                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6739                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6740                         };
6741
6742                         CopyRegion      imageCopy;
6743                         imageCopy.imageCopy = testCopy;
6744                         params.regions.push_back(imageCopy);
6745                 }
6746
6747                 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
6748         }
6749
6750         static const struct
6751         {
6752                 std::string             name;
6753                 vk::VkFormat    format1;
6754                 vk::VkFormat    format2;
6755         } formats [] =
6756         {
6757                 { "diff_format",        vk::VK_FORMAT_R32_UINT,                 vk::VK_FORMAT_R8G8B8A8_UNORM    },
6758                 { "same_format",        vk::VK_FORMAT_R8G8B8A8_UNORM,   vk::VK_FORMAT_R8G8B8A8_UNORM    }
6759         };
6760         static const struct
6761         {
6762                 std::string             name;
6763                 vk::VkBool32    clear;
6764         } clears [] =
6765         {
6766                 { "clear",              VK_TRUE         },
6767                 { "noclear",    VK_FALSE        }
6768         };
6769         static const struct
6770         {
6771                 std::string             name;
6772                 VkExtent3D              extent;
6773         } extents [] =
6774         {
6775                 { "npot",       {65u, 63u, 1u}  },
6776                 { "pot",        {64u, 64u, 1u}  }
6777         };
6778
6779         for (const auto& format : formats)
6780         {
6781                 for (const auto& clear : clears)
6782                 {
6783                         for (const auto& extent : extents)
6784                         {
6785                                 TestParams      params;
6786                                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6787                                 params.src.image.format                         = format.format1;
6788                                 params.src.image.extent                         = extent.extent;
6789                                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6790                                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6791                                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6792                                 params.dst.image.format                         = format.format2;
6793                                 params.dst.image.extent                         = extent.extent;
6794                                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6795                                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6796                                 params.allocationKind                           = allocationKind;
6797                                 params.extensionUse                                     = extensionUse;
6798                                 params.clearDestination                         = clear.clear;
6799
6800                                 {
6801                                         VkImageCopy     testCopy        =
6802                                         {
6803                                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
6804                                                 {34, 34, 0},            // VkOffset3D                           srcOffset;
6805                                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
6806                                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
6807                                                 {31, 29, 1}                     // VkExtent3D                           extent;
6808                                         };
6809
6810                                         if (extent.name == "pot")
6811                                         {
6812                                                 testCopy.srcOffset      = { 16, 16, 0 };
6813                                                 testCopy.extent         = { 32, 32, 1 };
6814                                         }
6815
6816                                         CopyRegion      imageCopy;
6817                                         imageCopy.imageCopy = testCopy;
6818                                         params.regions.push_back(imageCopy);
6819                                 }
6820
6821                                 // Example test case name: "partial_image_npot_diff_format_clear"
6822                                 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
6823
6824                                 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
6825                         }
6826                 }
6827         }
6828
6829         {
6830                 TestParams      params;
6831                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6832                 params.src.image.format                         = VK_FORMAT_D32_SFLOAT;
6833                 params.src.image.extent                         = defaultExtent;
6834                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6835                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6836                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6837                 params.dst.image.format                         = VK_FORMAT_D32_SFLOAT;
6838                 params.dst.image.extent                         = defaultExtent;
6839                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6840                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6841                 params.allocationKind                           = allocationKind;
6842                 params.extensionUse                                     = extensionUse;
6843
6844                 {
6845                         const VkImageSubresourceLayers  sourceLayer =
6846                         {
6847                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
6848                                 0u,                                                     // deUint32                             mipLevel;
6849                                 0u,                                                     // deUint32                             baseArrayLayer;
6850                                 1u                                                      // deUint32                             layerCount;
6851                         };
6852                         const VkImageCopy                               testCopy        =
6853                         {
6854                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
6855                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6856                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
6857                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6858                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6859                         };
6860
6861                         CopyRegion      imageCopy;
6862                         imageCopy.imageCopy = testCopy;
6863                         params.regions.push_back(imageCopy);
6864                 }
6865
6866                 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
6867         }
6868
6869         {
6870                 TestParams      params;
6871                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
6872                 params.src.image.format                         = VK_FORMAT_S8_UINT;
6873                 params.src.image.extent                         = defaultExtent;
6874                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6875                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6876                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
6877                 params.dst.image.format                         = VK_FORMAT_S8_UINT;
6878                 params.dst.image.extent                         = defaultExtent;
6879                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
6880                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6881                 params.allocationKind                           = allocationKind;
6882                 params.extensionUse                                     = extensionUse;
6883
6884                 {
6885                         const VkImageSubresourceLayers  sourceLayer =
6886                         {
6887                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
6888                                 0u,                                                             // deUint32                             mipLevel;
6889                                 0u,                                                             // deUint32                             baseArrayLayer;
6890                                 1u                                                              // deUint32                             layerCount;
6891                         };
6892                         const VkImageCopy                               testCopy        =
6893                         {
6894                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
6895                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
6896                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
6897                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
6898                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
6899                         };
6900
6901                         CopyRegion      imageCopy;
6902                         imageCopy.imageCopy = testCopy;
6903                         params.regions.push_back(imageCopy);
6904                 }
6905
6906                 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
6907         }
6908 }
6909
6910 struct CopyColorTestParams
6911 {
6912         TestParams              params;
6913         const VkFormat* compatibleFormats;
6914 };
6915
6916 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
6917 {
6918         const VkImageLayout copySrcLayouts[]            =
6919         {
6920                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6921                 VK_IMAGE_LAYOUT_GENERAL
6922         };
6923         const VkImageLayout copyDstLayouts[]            =
6924         {
6925                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6926                 VK_IMAGE_LAYOUT_GENERAL
6927         };
6928
6929         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
6930         {
6931                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
6932
6933                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
6934                 {
6935                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
6936
6937                         const std::string testName      = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
6938                                                                                   getImageLayoutCaseName(params.dst.image.operationLayout);
6939                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
6940                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
6941                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
6942                 }
6943         }
6944 }
6945
6946 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
6947 {
6948         bool result = true;
6949
6950         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
6951         {
6952                 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
6953
6954                 result =
6955                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
6956                         de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
6957         }
6958
6959         return result;
6960 }
6961
6962 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
6963 {
6964         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
6965         const VkFormat  srcFormatOnly[2]        = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
6966         const VkFormat* formatList                      = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
6967
6968         for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
6969         {
6970                 testParams.params.dst.image.format = formatList[dstFormatIndex];
6971
6972                 const VkFormat          srcFormat       = testParams.params.src.image.format;
6973                 const VkFormat          dstFormat       = testParams.params.dst.image.format;
6974
6975                 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
6976                         continue;
6977
6978                 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
6979                         continue;
6980
6981                 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
6982                         if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
6983                                 continue;
6984
6985                 const std::string       description     = "Copy to destination format " + getFormatCaseName(dstFormat);
6986                 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
6987         }
6988 }
6989
6990 const VkFormat  compatibleFormats8Bit[]         =
6991 {
6992         VK_FORMAT_R4G4_UNORM_PACK8,
6993         VK_FORMAT_R8_UNORM,
6994         VK_FORMAT_R8_SNORM,
6995         VK_FORMAT_R8_USCALED,
6996         VK_FORMAT_R8_SSCALED,
6997         VK_FORMAT_R8_UINT,
6998         VK_FORMAT_R8_SINT,
6999         VK_FORMAT_R8_SRGB,
7000
7001         VK_FORMAT_UNDEFINED
7002 };
7003 const VkFormat  compatibleFormats16Bit[]        =
7004 {
7005         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7006         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
7007         VK_FORMAT_R5G6B5_UNORM_PACK16,
7008         VK_FORMAT_B5G6R5_UNORM_PACK16,
7009         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
7010         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
7011         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
7012         VK_FORMAT_R8G8_UNORM,
7013         VK_FORMAT_R8G8_SNORM,
7014         VK_FORMAT_R8G8_USCALED,
7015         VK_FORMAT_R8G8_SSCALED,
7016         VK_FORMAT_R8G8_UINT,
7017         VK_FORMAT_R8G8_SINT,
7018         VK_FORMAT_R8G8_SRGB,
7019         VK_FORMAT_R16_UNORM,
7020         VK_FORMAT_R16_SNORM,
7021         VK_FORMAT_R16_USCALED,
7022         VK_FORMAT_R16_SSCALED,
7023         VK_FORMAT_R16_UINT,
7024         VK_FORMAT_R16_SINT,
7025         VK_FORMAT_R16_SFLOAT,
7026         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
7027         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
7028
7029         VK_FORMAT_UNDEFINED
7030 };
7031 const VkFormat  compatibleFormats24Bit[]        =
7032 {
7033         VK_FORMAT_R8G8B8_UNORM,
7034         VK_FORMAT_R8G8B8_SNORM,
7035         VK_FORMAT_R8G8B8_USCALED,
7036         VK_FORMAT_R8G8B8_SSCALED,
7037         VK_FORMAT_R8G8B8_UINT,
7038         VK_FORMAT_R8G8B8_SINT,
7039         VK_FORMAT_R8G8B8_SRGB,
7040         VK_FORMAT_B8G8R8_UNORM,
7041         VK_FORMAT_B8G8R8_SNORM,
7042         VK_FORMAT_B8G8R8_USCALED,
7043         VK_FORMAT_B8G8R8_SSCALED,
7044         VK_FORMAT_B8G8R8_UINT,
7045         VK_FORMAT_B8G8R8_SINT,
7046         VK_FORMAT_B8G8R8_SRGB,
7047
7048         VK_FORMAT_UNDEFINED
7049 };
7050 const VkFormat  compatibleFormats32Bit[]        =
7051 {
7052         VK_FORMAT_R8G8B8A8_UNORM,
7053         VK_FORMAT_R8G8B8A8_SNORM,
7054         VK_FORMAT_R8G8B8A8_USCALED,
7055         VK_FORMAT_R8G8B8A8_SSCALED,
7056         VK_FORMAT_R8G8B8A8_UINT,
7057         VK_FORMAT_R8G8B8A8_SINT,
7058         VK_FORMAT_R8G8B8A8_SRGB,
7059         VK_FORMAT_B8G8R8A8_UNORM,
7060         VK_FORMAT_B8G8R8A8_SNORM,
7061         VK_FORMAT_B8G8R8A8_USCALED,
7062         VK_FORMAT_B8G8R8A8_SSCALED,
7063         VK_FORMAT_B8G8R8A8_UINT,
7064         VK_FORMAT_B8G8R8A8_SINT,
7065         VK_FORMAT_B8G8R8A8_SRGB,
7066         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
7067         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
7068         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
7069         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
7070         VK_FORMAT_A8B8G8R8_UINT_PACK32,
7071         VK_FORMAT_A8B8G8R8_SINT_PACK32,
7072         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
7073         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
7074         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
7075         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
7076         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
7077         VK_FORMAT_A2R10G10B10_UINT_PACK32,
7078         VK_FORMAT_A2R10G10B10_SINT_PACK32,
7079         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
7080         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
7081         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
7082         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
7083         VK_FORMAT_A2B10G10R10_UINT_PACK32,
7084         VK_FORMAT_A2B10G10R10_SINT_PACK32,
7085         VK_FORMAT_R16G16_UNORM,
7086         VK_FORMAT_R16G16_SNORM,
7087         VK_FORMAT_R16G16_USCALED,
7088         VK_FORMAT_R16G16_SSCALED,
7089         VK_FORMAT_R16G16_UINT,
7090         VK_FORMAT_R16G16_SINT,
7091         VK_FORMAT_R16G16_SFLOAT,
7092         VK_FORMAT_R32_UINT,
7093         VK_FORMAT_R32_SINT,
7094         VK_FORMAT_R32_SFLOAT,
7095
7096         VK_FORMAT_UNDEFINED
7097 };
7098 const VkFormat  compatibleFormats48Bit[]        =
7099 {
7100         VK_FORMAT_R16G16B16_UNORM,
7101         VK_FORMAT_R16G16B16_SNORM,
7102         VK_FORMAT_R16G16B16_USCALED,
7103         VK_FORMAT_R16G16B16_SSCALED,
7104         VK_FORMAT_R16G16B16_UINT,
7105         VK_FORMAT_R16G16B16_SINT,
7106         VK_FORMAT_R16G16B16_SFLOAT,
7107
7108         VK_FORMAT_UNDEFINED
7109 };
7110 const VkFormat  compatibleFormats64Bit[]        =
7111 {
7112         VK_FORMAT_R16G16B16A16_UNORM,
7113         VK_FORMAT_R16G16B16A16_SNORM,
7114         VK_FORMAT_R16G16B16A16_USCALED,
7115         VK_FORMAT_R16G16B16A16_SSCALED,
7116         VK_FORMAT_R16G16B16A16_UINT,
7117         VK_FORMAT_R16G16B16A16_SINT,
7118         VK_FORMAT_R16G16B16A16_SFLOAT,
7119         VK_FORMAT_R32G32_UINT,
7120         VK_FORMAT_R32G32_SINT,
7121         VK_FORMAT_R32G32_SFLOAT,
7122         VK_FORMAT_R64_UINT,
7123         VK_FORMAT_R64_SINT,
7124         VK_FORMAT_R64_SFLOAT,
7125
7126         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
7127         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
7128         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
7129         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
7130         VK_FORMAT_BC4_UNORM_BLOCK,
7131         VK_FORMAT_BC4_SNORM_BLOCK,
7132
7133         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
7134         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
7135         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
7136         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
7137
7138         VK_FORMAT_EAC_R11_UNORM_BLOCK,
7139         VK_FORMAT_EAC_R11_SNORM_BLOCK,
7140
7141         VK_FORMAT_UNDEFINED
7142 };
7143 const VkFormat  compatibleFormats96Bit[]        =
7144 {
7145         VK_FORMAT_R32G32B32_UINT,
7146         VK_FORMAT_R32G32B32_SINT,
7147         VK_FORMAT_R32G32B32_SFLOAT,
7148
7149         VK_FORMAT_UNDEFINED
7150 };
7151 const VkFormat  compatibleFormats128Bit[]       =
7152 {
7153         VK_FORMAT_R32G32B32A32_UINT,
7154         VK_FORMAT_R32G32B32A32_SINT,
7155         VK_FORMAT_R32G32B32A32_SFLOAT,
7156         VK_FORMAT_R64G64_UINT,
7157         VK_FORMAT_R64G64_SINT,
7158         VK_FORMAT_R64G64_SFLOAT,
7159
7160         VK_FORMAT_BC2_UNORM_BLOCK,
7161         VK_FORMAT_BC2_SRGB_BLOCK,
7162         VK_FORMAT_BC3_UNORM_BLOCK,
7163         VK_FORMAT_BC3_SRGB_BLOCK,
7164         VK_FORMAT_BC5_UNORM_BLOCK,
7165         VK_FORMAT_BC5_SNORM_BLOCK,
7166         VK_FORMAT_BC6H_UFLOAT_BLOCK,
7167         VK_FORMAT_BC6H_SFLOAT_BLOCK,
7168         VK_FORMAT_BC7_UNORM_BLOCK,
7169         VK_FORMAT_BC7_SRGB_BLOCK,
7170
7171         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
7172         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
7173
7174         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
7175         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
7176
7177         VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
7178         VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
7179         VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
7180         VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
7181         VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
7182         VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
7183         VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
7184         VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
7185         VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
7186         VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
7187         VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
7188         VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
7189         VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
7190         VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
7191         VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
7192         VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
7193         VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
7194         VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
7195         VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
7196         VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
7197         VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
7198         VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
7199         VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
7200         VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
7201         VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
7202         VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
7203         VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
7204         VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
7205
7206         VK_FORMAT_UNDEFINED
7207 };
7208 const VkFormat  compatibleFormats192Bit[]       =
7209 {
7210         VK_FORMAT_R64G64B64_UINT,
7211         VK_FORMAT_R64G64B64_SINT,
7212         VK_FORMAT_R64G64B64_SFLOAT,
7213
7214         VK_FORMAT_UNDEFINED
7215 };
7216 const VkFormat  compatibleFormats256Bit[]       =
7217 {
7218         VK_FORMAT_R64G64B64A64_UINT,
7219         VK_FORMAT_R64G64B64A64_SINT,
7220         VK_FORMAT_R64G64B64A64_SFLOAT,
7221
7222         VK_FORMAT_UNDEFINED
7223 };
7224
7225 const VkFormat* colorImageFormatsToTest[]       =
7226 {
7227         compatibleFormats8Bit,
7228         compatibleFormats16Bit,
7229         compatibleFormats24Bit,
7230         compatibleFormats32Bit,
7231         compatibleFormats48Bit,
7232         compatibleFormats64Bit,
7233         compatibleFormats96Bit,
7234         compatibleFormats128Bit,
7235         compatibleFormats192Bit,
7236         compatibleFormats256Bit
7237 };
7238
7239 const VkFormat  dedicatedAllocationImageToImageFormatsToTest[]  =
7240 {
7241         // From compatibleFormats8Bit
7242         VK_FORMAT_R4G4_UNORM_PACK8,
7243         VK_FORMAT_R8_SRGB,
7244
7245         // From compatibleFormats16Bit
7246         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7247         VK_FORMAT_R16_SFLOAT,
7248
7249         // From compatibleFormats24Bit
7250         VK_FORMAT_R8G8B8_UNORM,
7251         VK_FORMAT_B8G8R8_SRGB,
7252
7253         // From compatibleFormats32Bit
7254         VK_FORMAT_R8G8B8A8_UNORM,
7255         VK_FORMAT_R32_SFLOAT,
7256
7257         // From compatibleFormats48Bit
7258         VK_FORMAT_R16G16B16_UNORM,
7259         VK_FORMAT_R16G16B16_SFLOAT,
7260
7261         // From compatibleFormats64Bit
7262         VK_FORMAT_R16G16B16A16_UNORM,
7263         VK_FORMAT_R64_SFLOAT,
7264
7265         // From compatibleFormats96Bit
7266         VK_FORMAT_R32G32B32_UINT,
7267         VK_FORMAT_R32G32B32_SFLOAT,
7268
7269         // From compatibleFormats128Bit
7270         VK_FORMAT_R32G32B32A32_UINT,
7271         VK_FORMAT_R64G64_SFLOAT,
7272
7273         // From compatibleFormats192Bit
7274         VK_FORMAT_R64G64B64_UINT,
7275         VK_FORMAT_R64G64B64_SFLOAT,
7276
7277         // From compatibleFormats256Bit
7278         VK_FORMAT_R64G64B64A64_UINT,
7279         VK_FORMAT_R64G64B64A64_SFLOAT,
7280 };
7281
7282 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7283 {
7284         if (allocationKind == ALLOCATION_KIND_DEDICATED)
7285         {
7286                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7287                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
7288                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7289         }
7290
7291         // 2D tests.
7292         {
7293                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7294
7295                 TestParams      params;
7296                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
7297                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
7298                 params.src.image.extent         = defaultExtent;
7299                 params.dst.image.extent         = defaultExtent;
7300                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7301                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7302                 params.allocationKind           = allocationKind;
7303                 params.extensionUse                     = extensionUse;
7304
7305                 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7306                 {
7307                         const VkImageCopy                               testCopy =
7308                         {
7309                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
7310                                 {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
7311                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
7312                                 {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
7313                                 {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
7314                         };
7315
7316                         CopyRegion      imageCopy;
7317                         imageCopy.imageCopy = testCopy;
7318
7319                         params.regions.push_back(imageCopy);
7320                 }
7321
7322                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7323                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7324                 {
7325                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7326                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7327                         {
7328                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7329                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7330                                         continue;
7331
7332                                 CopyColorTestParams     testParams;
7333                                 testParams.params                               = params;
7334                                 testParams.compatibleFormats    = compatibleFormats;
7335
7336                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7337                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7338                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7339                         }
7340                 }
7341
7342                 group->addChild(subGroup.release());
7343         }
7344
7345         // 1D tests.
7346         {
7347                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7348
7349                 TestParams      params;
7350                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
7351                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
7352                 params.src.image.extent         = default1dExtent;
7353                 params.dst.image.extent         = default1dExtent;
7354                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7355                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7356                 params.allocationKind           = allocationKind;
7357                 params.extensionUse                     = extensionUse;
7358
7359                 for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7360                 {
7361                         const VkImageCopy                               testCopy =
7362                         {
7363                                 defaultSourceLayer,                     // VkImageSubresourceLayers     srcSubresource;
7364                                 {0, 0, 0},                                      // VkOffset3D                           srcOffset;
7365                                 defaultSourceLayer,                     // VkImageSubresourceLayers     dstSubresource;
7366                                 {i, 0, 0},                                      // VkOffset3D                           dstOffset;
7367                                 {defaultFourthSize, 1, 1},      // VkExtent3D                           extent;
7368                         };
7369
7370                         CopyRegion      imageCopy;
7371                         imageCopy.imageCopy = testCopy;
7372
7373                         params.regions.push_back(imageCopy);
7374                 }
7375
7376                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7377                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7378                 {
7379                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7380                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7381                         {
7382                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7383                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7384                                         continue;
7385
7386                                 CopyColorTestParams     testParams;
7387                                 testParams.params                               = params;
7388                                 testParams.compatibleFormats    = nullptr;
7389
7390                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7391                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7392                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7393                         }
7394                 }
7395
7396                 group->addChild(subGroup.release());
7397         }
7398
7399         // 3D tests. Note we use smaller dimensions here for performance reasons.
7400         {
7401                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7402
7403                 TestParams      params;
7404                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
7405                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
7406                 params.src.image.extent         = default3dExtent;
7407                 params.dst.image.extent         = default3dExtent;
7408                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7409                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
7410                 params.allocationKind           = allocationKind;
7411                 params.extensionUse                     = extensionUse;
7412
7413                 for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7414                 {
7415                         const VkImageCopy                               testCopy =
7416                         {
7417                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     srcSubresource;
7418                                 {0, 0, 0},                                                                                                                      // VkOffset3D                           srcOffset;
7419                                 defaultSourceLayer,                                                                                                     // VkImageSubresourceLayers     dstSubresource;
7420                                 {i, defaultFourthSize - i - defaultSixteenthSize, i},                           // VkOffset3D                           dstOffset;
7421                                 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},     // VkExtent3D                           extent;
7422                         };
7423
7424                         CopyRegion      imageCopy;
7425                         imageCopy.imageCopy = testCopy;
7426
7427                         params.regions.push_back(imageCopy);
7428                 }
7429
7430                 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7431                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7432                 {
7433                         const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
7434                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7435                         {
7436                                 params.src.image.format = compatibleFormats[srcFormatIndex];
7437                                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7438                                         continue;
7439
7440                                 CopyColorTestParams     testParams;
7441                                 testParams.params                               = params;
7442                                 testParams.compatibleFormats    = nullptr;
7443
7444                                 const std::string testName              = getFormatCaseName(params.src.image.format);
7445                                 const std::string description   = "Copy from source format " + getFormatCaseName(params.src.image.format);
7446                                 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7447                         }
7448                 }
7449
7450                 group->addChild(subGroup.release());
7451         }
7452 }
7453
7454 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7455 {
7456         tcu::TestContext&               testCtx                         = group->getTestContext();
7457
7458         const VkFormat                  testFormats[][2]        =
7459         {
7460                 // From compatibleFormats8Bit
7461                 {
7462                         VK_FORMAT_R4G4_UNORM_PACK8,
7463                         VK_FORMAT_R8_SRGB
7464                 },
7465                 // From compatibleFormats16Bit
7466                 {
7467                         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7468                         VK_FORMAT_R16_SFLOAT,
7469                 },
7470                 // From compatibleFormats24Bit
7471                 {
7472                         VK_FORMAT_R8G8B8_UNORM,
7473                         VK_FORMAT_B8G8R8_SRGB
7474                 },
7475                 // From compatibleFormats32Bit
7476                 {
7477                         VK_FORMAT_R8G8B8A8_UNORM,
7478                         VK_FORMAT_R32_SFLOAT
7479                 },
7480                 // From compatibleFormats48Bit
7481                 {
7482                         VK_FORMAT_R16G16B16_UNORM,
7483                         VK_FORMAT_R16G16B16_SFLOAT
7484                 },
7485                 // From compatibleFormats64Bit
7486                 {
7487                         VK_FORMAT_R16G16B16A16_UNORM,
7488                         VK_FORMAT_R64_SFLOAT
7489                 },
7490                 // From compatibleFormats96Bit
7491                 {
7492                         VK_FORMAT_R32G32B32_UINT,
7493                         VK_FORMAT_R32G32B32_SFLOAT
7494                 },
7495                 // From compatibleFormats128Bit
7496                 {
7497                         VK_FORMAT_R32G32B32A32_UINT,
7498                         VK_FORMAT_R64G64_SFLOAT
7499                 },
7500                 // From compatibleFormats192Bit
7501                 {
7502                         VK_FORMAT_R64G64B64_UINT,
7503                         VK_FORMAT_R64G64B64_SFLOAT,
7504                 },
7505                 // From compatibleFormats256Bit
7506                 {
7507                         VK_FORMAT_R64G64B64A64_UINT,
7508                         VK_FORMAT_R64G64B64A64_SFLOAT
7509                 }
7510         };
7511
7512         const tcu::UVec2                imageDimensions[]       =
7513         {
7514                 // large pot x small pot
7515                 tcu::UVec2(4096,        4u),
7516                 tcu::UVec2(8192,        4u),
7517                 tcu::UVec2(16384,       4u),
7518                 tcu::UVec2(32768,       4u),
7519
7520                 // large pot x small npot
7521                 tcu::UVec2(4096,        6u),
7522                 tcu::UVec2(8192,        6u),
7523                 tcu::UVec2(16384,       6u),
7524                 tcu::UVec2(32768,       6u),
7525
7526                 // small pot x large pot
7527                 tcu::UVec2(4u, 4096),
7528                 tcu::UVec2(4u, 8192),
7529                 tcu::UVec2(4u, 16384),
7530                 tcu::UVec2(4u, 32768),
7531
7532                 // small npot x large pot
7533                 tcu::UVec2(6u, 4096),
7534                 tcu::UVec2(6u, 8192),
7535                 tcu::UVec2(6u, 16384),
7536                 tcu::UVec2(6u, 32768)
7537         };
7538
7539         const VkImageLayout             copySrcLayouts[]        =
7540         {
7541                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7542                 VK_IMAGE_LAYOUT_GENERAL
7543         };
7544
7545         const VkImageLayout             copyDstLayouts[]        =
7546         {
7547                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7548                 VK_IMAGE_LAYOUT_GENERAL
7549         };
7550
7551         if (allocationKind == ALLOCATION_KIND_DEDICATED)
7552         {
7553                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7554                         dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7555         }
7556
7557         // Image dimensions
7558         for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
7559         {
7560                 CopyRegion                              copyRegion;
7561                 CopyColorTestParams             testParams;
7562
7563                 const VkExtent3D                extent                  = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
7564
7565                 const VkImageCopy               testCopy                =
7566                 {
7567                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
7568                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
7569                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
7570                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
7571                         extent,                         // VkExtent3D                           extent;
7572                 };
7573
7574                 testParams.params.src.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
7575                 testParams.params.src.image.imageType   = VK_IMAGE_TYPE_2D;
7576                 testParams.params.src.image.extent              = extent;
7577
7578                 testParams.params.dst.image.tiling              = VK_IMAGE_TILING_OPTIMAL;
7579                 testParams.params.dst.image.imageType   = VK_IMAGE_TYPE_2D;
7580                 testParams.params.dst.image.extent              = extent;
7581
7582                 copyRegion.imageCopy                                    = testCopy;
7583                 testParams.params.allocationKind                = allocationKind;
7584                 testParams.params.extensionUse                  = extensionUse;
7585
7586                 testParams.params.regions.push_back(copyRegion);
7587
7588                 const std::string       dimensionStr            = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
7589                                                                                                   + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
7590                 tcu::TestCaseGroup*     imageSizeGroup          = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
7591
7592                 // Compatible formats for copying
7593                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7594                 {
7595                         const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
7596
7597                         testParams.compatibleFormats = compatibleFormats;
7598
7599                         // Source image format
7600                         for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
7601                         {
7602                                 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
7603
7604                                 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
7605                                         continue;
7606
7607                                 const std::string       srcDescription  = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
7608                                 tcu::TestCaseGroup*     srcFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
7609
7610                                 // Destination image format
7611                                 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
7612                                 {
7613                                         testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
7614
7615                                         if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
7616                                                 continue;
7617
7618                                         if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
7619                                                 continue;
7620
7621                                         if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
7622                                         {
7623                                                 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
7624                                                         || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
7625                                                         continue;
7626                                         }
7627
7628                                         const std::string       dstDescription  = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
7629                                         tcu::TestCaseGroup*     dstFormatGroup  = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
7630
7631                                         // Source/destionation image layouts
7632                                         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
7633                                         {
7634                                                 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7635
7636                                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
7637                                                 {
7638                                                         testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7639
7640                                                         const std::string       testName        = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
7641                                                         const std::string       description     = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
7642                                                         const TestParams        params          = testParams.params;
7643
7644                                                         dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
7645                                                 }
7646                                         }
7647
7648                                         srcFormatGroup->addChild(dstFormatGroup);
7649                                 }
7650
7651                                 imageSizeGroup->addChild(srcFormatGroup);
7652                         }
7653                 }
7654
7655                 group->addChild(imageSizeGroup);
7656         }
7657 }
7658
7659 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
7660 {
7661         const VkImageLayout copySrcLayouts[]            =
7662         {
7663                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7664                 VK_IMAGE_LAYOUT_GENERAL
7665         };
7666         const VkImageLayout copyDstLayouts[]            =
7667         {
7668                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7669                 VK_IMAGE_LAYOUT_GENERAL
7670         };
7671
7672         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
7673         {
7674                 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7675                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
7676                 {
7677                         params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7678
7679                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
7680                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
7681                         const std::string description   = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
7682                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
7683                         group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
7684                 }
7685         }
7686 }
7687
7688 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7689 {
7690         const VkFormat  depthAndStencilFormats[]        =
7691         {
7692                 VK_FORMAT_D16_UNORM,
7693                 VK_FORMAT_X8_D24_UNORM_PACK32,
7694                 VK_FORMAT_D32_SFLOAT,
7695                 VK_FORMAT_S8_UINT,
7696                 VK_FORMAT_D16_UNORM_S8_UINT,
7697                 VK_FORMAT_D24_UNORM_S8_UINT,
7698                 VK_FORMAT_D32_SFLOAT_S8_UINT,
7699         };
7700
7701         // 2D tests.
7702         {
7703                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7704
7705                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7706                 {
7707                         TestParams      params;
7708                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
7709                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
7710                         params.src.image.extent                         = defaultExtent;
7711                         params.dst.image.extent                         = defaultExtent;
7712                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7713                         params.dst.image.format                         = params.src.image.format;
7714                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7715                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7716                         params.allocationKind                           = allocationKind;
7717                         params.extensionUse                                     = extensionUse;
7718                         params.separateDepthStencilLayouts      = DE_FALSE;
7719
7720                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7721                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7722
7723                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7724                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7725                         const VkImageSubresourceLayers          defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7726
7727                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7728                         {
7729                                 CopyRegion                      copyRegion;
7730                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7731                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
7732                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
7733
7734                                 if (hasDepth)
7735                                 {
7736                                         const VkImageCopy                               testCopy        =
7737                                         {
7738                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7739                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7740                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7741                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7742                                                 extent,                                         // VkExtent3D                           extent;
7743                                         };
7744
7745                                         copyRegion.imageCopy    = testCopy;
7746                                         params.regions.push_back(copyRegion);
7747                                 }
7748                                 if (hasStencil)
7749                                 {
7750                                         const VkImageCopy                               testCopy        =
7751                                         {
7752                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7753                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7754                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7755                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7756                                                 extent,                                         // VkExtent3D                           extent;
7757                                         };
7758
7759                                         copyRegion.imageCopy    = testCopy;
7760                                         params.regions.push_back(copyRegion);
7761                                 }
7762                         }
7763
7764                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7765                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7766                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7767
7768                         if (hasDepth && hasStencil)
7769                         {
7770                                 params.separateDepthStencilLayouts      = DE_TRUE;
7771                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7772                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7773                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7774
7775                                 // DS Image copy
7776                                 {
7777                                         params.separateDepthStencilLayouts      = DE_FALSE;
7778                                         // Clear previous vkImageCopy elements
7779                                         params.regions.clear();
7780
7781                                         for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7782                                         {
7783                                                 CopyRegion                      copyRegion;
7784                                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7785                                                 const VkOffset3D        dstOffset       = {i, defaultSize - i - defaultFourthSize, 0};
7786                                                 const VkExtent3D        extent          = {defaultFourthSize, defaultFourthSize, 1};
7787
7788                                                 const VkImageCopy                               testCopy        =
7789                                                 {
7790                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     srcSubresource;
7791                                                         srcOffset,                                      // VkOffset3D                           srcOffset;
7792                                                         defaultDSSourceLayer,           // VkImageSubresourceLayers     dstSubresource;
7793                                                         dstOffset,                                      // VkOffset3D                           dstOffset;
7794                                                         extent,                                         // VkExtent3D                           extent;
7795                                                 };
7796
7797                                                 copyRegion.imageCopy    = testCopy;
7798                                                 params.regions.push_back(copyRegion);
7799                                         }
7800
7801                                         const std::string testName3             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
7802                                         const std::string description3  = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7803                                         addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7804                                 }
7805                         }
7806                 }
7807
7808                 group->addChild(subGroup.release());
7809         }
7810
7811         // 1D tests.
7812         {
7813                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7814
7815                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7816                 {
7817                         TestParams      params;
7818                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
7819                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
7820                         params.src.image.extent                         = default1dExtent;
7821                         params.dst.image.extent                         = default1dExtent;
7822                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7823                         params.dst.image.format                         = params.src.image.format;
7824                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7825                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7826                         params.allocationKind                           = allocationKind;
7827                         params.extensionUse                                     = extensionUse;
7828
7829                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7830                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7831
7832                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7833                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7834
7835                         for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7836                         {
7837                                 CopyRegion                      copyRegion;
7838                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7839                                 const VkOffset3D        dstOffset       = {i, 0, 0};
7840                                 const VkExtent3D        extent          = {defaultFourthSize, 1, 1};
7841
7842                                 if (hasDepth)
7843                                 {
7844                                         const VkImageCopy                               testCopy        =
7845                                         {
7846                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7847                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7848                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7849                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7850                                                 extent,                                         // VkExtent3D                           extent;
7851                                         };
7852
7853                                         copyRegion.imageCopy    = testCopy;
7854                                         params.regions.push_back(copyRegion);
7855                                 }
7856                                 if (hasStencil)
7857                                 {
7858                                         const VkImageCopy                               testCopy        =
7859                                         {
7860                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7861                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7862                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7863                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7864                                                 extent,                                         // VkExtent3D                           extent;
7865                                         };
7866
7867                                         copyRegion.imageCopy    = testCopy;
7868                                         params.regions.push_back(copyRegion);
7869                                 }
7870                         }
7871
7872                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7873                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7874                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7875
7876                         if (hasDepth && hasStencil)
7877                         {
7878                                 params.separateDepthStencilLayouts      = DE_TRUE;
7879                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7880                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7881                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7882                         }
7883                 }
7884
7885                 group->addChild(subGroup.release());
7886         }
7887
7888         // 3D tests. Note we use smaller dimensions here for performance reasons.
7889         {
7890                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7891
7892                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
7893                 {
7894                         TestParams      params;
7895                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
7896                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
7897                         params.src.image.extent                         = default3dExtent;
7898                         params.dst.image.extent                         = default3dExtent;
7899                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
7900                         params.dst.image.format                         = params.src.image.format;
7901                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7902                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
7903                         params.allocationKind                           = allocationKind;
7904                         params.extensionUse                                     = extensionUse;
7905
7906                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
7907                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
7908
7909                         const VkImageSubresourceLayers          defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
7910                         const VkImageSubresourceLayers          defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
7911
7912                         for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7913                         {
7914                                 CopyRegion                      copyRegion;
7915                                 const VkOffset3D        srcOffset       = {0, 0, 0};
7916                                 const VkOffset3D        dstOffset       = {i, defaultFourthSize - i - defaultSixteenthSize, i};
7917                                 const VkExtent3D        extent          = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
7918
7919                                 if (hasDepth)
7920                                 {
7921                                         const VkImageCopy                               testCopy        =
7922                                         {
7923                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     srcSubresource;
7924                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7925                                                 defaultDepthSourceLayer,        // VkImageSubresourceLayers     dstSubresource;
7926                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7927                                                 extent,                                         // VkExtent3D                           extent;
7928                                         };
7929
7930                                         copyRegion.imageCopy    = testCopy;
7931                                         params.regions.push_back(copyRegion);
7932                                 }
7933                                 if (hasStencil)
7934                                 {
7935                                         const VkImageCopy                               testCopy        =
7936                                         {
7937                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     srcSubresource;
7938                                                 srcOffset,                                      // VkOffset3D                           srcOffset;
7939                                                 defaultStencilSourceLayer,      // VkImageSubresourceLayers     dstSubresource;
7940                                                 dstOffset,                                      // VkOffset3D                           dstOffset;
7941                                                 extent,                                         // VkExtent3D                           extent;
7942                                         };
7943
7944                                         copyRegion.imageCopy    = testCopy;
7945                                         params.regions.push_back(copyRegion);
7946                                 }
7947                         }
7948
7949                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
7950                         const std::string description   = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
7951                         addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7952
7953                         if (hasDepth && hasStencil)
7954                         {
7955                                 params.separateDepthStencilLayouts      = DE_TRUE;
7956                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
7957                                 const std::string description2  = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
7958                                 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
7959                         }
7960                 }
7961
7962                 group->addChild(subGroup.release());
7963         }
7964 }
7965
7966 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7967 {
7968         addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
7969         addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
7970 }
7971
7972 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7973 {
7974         tcu::TestContext& testCtx       = group->getTestContext();
7975
7976         {
7977                 TestParams      params3DTo2D;
7978                 const deUint32  slicesLayers                    = 16u;
7979                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
7980                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7981                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
7982                 params3DTo2D.src.image.extent.depth             = slicesLayers;
7983                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7984                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7985                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
7986                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
7987                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
7988                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
7989                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
7990                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7991                 params3DTo2D.allocationKind                             = allocationKind;
7992                 params3DTo2D.extensionUse                               = extensionUse;
7993
7994                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
7995                 {
7996                         const VkImageSubresourceLayers  sourceLayer     =
7997                         {
7998                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
7999                                 0u,                                                     // deUint32                             mipLevel;
8000                                 0u,                                                     // deUint32                             baseArrayLayer;
8001                                 1u                                                      // deUint32                             layerCount;
8002                         };
8003
8004                         const VkImageSubresourceLayers  destinationLayer        =
8005                         {
8006                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8007                                 0u,                                                     // deUint32                             mipLevel;
8008                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8009                                 1u                                                      // deUint32                             layerCount;
8010                         };
8011
8012                         const VkImageCopy                               testCopy        =
8013                         {
8014                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
8015                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           srcOffset;
8016                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
8017                                 {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
8018                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
8019                         };
8020
8021                         CopyRegion      imageCopy;
8022                         imageCopy.imageCopy     = testCopy;
8023
8024                         params3DTo2D.regions.push_back(imageCopy);
8025                 }
8026                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
8027         }
8028
8029         {
8030                 TestParams      params2DTo3D;
8031                 const deUint32  slicesLayers                    = 16u;
8032                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8033                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8034                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8035                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8036                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8037                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8038                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8039                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8040                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8041                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8042                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8043                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8044                 params2DTo3D.allocationKind                             = allocationKind;
8045                 params2DTo3D.extensionUse                               = extensionUse;
8046
8047                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8048                 {
8049                         const VkImageSubresourceLayers  sourceLayer     =
8050                         {
8051                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8052                                 0u,                                                     // deUint32                             mipLevel;
8053                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8054                                 1u                                                      // deUint32                             layerCount;
8055                         };
8056
8057                         const VkImageSubresourceLayers  destinationLayer        =
8058                         {
8059                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8060                                 0u,                                                     // deUint32                             mipLevel;
8061                                 0u,                                                     // deUint32                             baseArrayLayer;
8062                                 1u                                                      // deUint32                             layerCount;
8063                         };
8064
8065                         const VkImageCopy                               testCopy        =
8066                         {
8067                                 sourceLayer,                                            // VkImageSubresourceLayers     srcSubresource;
8068                                 {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
8069                                 destinationLayer,                                       // VkImageSubresourceLayers     dstSubresource;
8070                                 {0, 0, (deInt32)slicesLayersNdx},       // VkOffset3D                           dstOffset;
8071                                 defaultHalfExtent,                                      // VkExtent3D                           extent;
8072                         };
8073
8074                         CopyRegion      imageCopy;
8075                         imageCopy.imageCopy     = testCopy;
8076
8077                         params2DTo3D.regions.push_back(imageCopy);
8078                 }
8079
8080                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
8081         }
8082
8083         {
8084                 TestParams      params3DTo2D;
8085                 const deUint32  slicesLayers                    = 16u;
8086                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
8087                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8088                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
8089                 params3DTo2D.src.image.extent.depth             = slicesLayers;
8090                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8091                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8092                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
8093                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8094                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
8095                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
8096                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8097                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8098                 params3DTo2D.allocationKind                             = allocationKind;
8099                 params3DTo2D.extensionUse                               = extensionUse;
8100
8101                 {
8102                         const VkImageSubresourceLayers  sourceLayer     =
8103                         {
8104                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8105                                 0u,                                                     // deUint32                             mipLevel;
8106                                 0u,                                                     // deUint32                             baseArrayLayer;
8107                                 1u                                                      // deUint32                             layerCount;
8108                         };
8109
8110                         const VkImageSubresourceLayers  destinationLayer        =
8111                         {
8112                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8113                                 0u,                                                     // deUint32                             mipLevel;
8114                                 0,                                                      // deUint32                             baseArrayLayer;
8115                                 slicesLayers                            // deUint32                             layerCount;
8116                         };
8117
8118                         const VkImageCopy                               testCopy        =
8119                         {
8120                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8121                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8122                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8123                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8124                                 params3DTo2D.src.image.extent   // VkExtent3D                           extent;
8125                         };
8126
8127                         CopyRegion      imageCopy;
8128                         imageCopy.imageCopy     = testCopy;
8129
8130                         params3DTo2D.regions.push_back(imageCopy);
8131                 }
8132                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
8133         }
8134
8135         {
8136                 TestParams      params2DTo3D;
8137                 const deUint32  slicesLayers                    = 16u;
8138                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8139                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8140                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8141                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8142                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8143                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8144                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8145                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8146                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8147                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8148                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8149                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8150                 params2DTo3D.allocationKind                             = allocationKind;
8151                 params2DTo3D.extensionUse                               = extensionUse;
8152
8153                 {
8154                         const VkImageSubresourceLayers  sourceLayer     =
8155                         {
8156                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8157                                 0u,                                                     // deUint32                             mipLevel;
8158                                 0u,                                                     // deUint32                             baseArrayLayer;
8159                                 slicesLayers                            // deUint32                             layerCount;
8160                         };
8161
8162                         const VkImageSubresourceLayers  destinationLayer        =
8163                         {
8164                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8165                                 0u,                                                     // deUint32                             mipLevel;
8166                                 0u,                                                     // deUint32                             baseArrayLayer;
8167                                 1u                                                      // deUint32                             layerCount;
8168                         };
8169
8170                         const VkImageCopy                               testCopy        =
8171                         {
8172                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8173                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8174                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8175                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8176                                 params2DTo3D.src.image.extent,  // VkExtent3D                           extent;
8177                         };
8178
8179                         CopyRegion      imageCopy;
8180                         imageCopy.imageCopy     = testCopy;
8181
8182                         params2DTo3D.regions.push_back(imageCopy);
8183                 }
8184
8185                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
8186         }
8187
8188         {
8189                 TestParams      params3DTo2D;
8190                 const deUint32  slicesLayers                    = 16u;
8191                 params3DTo2D.src.image.imageType                = VK_IMAGE_TYPE_3D;
8192                 params3DTo2D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8193                 params3DTo2D.src.image.extent                   = defaultHalfExtent;
8194                 params3DTo2D.src.image.extent.depth             = slicesLayers;
8195                 params3DTo2D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8196                 params3DTo2D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8197                 params3DTo2D.dst.image.imageType                = VK_IMAGE_TYPE_2D;
8198                 params3DTo2D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8199                 params3DTo2D.dst.image.extent                   = defaultHalfExtent;
8200                 params3DTo2D.dst.image.extent.depth             = slicesLayers;
8201                 params3DTo2D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8202                 params3DTo2D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8203                 params3DTo2D.allocationKind                             = allocationKind;
8204                 params3DTo2D.extensionUse                               = extensionUse;
8205
8206                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
8207                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
8208
8209                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8210                 {
8211                         const VkImageSubresourceLayers  sourceLayer     =
8212                         {
8213                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8214                                 0u,                                                     // deUint32                             mipLevel;
8215                                 0u,                                                     // deUint32                             baseArrayLayer;
8216                                 1u                                                      // deUint32                             layerCount;
8217                         };
8218
8219                         const VkImageSubresourceLayers  destinationLayer        =
8220                         {
8221                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8222                                         0u,                                                             // deUint32                             mipLevel;
8223                                         slicesLayersNdx,                                // deUint32                             baseArrayLayer;
8224                                         1u                                                              // deUint32                             layerCount;
8225                         };
8226
8227
8228                         const VkImageCopy                               testCopy        =
8229                         {
8230                                 sourceLayer,                                                                                                                    // VkImageSubresourceLayers     srcSubresource;
8231                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D                           srcOffset;
8232                                         destinationLayer,                                                                                                       // VkImageSubresourceLayers     dstSubresource;
8233                                         {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                         // VkOffset3D                           dstOffset;
8234                                         {
8235                                                 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
8236                                                 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
8237                                                 1
8238                                         }                                                                                                                                       // VkExtent3D                           extent;
8239                         };
8240
8241                         CopyRegion      imageCopy;
8242                         imageCopy.imageCopy = testCopy;
8243                         params3DTo2D.regions.push_back(imageCopy);
8244                 }
8245                 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
8246         }
8247
8248         {
8249                 TestParams      params2DTo3D;
8250                 const deUint32  slicesLayers                    = 16u;
8251                 params2DTo3D.src.image.imageType                = VK_IMAGE_TYPE_2D;
8252                 params2DTo3D.src.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8253                 params2DTo3D.src.image.extent                   = defaultHalfExtent;
8254                 params2DTo3D.src.image.extent.depth             = slicesLayers;
8255                 params2DTo3D.src.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8256                 params2DTo3D.src.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8257                 params2DTo3D.dst.image.imageType                = VK_IMAGE_TYPE_3D;
8258                 params2DTo3D.dst.image.format                   = VK_FORMAT_R8G8B8A8_UINT;
8259                 params2DTo3D.dst.image.extent                   = defaultHalfExtent;
8260                 params2DTo3D.dst.image.extent.depth             = slicesLayers;
8261                 params2DTo3D.dst.image.tiling                   = VK_IMAGE_TILING_OPTIMAL;
8262                 params2DTo3D.dst.image.operationLayout  = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8263                 params2DTo3D.allocationKind                             = allocationKind;
8264                 params2DTo3D.extensionUse                               = extensionUse;
8265
8266                 const deUint32 regionWidth                              = defaultHalfExtent.width / slicesLayers -1;
8267                 const deUint32 regionHeight                             = defaultHalfExtent.height / slicesLayers -1 ;
8268
8269                 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8270                 {
8271                         const VkImageSubresourceLayers  sourceLayer     =
8272                         {
8273                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8274                                 0u,                                                     // deUint32                             mipLevel;
8275                                 slicesLayersNdx,                        // deUint32                             baseArrayLayer;
8276                                 1u                                                      // deUint32                             layerCount;
8277                         };
8278
8279                         const VkImageSubresourceLayers  destinationLayer        =
8280                         {
8281                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8282                                 0u,                                                     // deUint32                             mipLevel;
8283                                 0u,                                                     // deUint32                             baseArrayLayer;
8284                                 1u                                                      // deUint32                             layerCount;
8285                         };
8286
8287                         const VkImageCopy                               testCopy        =
8288                         {
8289                                 sourceLayer,                                                                                                                            // VkImageSubresourceLayers     srcSubresource;
8290                                 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0},                                                         // VkOffset3D                           srcOffset;
8291                                 destinationLayer,                                                                                                                       // VkImageSubresourceLayers     dstSubresource;
8292                                 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},       // VkOffset3D                           dstOffset;
8293                                 {
8294                                         defaultHalfExtent.width - regionWidth*slicesLayersNdx,
8295                                         defaultHalfExtent.height - regionHeight*slicesLayersNdx,
8296                                         1
8297                                 }                                                                                                                                                       // VkExtent3D                           extent;
8298                         };
8299
8300                         CopyRegion      imageCopy;
8301                         imageCopy.imageCopy     = testCopy;
8302
8303                         params2DTo3D.regions.push_back(imageCopy);
8304                 }
8305
8306                 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
8307         }
8308 }
8309
8310 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8311 {
8312         tcu::TestContext& testCtx       = group->getTestContext();
8313
8314         {
8315                 TestParams      paramsCubeToArray;
8316                 const deUint32  arrayLayers                                     = 6u;
8317                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8318                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8319                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8320                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8321                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8322                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8323                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8324                 paramsCubeToArray.dst.image.createFlags         = 0;
8325                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8326                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8327                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8328                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8329                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8330                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8331                 paramsCubeToArray.allocationKind                        = allocationKind;
8332                 paramsCubeToArray.extensionUse                          = extensionUse;
8333
8334                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8335                 {
8336                         const VkImageSubresourceLayers  sourceLayer     =
8337                                 {
8338                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8339                                         0u,                                                     // deUint32                             mipLevel;
8340                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8341                                         1u                                                      // deUint32                             layerCount;
8342                                 };
8343
8344                         const VkImageSubresourceLayers  destinationLayer        =
8345                                 {
8346                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8347                                         0u,                                                     // deUint32                             mipLevel;
8348                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8349                                         1u                                                      // deUint32                             layerCount;
8350                                 };
8351
8352                         const VkImageCopy                               testCopy        =
8353                                 {
8354                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8355                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8356                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8357                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8358                                         defaultHalfExtent                               // VkExtent3D                           extent;
8359                                 };
8360
8361                         CopyRegion      imageCopy;
8362                         imageCopy.imageCopy     = testCopy;
8363
8364                         paramsCubeToArray.regions.push_back(imageCopy);
8365                 }
8366
8367                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
8368         }
8369
8370         {
8371                 TestParams      paramsCubeToArray;
8372                 const deUint32  arrayLayers                                     = 6u;
8373                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8374                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8375                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8376                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8377                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8378                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8379                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8380                 paramsCubeToArray.dst.image.createFlags         = 0;
8381                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8382                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8383                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8384                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8385                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8386                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8387                 paramsCubeToArray.allocationKind                        = allocationKind;
8388                 paramsCubeToArray.extensionUse                          = extensionUse;
8389
8390                 {
8391                         const VkImageSubresourceLayers  sourceLayer     =
8392                                 {
8393                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8394                                         0u,                                                     // deUint32                             mipLevel;
8395                                         0u,                                                     // deUint32                             baseArrayLayer;
8396                                         arrayLayers                                     // deUint32                             layerCount;
8397                                 };
8398
8399                         const VkImageSubresourceLayers  destinationLayer        =
8400                                 {
8401                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8402                                         0u,                                                     // deUint32                             mipLevel;
8403                                         0u,                                                     // deUint32                             baseArrayLayer;
8404                                         arrayLayers                                     // deUint32                             layerCount;
8405                                 };
8406
8407                         const VkImageCopy                               testCopy        =
8408                                 {
8409                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8410                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8411                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8412                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8413                                         defaultHalfExtent                       // VkExtent3D                           extent;
8414                                 };
8415
8416                         CopyRegion      imageCopy;
8417                         imageCopy.imageCopy     = testCopy;
8418
8419                         paramsCubeToArray.regions.push_back(imageCopy);
8420                 }
8421
8422                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
8423         }
8424
8425         {
8426                 TestParams      paramsArrayToCube;
8427                 const deUint32  arrayLayers                                     = 6u;
8428                 paramsArrayToCube.src.image.createFlags         = 0;
8429                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
8430                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8431                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
8432                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
8433                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8434                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8435                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8436                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8437                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8438                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
8439                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
8440                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8441                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8442                 paramsArrayToCube.allocationKind                        = allocationKind;
8443                 paramsArrayToCube.extensionUse                          = extensionUse;
8444
8445                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8446                 {
8447                         const VkImageSubresourceLayers  sourceLayer     =
8448                                 {
8449                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8450                                         0u,                                                     // deUint32                             mipLevel;
8451                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8452                                         1u                                                      // deUint32                             layerCount;
8453                                 };
8454
8455                         const VkImageSubresourceLayers  destinationLayer =
8456                                 {
8457                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8458                                         0u,                                                     // deUint32                             mipLevel;
8459                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8460                                         1u                                                      // deUint32                             layerCount;
8461                                 };
8462
8463                         const VkImageCopy                               testCopy =
8464                                 {
8465                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8466                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8467                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8468                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8469                                         defaultHalfExtent                       // VkExtent3D                           extent;
8470                                 };
8471
8472                         CopyRegion      imageCopy;
8473                         imageCopy.imageCopy     = testCopy;
8474
8475                         paramsArrayToCube.regions.push_back(imageCopy);
8476                 }
8477
8478                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
8479         }
8480
8481         {
8482                 TestParams      paramsArrayToCube;
8483                 const deUint32  arrayLayers                                     = 6u;
8484                 paramsArrayToCube.src.image.createFlags         = 0;
8485                 paramsArrayToCube.src.image.imageType           = VK_IMAGE_TYPE_2D;
8486                 paramsArrayToCube.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8487                 paramsArrayToCube.src.image.extent                      = defaultHalfExtent;
8488                 paramsArrayToCube.src.image.extent.depth        = arrayLayers;
8489                 paramsArrayToCube.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8490                 paramsArrayToCube.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8491                 paramsArrayToCube.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8492                 paramsArrayToCube.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8493                 paramsArrayToCube.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8494                 paramsArrayToCube.dst.image.extent                      = defaultHalfExtent;
8495                 paramsArrayToCube.dst.image.extent.depth        = arrayLayers;
8496                 paramsArrayToCube.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8497                 paramsArrayToCube.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8498                 paramsArrayToCube.allocationKind                        = allocationKind;
8499                 paramsArrayToCube.extensionUse                          = extensionUse;
8500
8501                 {
8502                         const VkImageSubresourceLayers sourceLayer =
8503                                 {
8504                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8505                                         0u,                                                             // deUint32                             mipLevel;
8506                                         0u,                                                             // deUint32                             baseArrayLayer;
8507                                         arrayLayers                                             // deUint32                             layerCount;
8508                                 };
8509
8510                         const VkImageSubresourceLayers destinationLayer =
8511                                 {
8512                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8513                                         0u,                                                             // deUint32                             mipLevel;
8514                                         0u,                                                             // deUint32                             baseArrayLayer;
8515                                         arrayLayers                                             // deUint32                             layerCount;
8516                                 };
8517
8518                         const VkImageCopy                               testCopy =
8519                                 {
8520                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8521                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8522                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8523                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8524                                         defaultHalfExtent                               // VkExtent3D                           extent;
8525                                 };
8526
8527                         CopyRegion imageCopy;
8528                         imageCopy.imageCopy = testCopy;
8529
8530                         paramsArrayToCube.regions.push_back(imageCopy);
8531                 }
8532
8533                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
8534         }
8535
8536         {
8537                 TestParams      paramsCubeToArray;
8538                 const deUint32  arrayLayers                                     = 6u;
8539                 paramsCubeToArray.src.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8540                 paramsCubeToArray.src.image.imageType           = VK_IMAGE_TYPE_2D;
8541                 paramsCubeToArray.src.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8542                 paramsCubeToArray.src.image.extent                      = defaultHalfExtent;
8543                 paramsCubeToArray.src.image.extent.depth        = arrayLayers;
8544                 paramsCubeToArray.src.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8545                 paramsCubeToArray.src.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8546                 paramsCubeToArray.dst.image.createFlags         = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8547                 paramsCubeToArray.dst.image.imageType           = VK_IMAGE_TYPE_2D;
8548                 paramsCubeToArray.dst.image.format                      = VK_FORMAT_R8G8B8A8_UINT;
8549                 paramsCubeToArray.dst.image.extent                      = defaultHalfExtent;
8550                 paramsCubeToArray.dst.image.extent.depth        = arrayLayers;
8551                 paramsCubeToArray.dst.image.tiling                      = VK_IMAGE_TILING_OPTIMAL;
8552                 paramsCubeToArray.dst.image.operationLayout     = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8553                 paramsCubeToArray.allocationKind                        = allocationKind;
8554                 paramsCubeToArray.extensionUse                          = extensionUse;
8555
8556                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8557                 {
8558                         const VkImageSubresourceLayers  sourceLayer     =
8559                                 {
8560                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8561                                         0u,                                                     // deUint32                             mipLevel;
8562                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8563                                         1u                                                      // deUint32                             layerCount;
8564                                 };
8565
8566                         const VkImageSubresourceLayers  destinationLayer        =
8567                                 {
8568                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8569                                         0u,                                                     // deUint32                             mipLevel;
8570                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8571                                         1u                                                      // deUint32                             layerCount;
8572                                 };
8573
8574                         const VkImageCopy                               testCopy        =
8575                                 {
8576                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8577                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8578                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8579                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8580                                         defaultHalfExtent                               // VkExtent3D                           extent;
8581                                 };
8582
8583                         CopyRegion      imageCopy;
8584                         imageCopy.imageCopy     = testCopy;
8585
8586                         paramsCubeToArray.regions.push_back(imageCopy);
8587                 }
8588
8589                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
8590         }
8591
8592         {
8593                 TestParams      paramsCubeToCube;
8594                 const deUint32  arrayLayers                                     = 6u;
8595                 paramsCubeToCube.src.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8596                 paramsCubeToCube.src.image.imageType            = VK_IMAGE_TYPE_2D;
8597                 paramsCubeToCube.src.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
8598                 paramsCubeToCube.src.image.extent                       = defaultHalfExtent;
8599                 paramsCubeToCube.src.image.extent.depth         = arrayLayers;
8600                 paramsCubeToCube.src.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
8601                 paramsCubeToCube.src.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8602                 paramsCubeToCube.dst.image.createFlags          = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8603                 paramsCubeToCube.dst.image.imageType            = VK_IMAGE_TYPE_2D;
8604                 paramsCubeToCube.dst.image.format                       = VK_FORMAT_R8G8B8A8_UINT;
8605                 paramsCubeToCube.dst.image.extent                       = defaultHalfExtent;
8606                 paramsCubeToCube.dst.image.extent.depth         = arrayLayers;
8607                 paramsCubeToCube.dst.image.tiling                       = VK_IMAGE_TILING_OPTIMAL;
8608                 paramsCubeToCube.dst.image.operationLayout      = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8609                 paramsCubeToCube.allocationKind                         = allocationKind;
8610                 paramsCubeToCube.extensionUse                           = extensionUse;
8611
8612                 {
8613                         const VkImageSubresourceLayers  sourceLayer     =
8614                                 {
8615                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8616                                         0u,                                                     // deUint32                             mipLevel;
8617                                         0u,                                                     // deUint32                             baseArrayLayer;
8618                                         arrayLayers                                     // deUint32                             layerCount;
8619                                 };
8620
8621                         const VkImageSubresourceLayers  destinationLayer        =
8622                                 {
8623                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8624                                         0u,                                                     // deUint32                             mipLevel;
8625                                         0u,                                                     // deUint32                             baseArrayLayer;
8626                                         arrayLayers                                     // deUint32                             layerCount;
8627                                 };
8628
8629                         const VkImageCopy                               testCopy        =
8630                                 {
8631                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8632                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8633                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8634                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8635                                         defaultHalfExtent                       // VkExtent3D                           extent;
8636                                 };
8637
8638                         CopyRegion      imageCopy;
8639                         imageCopy.imageCopy     = testCopy;
8640
8641                         paramsCubeToCube.regions.push_back(imageCopy);
8642                 }
8643
8644                 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
8645         }
8646 }
8647
8648 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8649 {
8650         tcu::TestContext& testCtx       = group->getTestContext();
8651
8652         {
8653                 TestParams      paramsArrayToArray;
8654                 const deUint32  arrayLayers                                     = 16u;
8655                 paramsArrayToArray.src.image.imageType          = VK_IMAGE_TYPE_2D;
8656                 paramsArrayToArray.src.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
8657                 paramsArrayToArray.src.image.extent                     = defaultHalfExtent;
8658                 paramsArrayToArray.src.image.extent.depth       = arrayLayers;
8659                 paramsArrayToArray.src.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
8660                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8661                 paramsArrayToArray.dst.image.imageType          = VK_IMAGE_TYPE_2D;
8662                 paramsArrayToArray.dst.image.format                     = VK_FORMAT_R8G8B8A8_UINT;
8663                 paramsArrayToArray.dst.image.extent                     = defaultHalfExtent;
8664                 paramsArrayToArray.dst.image.extent.depth       = arrayLayers;
8665                 paramsArrayToArray.dst.image.tiling                     = VK_IMAGE_TILING_OPTIMAL;
8666                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8667                 paramsArrayToArray.allocationKind                       = allocationKind;
8668                 paramsArrayToArray.extensionUse                         = extensionUse;
8669
8670                 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8671                 {
8672                         const VkImageSubresourceLayers  sourceLayer     =
8673                                         {
8674                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8675                                                         0u,                                                     // deUint32                             mipLevel;
8676                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8677                                                         1u                                                      // deUint32                             layerCount;
8678                                         };
8679
8680                         const VkImageSubresourceLayers  destinationLayer =
8681                                         {
8682                                                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
8683                                                         0u,                                                     // deUint32                             mipLevel;
8684                                                         arrayLayersNdx,                         // deUint32                             baseArrayLayer;
8685                                                         1u                                                      // deUint32                             layerCount;
8686                                         };
8687
8688                         const VkImageCopy                               testCopy =
8689                                         {
8690                                                         sourceLayer,                            // VkImageSubresourceLayers     srcSubresource;
8691                                                         {0, 0, 0},                                      // VkOffset3D                           srcOffset;
8692                                                         destinationLayer,                       // VkImageSubresourceLayers     dstSubresource;
8693                                                         {0, 0, 0},                                      // VkOffset3D                           dstOffset;
8694                                                         defaultHalfExtent                       // VkExtent3D                           extent;
8695                                         };
8696
8697                         CopyRegion      imageCopy;
8698                         imageCopy.imageCopy     = testCopy;
8699
8700                         paramsArrayToArray.regions.push_back(imageCopy);
8701                 }
8702
8703                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
8704         }
8705
8706         {
8707                 TestParams      paramsArrayToArray;
8708                 const deUint32  arrayLayers                                             = 16u;
8709                 paramsArrayToArray.src.image.imageType                  = VK_IMAGE_TYPE_2D;
8710                 paramsArrayToArray.src.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
8711                 paramsArrayToArray.src.image.extent                             = defaultHalfExtent;
8712                 paramsArrayToArray.src.image.extent.depth               = arrayLayers;
8713                 paramsArrayToArray.src.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8714                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8715                 paramsArrayToArray.dst.image.imageType                  = VK_IMAGE_TYPE_2D;
8716                 paramsArrayToArray.dst.image.format                             = VK_FORMAT_R8G8B8A8_UINT;
8717                 paramsArrayToArray.dst.image.extent                             = defaultHalfExtent;
8718                 paramsArrayToArray.dst.image.extent.depth               = arrayLayers;
8719                 paramsArrayToArray.dst.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8720                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8721                 paramsArrayToArray.allocationKind                               = allocationKind;
8722                 paramsArrayToArray.extensionUse                                 = extensionUse;
8723
8724                 {
8725                         const VkImageSubresourceLayers sourceLayer =
8726                                         {
8727                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8728                                                         0u,                                                             // deUint32                             mipLevel;
8729                                                         0u,                                                             // deUint32                             baseArrayLayer;
8730                                                         arrayLayers                                             // deUint32                             layerCount;
8731                                         };
8732
8733                         const VkImageSubresourceLayers destinationLayer =
8734                                         {
8735                                                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8736                                                         0u,                                                             // deUint32                             mipLevel;
8737                                                         0u,                                                             // deUint32                             baseArrayLayer;
8738                                                         arrayLayers                                             // deUint32                             layerCount;
8739                                         };
8740
8741                         const VkImageCopy                               testCopy =
8742                                         {
8743                                                         sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8744                                                         {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8745                                                         destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8746                                                         {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8747                                                         defaultHalfExtent                               // VkExtent3D                           extent;
8748                                         };
8749
8750                         CopyRegion imageCopy;
8751                         imageCopy.imageCopy = testCopy;
8752
8753                         paramsArrayToArray.regions.push_back(imageCopy);
8754                 }
8755
8756                 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
8757         }
8758
8759         {
8760                 TestParams      paramsArrayToArray;
8761                 const deUint32  arrayLayers                                             = 16u;
8762                 paramsArrayToArray.src.image.imageType                  = VK_IMAGE_TYPE_2D;
8763                 paramsArrayToArray.src.image.extent                             = defaultHalfExtent;
8764                 paramsArrayToArray.src.image.extent.depth               = arrayLayers;
8765                 paramsArrayToArray.src.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8766                 paramsArrayToArray.src.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8767                 paramsArrayToArray.dst.image.imageType                  = VK_IMAGE_TYPE_2D;
8768                 paramsArrayToArray.dst.image.extent                             = defaultHalfExtent;
8769                 paramsArrayToArray.dst.image.extent.depth               = arrayLayers;
8770                 paramsArrayToArray.dst.image.tiling                             = VK_IMAGE_TILING_OPTIMAL;
8771                 paramsArrayToArray.dst.image.operationLayout    = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8772                 paramsArrayToArray.allocationKind                               = allocationKind;
8773                 paramsArrayToArray.extensionUse                                 = extensionUse;
8774                 paramsArrayToArray.mipLevels                                    = deLog2Floor32(deMinu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
8775
8776                 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
8777                 {
8778                         const VkImageSubresourceLayers sourceLayer =
8779                         {
8780                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8781                                 mipLevelNdx,                                    // deUint32                             mipLevel;
8782                                 0u,                                                             // deUint32                             baseArrayLayer;
8783                                 arrayLayers                                             // deUint32                             layerCount;
8784                         };
8785
8786                         const VkImageSubresourceLayers destinationLayer =
8787                         {
8788                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
8789                                 mipLevelNdx,                                    // deUint32                             mipLevel;
8790                                 0u,                                                             // deUint32                             baseArrayLayer;
8791                                 arrayLayers                                             // deUint32                             layerCount;
8792                         };
8793
8794                         const VkExtent3D extent =
8795                         {
8796                                 (deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),             // deUint32    width;
8797                                 (deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1),    // deUint32    height;
8798                                 1u,                                                                                                                             // deUint32    depth;
8799                         };
8800
8801                         const VkImageCopy                               testCopy =
8802                         {
8803                                 sourceLayer,                                    // VkImageSubresourceLayers     srcSubresource;
8804                                 {0, 0, 0},                                              // VkOffset3D                           srcOffset;
8805                                 destinationLayer,                               // VkImageSubresourceLayers     dstSubresource;
8806                                 {0, 0, 0},                                              // VkOffset3D                           dstOffset;
8807                                 extent                                                  // VkExtent3D                           extent;
8808                         };
8809
8810                         CopyRegion imageCopy;
8811                         imageCopy.imageCopy = testCopy;
8812
8813                         paramsArrayToArray.regions.push_back(imageCopy);
8814                 }
8815
8816                 VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
8817
8818                 for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
8819                 {
8820                         paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
8821                         paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
8822                         for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
8823                         {
8824                                 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
8825                                 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
8826                         }
8827                         std::ostringstream testName;
8828                         const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
8829                         testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
8830                         group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
8831                 }
8832         }
8833 };
8834
8835 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8836 {
8837         addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
8838         addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
8839         addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
8840         addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
8841         addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
8842         addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
8843 }
8844
8845 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8846 {
8847         tcu::TestContext& testCtx       = group->getTestContext();
8848
8849         {
8850                 TestParams      params;
8851                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8852                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8853                 params.src.image.extent                         = defaultExtent;
8854                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8855                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8856                 params.dst.buffer.size                          = defaultSize * defaultSize;
8857                 params.allocationKind                           = allocationKind;
8858                 params.extensionUse                                     = extensionUse;
8859
8860                 const VkBufferImageCopy bufferImageCopy =
8861                 {
8862                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
8863                         0u,                                                                                     // deUint32                                     bufferRowLength;
8864                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8865                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8866                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
8867                         defaultExtent                                                           // VkExtent3D                           imageExtent;
8868                 };
8869                 CopyRegion      copyRegion;
8870                 copyRegion.bufferImageCopy      = bufferImageCopy;
8871
8872                 params.regions.push_back(copyRegion);
8873
8874                 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
8875         }
8876
8877         {
8878                 TestParams      params;
8879                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8880                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8881                 params.src.image.extent                         = defaultExtent;
8882                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8883                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8884                 params.dst.buffer.size                          = defaultSize * defaultSize;
8885                 params.allocationKind                           = allocationKind;
8886                 params.extensionUse                                     = extensionUse;
8887
8888                 const VkBufferImageCopy bufferImageCopy =
8889                 {
8890                         defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
8891                         0u,                                                                                     // deUint32                                     bufferRowLength;
8892                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8893                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8894                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8895                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8896                 };
8897                 CopyRegion      copyRegion;
8898                 copyRegion.bufferImageCopy      = bufferImageCopy;
8899
8900                 params.regions.push_back(copyRegion);
8901
8902                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
8903         }
8904
8905         {
8906                 TestParams      params;
8907                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8908                 params.src.image.format                         = VK_FORMAT_R8_UNORM;
8909                 params.src.image.extent                         = defaultExtent;
8910                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8911                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8912                 params.dst.buffer.size                          = defaultSize * defaultSize;
8913                 params.allocationKind                           = allocationKind;
8914                 params.extensionUse                                     = extensionUse;
8915
8916                 const VkBufferImageCopy bufferImageCopy =
8917                 {
8918                         defaultSize * defaultHalfSize + 1u,             // VkDeviceSize                         bufferOffset;
8919                         0u,                                                                                     // deUint32                                     bufferRowLength;
8920                         0u,                                                                                     // deUint32                                     bufferImageHeight;
8921                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8922                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8923                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8924                 };
8925                 CopyRegion      copyRegion;
8926                 copyRegion.bufferImageCopy      = bufferImageCopy;
8927
8928                 params.regions.push_back(copyRegion);
8929
8930                 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
8931         }
8932
8933         {
8934                 TestParams      params;
8935                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8936                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8937                 params.src.image.extent                         = defaultExtent;
8938                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8939                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8940                 params.dst.buffer.size                          = defaultSize * defaultSize;
8941                 params.allocationKind                           = allocationKind;
8942                 params.extensionUse                                     = extensionUse;
8943
8944                 const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
8945                 const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
8946                 const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
8947                 deUint32                        divisor         = 1;
8948                 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
8949                 {
8950                         const deUint32                  bufferRowLength         = defaultFourthSize;
8951                         const deUint32                  bufferImageHeight       = defaultFourthSize;
8952                         const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
8953                         DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
8954                         DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
8955                         DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
8956
8957                         CopyRegion                              region;
8958                         const VkBufferImageCopy bufferImageCopy         =
8959                         {
8960                                 offset,                                         // VkDeviceSize                         bufferOffset;
8961                                 bufferRowLength,                        // deUint32                                     bufferRowLength;
8962                                 bufferImageHeight,                      // deUint32                                     bufferImageHeight;
8963                                 defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
8964                                 {0, 0, 0},                                      // VkOffset3D                           imageOffset;
8965                                 imageExtent                                     // VkExtent3D                           imageExtent;
8966                         };
8967                         region.bufferImageCopy  = bufferImageCopy;
8968                         params.regions.push_back(region);
8969                 }
8970
8971                 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
8972         }
8973
8974         {
8975                 TestParams                              params;
8976                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
8977                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
8978                 params.src.image.extent                         = defaultExtent;
8979                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
8980                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8981                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
8982                 params.allocationKind                           = allocationKind;
8983                 params.extensionUse                                     = extensionUse;
8984
8985                 const VkBufferImageCopy bufferImageCopy =
8986                 {
8987                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
8988                         defaultSize,                                                            // deUint32                                     bufferRowLength;
8989                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
8990                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
8991                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
8992                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
8993                 };
8994                 CopyRegion                              copyRegion;
8995                 copyRegion.bufferImageCopy      = bufferImageCopy;
8996
8997                 params.regions.push_back(copyRegion);
8998
8999                 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
9000         }
9001
9002         {
9003                 TestParams                              params;
9004                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9005                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9006                 params.src.image.extent                         = defaultExtent;
9007                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9008                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9009                 params.dst.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9010                 params.allocationKind                           = allocationKind;
9011                 params.extensionUse                                     = extensionUse;
9012
9013                 const VkBufferImageCopy bufferImageCopy =
9014                 {
9015                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9016                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9017                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9018                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9019                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9020                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9021                 };
9022                 CopyRegion                              copyRegion;
9023                 copyRegion.bufferImageCopy      = bufferImageCopy;
9024
9025                 params.regions.push_back(copyRegion);
9026
9027                 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));
9028         }
9029
9030         {
9031                 TestParams                              params;
9032                 deUint32                                arrayLayers = 16u;
9033                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9034                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9035                 params.src.image.extent                         = defaultHalfExtent;
9036                 params.src.image.extent.depth           = arrayLayers;
9037                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9038                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9039                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9040                 params.allocationKind                           = allocationKind;
9041                 params.extensionUse                                     = extensionUse;
9042
9043                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9044                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9045                 {
9046                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9047                         const VkBufferImageCopy bufferImageCopy =
9048                                 {
9049                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9050                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
9051                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
9052                                         {
9053                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9054                                                 0u,                                                                                             // deUint32                             mipLevel;
9055                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9056                                                 1u,                                                                                             // deUint32                             layerCount;
9057                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9058                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9059                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9060                                 };
9061                         CopyRegion copyRegion;
9062                         copyRegion.bufferImageCopy = bufferImageCopy;
9063
9064                         params.regions.push_back(copyRegion);
9065                 }
9066                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
9067         }
9068
9069         {
9070                 TestParams                              params;
9071                 deUint32                                arrayLayers = 16u;
9072                 params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
9073                 params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9074                 params.src.image.extent                         = defaultHalfExtent;
9075                 params.src.image.extent.depth           = arrayLayers;
9076                 params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9077                 params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9078                 params.dst.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9079                 params.allocationKind                           = allocationKind;
9080                 params.extensionUse                                     = extensionUse;
9081
9082                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9083                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9084                 {
9085                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9086                         const VkBufferImageCopy bufferImageCopy =
9087                                 {
9088                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9089                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
9090                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
9091                                         {
9092                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9093                                                 0u,                                                                                             // deUint32                             mipLevel;
9094                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9095                                                 1u,                                                                                             // deUint32                             layerCount;
9096                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9097                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9098                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9099                                 };
9100                         CopyRegion copyRegion;
9101                         copyRegion.bufferImageCopy = bufferImageCopy;
9102
9103                         params.regions.push_back(copyRegion);
9104                 }
9105                 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
9106         }
9107 }
9108
9109 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9110 {
9111         tcu::TestContext& testCtx = group->getTestContext();
9112
9113         const struct
9114         {
9115                 const char*             name;
9116                 const VkFormat  format;
9117         } depthAndStencilFormats[] =
9118         {
9119                 { "d16_unorm",                          VK_FORMAT_D16_UNORM                             },
9120                 { "x8_d24_unorm_pack32",        VK_FORMAT_X8_D24_UNORM_PACK32   },
9121                 { "d32_sfloat",                         VK_FORMAT_D32_SFLOAT                    },
9122                 { "d16_unorm_s8_uint",          VK_FORMAT_D16_UNORM_S8_UINT             },
9123                 { "d24_unorm_s8_uint",          VK_FORMAT_D24_UNORM_S8_UINT             },
9124                 { "d32_sfloat_s8_uint",         VK_FORMAT_D32_SFLOAT_S8_UINT    }
9125         };
9126
9127         const VkImageSubresourceLayers  depthSourceLayer                =
9128         {
9129                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
9130                 0u,                                                     // deUint32                             mipLevel;
9131                 0u,                                                     // deUint32                             baseArrayLayer;
9132                 1u,                                                     // deUint32                             layerCount;
9133         };
9134
9135         const VkBufferImageCopy                 bufferDepthCopy                 =
9136         {
9137                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
9138                 0u,                                                                                     // deUint32                                     bufferRowLength;
9139                 0u,                                                                                     // deUint32                                     bufferImageHeight;
9140                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
9141                 {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
9142                 defaultExtent                                                           // VkExtent3D                           imageExtent;
9143         };
9144
9145         const VkBufferImageCopy                 bufferDepthCopyOffset   =
9146         {
9147                 32,                                                                                     // VkDeviceSize                         bufferOffset;
9148                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9149                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9150                 depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
9151                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9152                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9153         };
9154
9155         const VkImageSubresourceLayers  stencilSourceLayer              =
9156         {
9157                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
9158                 0u,                                                             // deUint32                             mipLevel;
9159                 0u,                                                             // deUint32                             baseArrayLayer;
9160                 1u,                                                             // deUint32                             layerCount;
9161         };
9162
9163         const VkBufferImageCopy                 bufferStencilCopy               =
9164         {
9165                 0u,                                     // VkDeviceSize                         bufferOffset;
9166                 0u,                                     // deUint32                                     bufferRowLength;
9167                 0u,                                     // deUint32                                     bufferImageHeight;
9168                 stencilSourceLayer,     // VkImageSubresourceLayers     imageSubresource;
9169                 {0, 0, 0},                      // VkOffset3D                           imageOffset;
9170                 defaultExtent           // VkExtent3D                           imageExtent;
9171         };
9172
9173     const VkBufferImageCopy                     bufferStencilCopyOffset =
9174         {
9175                 32,                                                                                     // VkDeviceSize                         bufferOffset;
9176                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9177                 defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9178                 stencilSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9179                 {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9180                 defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9181         };
9182
9183     const bool                                          useOffset[]                             = {false, true};
9184
9185         // Note: Depth stencil tests I want to do
9186         // Formats: D16, D24S8, D32FS8
9187         // Test writing each component with separate CopyBufferToImage commands
9188         // Test writing both components in one CopyBufferToImage command
9189         // Swap order of writes of Depth & Stencil
9190         // whole surface, subimages?
9191         // Similar tests as BufferToImage?
9192         for (const auto config : depthAndStencilFormats)
9193                 for (const auto offset : useOffset)
9194                 {
9195                         // TODO: Check that this format is supported before creating tests?
9196                         //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
9197
9198                         CopyRegion                                      copyDepthRegion;
9199                         CopyRegion                                      copyStencilRegion;
9200                         TestParams                                      params;
9201                         const tcu::TextureFormat        format          = mapVkFormat(config.format);
9202                         const bool                                      hasDepth        = tcu::hasDepthComponent(format.order);
9203                         const bool                                      hasStencil      = tcu::hasStencilComponent(format.order);
9204                         std::string                                     description     = config.name;
9205
9206                         if (offset)
9207                         {
9208                                 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
9209                                 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
9210                                 description = "buffer_offset_" + description;
9211                                 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9212                         }
9213                         else
9214                         {
9215                                 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
9216                                 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
9217                                 params.src.buffer.size = defaultSize * defaultSize;
9218                         }
9219
9220                         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9221                         params.dst.image.format = config.format;
9222                         params.dst.image.extent = defaultExtent;
9223                         params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9224                         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9225                         params.allocationKind = allocationKind;
9226                         params.extensionUse = extensionUse;
9227
9228                         if (hasDepth && hasStencil)
9229                         {
9230                                 params.singleCommand = DE_TRUE;
9231
9232                                 params.regions.push_back(copyDepthRegion);
9233                                 params.regions.push_back(copyStencilRegion);
9234
9235                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
9236
9237                                 params.singleCommand = DE_FALSE;
9238
9239                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
9240
9241                                 params.regions.clear();
9242                                 params.regions.push_back(copyStencilRegion);
9243                                 params.regions.push_back(copyDepthRegion);
9244
9245                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
9246
9247                                 params.singleCommand = DE_TRUE;
9248                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
9249                         }
9250
9251                         if (hasStencil)
9252                         {
9253                                 params.regions.clear();
9254                                 params.regions.push_back(copyStencilRegion);
9255
9256                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
9257                         }
9258
9259                         if (hasDepth)
9260                         {
9261                                 params.regions.clear();
9262                                 params.regions.push_back(copyDepthRegion);
9263
9264                                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
9265                         }
9266                 }
9267 }
9268
9269 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9270 {
9271         tcu::TestContext& testCtx       = group->getTestContext();
9272
9273         {
9274                 TestParams      params;
9275                 params.src.buffer.size                          = defaultSize * defaultSize;
9276                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9277                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UINT;
9278                 params.dst.image.extent                         = defaultExtent;
9279                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9280                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9281                 params.allocationKind                           = allocationKind;
9282                 params.extensionUse                                     = extensionUse;
9283
9284                 const VkBufferImageCopy bufferImageCopy =
9285                 {
9286                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
9287                         0u,                                                                                     // deUint32                                     bufferRowLength;
9288                         0u,                                                                                     // deUint32                                     bufferImageHeight;
9289                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9290                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
9291                         defaultExtent                                                           // VkExtent3D                           imageExtent;
9292                 };
9293                 CopyRegion      copyRegion;
9294                 copyRegion.bufferImageCopy      = bufferImageCopy;
9295
9296                 params.regions.push_back(copyRegion);
9297
9298                 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
9299         }
9300
9301         {
9302                 TestParams      params;
9303                 params.src.buffer.size                          = defaultSize * defaultSize;
9304                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9305                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9306                 params.dst.image.extent                         = defaultExtent;
9307                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9308                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9309                 params.allocationKind                           = allocationKind;
9310                 params.extensionUse                                     = extensionUse;
9311
9312                 CopyRegion      region;
9313                 deUint32        divisor = 1;
9314                 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
9315                 {
9316                         const VkBufferImageCopy bufferImageCopy =
9317                         {
9318                                 0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
9319                                 0u,                                                                                                                             // deUint32                                     bufferRowLength;
9320                                 0u,                                                                                                                             // deUint32                                     bufferImageHeight;
9321                                 defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
9322                                 {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
9323                                 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
9324                         };
9325                         region.bufferImageCopy  = bufferImageCopy;
9326                         params.regions.push_back(region);
9327                 }
9328
9329                 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
9330         }
9331
9332         {
9333                 TestParams      params;
9334                 params.src.buffer.size                          = defaultSize * defaultSize;
9335                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9336                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9337                 params.dst.image.extent                         = defaultExtent;
9338                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9339                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9340                 params.allocationKind                           = allocationKind;
9341                 params.extensionUse                                     = extensionUse;
9342
9343                 const VkBufferImageCopy bufferImageCopy =
9344                 {
9345                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9346                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9347                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9348                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9349                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9350                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9351                 };
9352                 CopyRegion      copyRegion;
9353                 copyRegion.bufferImageCopy      = bufferImageCopy;
9354
9355                 params.regions.push_back(copyRegion);
9356
9357                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
9358         }
9359
9360         {
9361                 TestParams      params;
9362                 params.src.buffer.size                          = defaultSize * defaultSize;
9363                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9364                 params.dst.image.format                         = VK_FORMAT_R8_UNORM;
9365                 params.dst.image.extent                         = defaultExtent;
9366                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9367                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9368                 params.allocationKind                           = allocationKind;
9369                 params.extensionUse                                     = extensionUse;
9370
9371                 const VkBufferImageCopy bufferImageCopy =
9372                 {
9373                         defaultFourthSize + 1u,                                         // VkDeviceSize                         bufferOffset;
9374                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferRowLength;
9375                         defaultHalfSize + defaultFourthSize,            // deUint32                                     bufferImageHeight;
9376                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9377                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9378                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9379                 };
9380                 CopyRegion      copyRegion;
9381                 copyRegion.bufferImageCopy      = bufferImageCopy;
9382
9383                 params.regions.push_back(copyRegion);
9384
9385                 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
9386         }
9387
9388         {
9389                 TestParams                              params;
9390                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9391                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9392                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9393                 params.dst.image.extent                         = defaultExtent;
9394                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9395                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9396                 params.allocationKind                           = allocationKind;
9397                 params.extensionUse                                     = extensionUse;
9398
9399                 const VkBufferImageCopy bufferImageCopy =
9400                 {
9401                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
9402                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9403                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9404                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9405                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9406                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9407                 };
9408                 CopyRegion                              copyRegion;
9409                 copyRegion.bufferImageCopy      = bufferImageCopy;
9410
9411                 params.regions.push_back(copyRegion);
9412
9413                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
9414         }
9415
9416         {
9417                 TestParams                              params;
9418                 params.src.buffer.size                          = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9419                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9420                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9421                 params.dst.image.extent                         = defaultExtent;
9422                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9423                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9424                 params.allocationKind                           = allocationKind;
9425                 params.extensionUse                                     = extensionUse;
9426
9427                 const VkBufferImageCopy bufferImageCopy =
9428                 {
9429                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
9430                         defaultSize,                                                            // deUint32                                     bufferRowLength;
9431                         defaultSize,                                                            // deUint32                                     bufferImageHeight;
9432                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
9433                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
9434                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
9435                 };
9436                 CopyRegion                              copyRegion;
9437                 copyRegion.bufferImageCopy      = bufferImageCopy;
9438
9439                 params.regions.push_back(copyRegion);
9440
9441                 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
9442         }
9443
9444         {
9445                 TestParams                              params;
9446                 deUint32                                arrayLayers = 16u;
9447                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9448                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9449                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9450                 params.dst.image.extent                         = defaultHalfExtent;
9451                 params.dst.image.extent.depth           = arrayLayers;
9452                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9453                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9454                 params.allocationKind                           = allocationKind;
9455                 params.extensionUse                                     = extensionUse;
9456
9457                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9458                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9459                 {
9460                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9461                         const VkBufferImageCopy bufferImageCopy =
9462                                 {
9463                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9464                                         0u,                                                                                                             // deUint32                                     bufferRowLength;
9465                                         0u,                                                                                                             // deUint32                                     bufferImageHeight;
9466                                         {
9467                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9468                                                 0u,                                                                                             // deUint32                             mipLevel;
9469                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9470                                                 1u,                                                                                             // deUint32                             layerCount;
9471                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9472                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9473                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9474                                 };
9475                         CopyRegion copyRegion;
9476                         copyRegion.bufferImageCopy = bufferImageCopy;
9477
9478                         params.regions.push_back(copyRegion);
9479                 }
9480                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
9481         }
9482
9483         {
9484                 TestParams                              params;
9485                 deUint32                                arrayLayers = 16u;
9486                 params.src.buffer.size                          = defaultHalfSize * defaultHalfSize * arrayLayers;
9487                 params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
9488                 params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
9489                 params.dst.image.extent                         = defaultHalfExtent;
9490                 params.dst.image.extent.depth           = arrayLayers;
9491                 params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
9492                 params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9493                 params.allocationKind                           = allocationKind;
9494                 params.extensionUse                                     = extensionUse;
9495
9496                 const int pixelSize     = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9497                 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9498                 {
9499                         const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9500                         const VkBufferImageCopy bufferImageCopy =
9501                                 {
9502                                         offset,                                                                                                 // VkDeviceSize                         bufferOffset;
9503                                         defaultHalfSize,                                                                                // deUint32                                     bufferRowLength;
9504                                         defaultHalfSize,                                                                                // deUint32                                     bufferImageHeight;
9505                                         {
9506                                                 VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags   aspectMask;
9507                                                 0u,                                                                                             // deUint32                             mipLevel;
9508                                                 arrayLayerNdx,                                                                  // deUint32                             baseArrayLayer;
9509                                                 1u,                                                                                             // deUint32                             layerCount;
9510                                         },                                                                                                              // VkImageSubresourceLayers     imageSubresource;
9511                                         {0, 0, 0},                                                                                              // VkOffset3D                           imageOffset;
9512                                         defaultHalfExtent                                                                               // VkExtent3D                           imageExtent;
9513                                 };
9514                         CopyRegion copyRegion;
9515                         copyRegion.bufferImageCopy = bufferImageCopy;
9516
9517                         params.regions.push_back(copyRegion);
9518                 }
9519                 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
9520         }
9521 }
9522
9523 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9524 {
9525         tcu::TestContext&                               testCtx                                 = group->getTestContext();
9526
9527         {
9528                 TestParams                      params;
9529                 params.src.buffer.size  = defaultSize;
9530                 params.dst.buffer.size  = defaultSize;
9531                 params.allocationKind   = allocationKind;
9532                 params.extensionUse             = extensionUse;
9533
9534                 const VkBufferCopy      bufferCopy      =
9535                 {
9536                         0u,                             // VkDeviceSize srcOffset;
9537                         0u,                             // VkDeviceSize dstOffset;
9538                         defaultSize,    // VkDeviceSize size;
9539                 };
9540
9541                 CopyRegion      copyRegion;
9542                 copyRegion.bufferCopy   = bufferCopy;
9543                 params.regions.push_back(copyRegion);
9544
9545                 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
9546         }
9547
9548         // Filter is VK_FILTER_NEAREST.
9549         {
9550                 TestParams                      params;
9551                 params.src.buffer.size  = defaultFourthSize;
9552                 params.dst.buffer.size  = defaultFourthSize;
9553                 params.allocationKind   = allocationKind;
9554                 params.extensionUse             = extensionUse;
9555
9556                 const VkBufferCopy      bufferCopy      =
9557                 {
9558                         12u,    // VkDeviceSize srcOffset;
9559                         4u,             // VkDeviceSize dstOffset;
9560                         1u,             // VkDeviceSize size;
9561                 };
9562
9563                 CopyRegion      copyRegion;
9564                 copyRegion.bufferCopy = bufferCopy;
9565                 params.regions.push_back(copyRegion);
9566
9567                 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
9568         }
9569
9570         {
9571                 const deUint32          size            = 16;
9572                 TestParams                      params;
9573                 params.src.buffer.size  = size;
9574                 params.dst.buffer.size  = size * (size + 1);
9575                 params.allocationKind   = allocationKind;
9576                 params.extensionUse             = extensionUse;
9577
9578                 // Copy region with size 1..size
9579                 for (unsigned int i = 1; i <= size; i++)
9580                 {
9581                         const VkBufferCopy      bufferCopy      =
9582                         {
9583                                 0,                      // VkDeviceSize srcOffset;
9584                                 i * size,       // VkDeviceSize dstOffset;
9585                                 i,                      // VkDeviceSize size;
9586                         };
9587
9588                         CopyRegion      copyRegion;
9589                         copyRegion.bufferCopy = bufferCopy;
9590                         params.regions.push_back(copyRegion);
9591                 }
9592
9593                 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
9594         }
9595 }
9596
9597 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
9598 {
9599         tcu::TestContext& testCtx = group->getTestContext();
9600
9601         // Filter is VK_FILTER_NEAREST.
9602         {
9603                 params.filter                                   = VK_FILTER_NEAREST;
9604                 const std::string description   = "Nearest filter";
9605
9606                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9607                 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
9608
9609                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9610                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
9611                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
9612
9613                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9614                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9615                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
9616         }
9617
9618         // Filter is VK_FILTER_LINEAR.
9619         {
9620                 params.filter                                   = VK_FILTER_LINEAR;
9621                 const std::string description   = "Linear filter";
9622
9623                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9624                 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
9625
9626                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9627                 const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
9628                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
9629
9630                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9631                 const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9632                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
9633         }
9634
9635         // Filter is VK_FILTER_CUBIC_EXT.
9636         // Cubic filtering can only be used with 2D images.
9637         if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
9638         {
9639                 params.filter                                   = VK_FILTER_CUBIC_EXT;
9640                 const std::string description   = "Cubic filter";
9641
9642                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9643                 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
9644
9645                 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
9646                 const std::string       descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
9647                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
9648
9649                 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
9650                 const std::string       descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
9651                 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
9652         }
9653 }
9654
9655 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
9656 {
9657         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9658         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9659         params.src.image.extent                 = defaultExtent;
9660         params.dst.image.extent                 = defaultExtent;
9661         params.src.image.extent.depth   = imageDepth;
9662         params.dst.image.extent.depth   = imageDepth;
9663
9664         {
9665                 const VkImageBlit imageBlit =
9666                 {
9667                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9668                         {
9669                                 { 0, 0, 0 },
9670                                 { defaultSize, defaultSize, imageDepth }
9671                         },                                      // VkOffset3D                           srcOffsets[2];
9672
9673                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9674                         {
9675                                 { 0, 0, 0 },
9676                                 { defaultSize, defaultSize, imageDepth }
9677                         }                                       // VkOffset3D                           dstOffset[2];
9678                 };
9679
9680                 CopyRegion region;
9681                 region.imageBlit = imageBlit;
9682                 params.regions.push_back(region);
9683         }
9684
9685         addBlittingImageSimpleTests(group, params);
9686 }
9687
9688 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
9689 {
9690         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9691         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9692         params.src.image.extent                 = defaultExtent;
9693         params.dst.image.extent                 = defaultExtent;
9694         params.src.image.extent.depth   = imageDepth;
9695         params.dst.image.extent.depth   = imageDepth;
9696
9697         {
9698                 const VkImageBlit imageBlit =
9699                 {
9700                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9701                         {
9702                                 {0, 0, 0},
9703                                 {defaultSize, defaultSize, imageDepth}
9704                         },                                      // VkOffset3D                           srcOffsets[2];
9705
9706                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9707                         {
9708                                 {defaultSize, defaultSize, 0},
9709                                 {0, 0, imageDepth}
9710                         }                                       // VkOffset3D                           dstOffset[2];
9711                 };
9712
9713                 CopyRegion region;
9714                 region.imageBlit = imageBlit;
9715                 params.regions.push_back(region);
9716         }
9717
9718         addBlittingImageSimpleTests(group, params);
9719 }
9720
9721 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
9722 {
9723         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9724         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9725         params.src.image.extent                 = defaultExtent;
9726         params.dst.image.extent                 = defaultExtent;
9727         params.src.image.extent.depth   = imageDepth;
9728         params.dst.image.extent.depth   = imageDepth;
9729
9730         {
9731                 const VkImageBlit imageBlit =
9732                 {
9733                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9734                         {
9735                                 {0, 0, 0},
9736                                 {defaultSize, defaultSize, imageDepth}
9737                         },                                      // VkOffset3D                           srcOffsets[2];
9738
9739                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9740                         {
9741                                 {defaultSize, 0, 0},
9742                                 {0, defaultSize, imageDepth}
9743                         }                                       // VkOffset3D                           dstOffset[2];
9744                 };
9745
9746                 CopyRegion region;
9747                 region.imageBlit = imageBlit;
9748                 params.regions.push_back(region);
9749         }
9750
9751         addBlittingImageSimpleTests(group, params);
9752 }
9753
9754 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
9755 {
9756         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9757         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9758         params.src.image.extent                 = defaultExtent;
9759         params.dst.image.extent                 = defaultExtent;
9760         params.src.image.extent.depth   = imageDepth;
9761         params.dst.image.extent.depth   = imageDepth;
9762
9763         {
9764                 const VkImageBlit imageBlit =
9765                 {
9766                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9767                         {
9768                                 {0, 0, 0},
9769                                 {defaultSize, defaultSize, imageDepth}
9770                         },                                      // VkOffset3D                           srcOffsets[2];
9771
9772                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9773                         {
9774                                 {0, defaultSize, 0},
9775                                 {defaultSize, 0, imageDepth}
9776                         }                                       // VkOffset3D                           dstOffset[2];
9777                 };
9778
9779                 CopyRegion region;
9780                 region.imageBlit = imageBlit;
9781                 params.regions.push_back(region);
9782         }
9783
9784         addBlittingImageSimpleTests(group, params);
9785 }
9786
9787 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
9788 {
9789         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9790         DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
9791         params.src.image.extent                 = defaultExtent;
9792         params.dst.image.extent                 = defaultExtent;
9793         params.src.image.extent.depth   = defaultSize;
9794         params.dst.image.extent.depth   = defaultSize;
9795
9796         {
9797                 const VkImageBlit imageBlit =
9798                 {
9799                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9800                         {
9801                                 {0, 0, 0},
9802                                 {defaultSize, defaultSize, defaultSize}
9803                         },                                      // VkOffset3D                           srcOffsets[2];
9804
9805                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9806                         {
9807                                 {0, 0, defaultSize},
9808                                 {defaultSize, defaultSize, 0}
9809                         }                                       // VkOffset3D                           dstOffset[2];
9810                 };
9811
9812                 CopyRegion region;
9813                 region.imageBlit = imageBlit;
9814                 params.regions.push_back(region);
9815         }
9816
9817         addBlittingImageSimpleTests(group, params);
9818 }
9819
9820 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
9821 {
9822         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9823         const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9824         params.src.image.extent                 = defaultExtent;
9825         params.dst.image.extent                 = defaultExtent;
9826         params.src.image.extent.depth   = imageDepth;
9827         params.dst.image.extent.depth   = imageDepth;
9828
9829         // No mirroring.
9830         {
9831                 const VkImageBlit imageBlit =
9832                 {
9833                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9834                         {
9835                                 {0, 0, 0},
9836                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9837                         },                                      // VkOffset3D                           srcOffsets[2];
9838
9839                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9840                         {
9841                                 {0, 0, 0},
9842                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9843                         }                                       // VkOffset3D                           dstOffset[2];
9844                 };
9845
9846                 CopyRegion region;
9847                 region.imageBlit = imageBlit;
9848                 params.regions.push_back(region);
9849         }
9850
9851         // Flipping y coordinates.
9852         {
9853                 const VkImageBlit imageBlit =
9854                 {
9855                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9856                         {
9857                                 {defaultHalfSize, 0, 0},
9858                                 {defaultSize, defaultHalfSize, imageDepth}
9859                         },                                      // VkOffset3D                           srcOffsets[2];
9860
9861                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9862                         {
9863                                 {defaultHalfSize, defaultHalfSize, 0},
9864                                 {defaultSize, 0, imageDepth}
9865                         }                                       // VkOffset3D                           dstOffset[2];
9866                 };
9867                 CopyRegion region;
9868                 region.imageBlit = imageBlit;
9869                 params.regions.push_back(region);
9870         }
9871
9872         // Flipping x coordinates.
9873         {
9874                 const VkImageBlit imageBlit =
9875                 {
9876                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9877                         {
9878                                 {0, defaultHalfSize, 0},
9879                                 {defaultHalfSize, defaultSize, imageDepth}
9880                         },                                      // VkOffset3D                           srcOffsets[2];
9881
9882                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9883                         {
9884                                 {defaultHalfSize, defaultHalfSize, 0},
9885                                 {0, defaultSize, imageDepth}
9886                         }                                       // VkOffset3D                           dstOffset[2];
9887                 };
9888
9889                 CopyRegion region;
9890                 region.imageBlit = imageBlit;
9891                 params.regions.push_back(region);
9892         }
9893
9894         // Flipping x and y coordinates.
9895         {
9896                 const VkImageBlit imageBlit =
9897                 {
9898                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9899                         {
9900                                 {defaultHalfSize, defaultHalfSize, 0},
9901                                 {defaultSize, defaultSize, imageDepth}
9902                         },                                      // VkOffset3D                           srcOffsets[2];
9903
9904                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9905                         {
9906                                 {defaultSize, defaultSize, 0},
9907                                 {defaultHalfSize, defaultHalfSize, imageDepth}
9908                         }                                       // VkOffset3D                           dstOffset[2];
9909                 };
9910
9911                 CopyRegion region;
9912                 region.imageBlit = imageBlit;
9913                 params.regions.push_back(region);
9914         }
9915
9916         addBlittingImageSimpleTests(group, params);
9917 }
9918
9919 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
9920 {
9921         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9922         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9923         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
9924         params.src.image.extent                 = defaultExtent;
9925         params.dst.image.extent                 = defaultHalfExtent;
9926         params.src.image.extent.depth   = imageDepth;
9927         params.dst.image.extent.depth   = halfImageDepth;
9928
9929         {
9930                 const VkImageBlit imageBlit =
9931                 {
9932                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9933                         {
9934                                 {0, 0, 0},
9935                                 {defaultSize, defaultSize, imageDepth}
9936                         },                                      // VkOffset3D                                   srcOffsets[2];
9937
9938                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9939                         {
9940                                 {0, 0, 0},
9941                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
9942                         }                                       // VkOffset3D                                   dstOffset[2];
9943                 };
9944
9945                 CopyRegion region;
9946                 region.imageBlit = imageBlit;
9947                 params.regions.push_back(region);
9948         }
9949
9950         addBlittingImageSimpleTests(group, params);
9951 }
9952
9953 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
9954 {
9955         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9956         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9957         const deInt32   halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
9958         params.src.image.extent                 = defaultHalfExtent;
9959         params.dst.image.extent                 = defaultExtent;
9960         params.src.image.extent.depth   = halfImageDepth;
9961         params.dst.image.extent.depth   = imageDepth;
9962
9963         {
9964                 const VkImageBlit imageBlit =
9965                 {
9966                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
9967                         {
9968                                 {0, 0, 0},
9969                                 {defaultHalfSize, defaultHalfSize, halfImageDepth}
9970                         },                                      // VkOffset3D                                   srcOffsets[2];
9971
9972                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
9973                         {
9974                                 {0, 0, 0},
9975                                 {defaultSize, defaultSize, imageDepth}
9976                         }                                       // VkOffset3D                                   dstOffset[2];
9977                 };
9978
9979                 CopyRegion region;
9980                 region.imageBlit = imageBlit;
9981                 params.regions.push_back(region);
9982         }
9983
9984         addBlittingImageSimpleTests(group, params);
9985 }
9986
9987 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
9988 {
9989         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
9990         const deInt32   imageDepth              = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
9991         const deInt32   srcDepthOffset  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
9992         const deInt32   srcDepthSize    = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
9993         params.src.image.extent                 = defaultExtent;
9994         params.dst.image.extent                 = defaultExtent;
9995         params.src.image.extent.depth   = imageDepth;
9996         params.dst.image.extent.depth   = imageDepth;
9997
9998         {
9999                 const VkImageBlit imageBlit =
10000                 {
10001                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10002                         {
10003                                 {defaultFourthSize, defaultFourthSize, srcDepthOffset},
10004                                 {defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
10005                         },                                      // VkOffset3D                                   srcOffsets[2];
10006
10007                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10008                         {
10009                                 {0, 0, 0},
10010                                 {defaultSize, defaultSize, imageDepth}
10011                         }                                       // VkOffset3D                                   dstOffset[2];
10012                 };
10013
10014                 CopyRegion region;
10015                 region.imageBlit = imageBlit;
10016                 params.regions.push_back(region);
10017         }
10018
10019         addBlittingImageSimpleTests(group, params);
10020 }
10021
10022 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
10023 {
10024         DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10025         const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
10026         params.src.image.extent = defaultExtent;
10027         params.dst.image.extent = defaultExtent;
10028
10029         if (is3dBlit)
10030         {
10031                 params.src.image.extent.depth = defaultSize;
10032                 params.dst.image.extent.depth = defaultSize;
10033         }
10034
10035         {
10036                 CopyRegion region;
10037                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
10038                 {
10039                         const VkImageBlit imageBlit =
10040                         {
10041                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10042                                 {
10043                                         {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
10044                                         {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
10045                                 },                                      // VkOffset3D                                   srcOffsets[2];
10046
10047                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10048                                 {
10049                                         {i, i, is3dBlit ? i : 0},
10050                                         {i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
10051                                 }                                       // VkOffset3D                                   dstOffset[2];
10052                         };
10053                         region.imageBlit = imageBlit;
10054                         params.regions.push_back(region);
10055                 }
10056         }
10057
10058         addBlittingImageSimpleTests(group, params);
10059 }
10060
10061 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10062 {
10063         TestParams params;
10064         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
10065         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10066         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10067         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10068         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10069         params.allocationKind                           = allocationKind;
10070         params.extensionUse                                     = extensionUse;
10071         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10072         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10073         addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10074         addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
10075         addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
10076         addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
10077         addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10078         addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10079         addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10080         addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10081         addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10082
10083         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
10084         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
10085         addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10086         addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
10087         addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
10088         addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
10089         addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
10090         addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10091         addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10092         addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10093         addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10094         addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10095 }
10096
10097 enum FilterMaskBits
10098 {
10099         FILTER_MASK_NEAREST     = 0,                    // Always tested.
10100         FILTER_MASK_LINEAR      = (1u << 0),
10101         FILTER_MASK_CUBIC       = (1u << 1),
10102 };
10103
10104 using FilterMask = deUint32;
10105
10106 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
10107 {
10108         FilterMask mask = FILTER_MASK_NEAREST;
10109
10110         if (!onlyNearest)
10111         {
10112                 mask |= FILTER_MASK_LINEAR;
10113                 if (!discardCubicFilter)
10114                         mask |= FILTER_MASK_CUBIC;
10115         }
10116
10117         return mask;
10118 }
10119
10120 struct BlitColorTestParams
10121 {
10122         TestParams              params;
10123         const VkFormat* compatibleFormats;
10124         FilterMask              testFilters;
10125 };
10126
10127 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
10128 {
10129         bool result = true;
10130
10131         if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
10132         {
10133                 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
10134
10135                 result =
10136                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
10137                         de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
10138         }
10139
10140         return result;
10141 }
10142
10143 const VkFormat  linearOtherImageFormatsToTest[] =
10144 {
10145         // From compatibleFormats8Bit
10146         VK_FORMAT_R4G4_UNORM_PACK8,
10147         VK_FORMAT_R8_SRGB,
10148
10149         // From compatibleFormats16Bit
10150         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10151         VK_FORMAT_R16_SFLOAT,
10152
10153         // From compatibleFormats24Bit
10154         VK_FORMAT_R8G8B8_UNORM,
10155         VK_FORMAT_B8G8R8_SRGB,
10156
10157         // From compatibleFormats32Bit
10158         VK_FORMAT_R8G8B8A8_UNORM,
10159         VK_FORMAT_R32_SFLOAT,
10160
10161         // From compatibleFormats48Bit
10162         VK_FORMAT_R16G16B16_UNORM,
10163         VK_FORMAT_R16G16B16_SFLOAT,
10164
10165         // From compatibleFormats64Bit
10166         VK_FORMAT_R16G16B16A16_UNORM,
10167         VK_FORMAT_R64_SFLOAT,
10168
10169         // From compatibleFormats96Bit
10170         VK_FORMAT_R32G32B32_UINT,
10171         VK_FORMAT_R32G32B32_SFLOAT,
10172
10173         // From compatibleFormats128Bit
10174         VK_FORMAT_R32G32B32A32_UINT,
10175         VK_FORMAT_R64G64_SFLOAT,
10176
10177         // From compatibleFormats192Bit
10178         VK_FORMAT_R64G64B64_UINT,
10179         VK_FORMAT_R64G64B64_SFLOAT,
10180
10181         // From compatibleFormats256Bit
10182         VK_FORMAT_R64G64B64A64_UINT,
10183         VK_FORMAT_R64G64B64A64_SFLOAT,
10184 };
10185
10186 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
10187 {
10188         switch (tiling)
10189         {
10190                 case VK_IMAGE_TILING_OPTIMAL:
10191                         return getImageLayoutCaseName(layout);
10192                 case VK_IMAGE_TILING_LINEAR:
10193                         return "linear";
10194                 default:
10195                         DE_ASSERT(false);
10196                         return "";
10197         }
10198 }
10199
10200 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10201 {
10202         tcu::TestContext& testCtx                               = group->getTestContext();
10203
10204         FormatSet linearOtherImageFormatsToTestSet;
10205         const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
10206         for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
10207                 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
10208
10209         const VkImageTiling blitSrcTilings[]    =
10210         {
10211                 VK_IMAGE_TILING_OPTIMAL,
10212                 VK_IMAGE_TILING_LINEAR,
10213         };
10214         const VkImageLayout blitSrcLayouts[]    =
10215         {
10216                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10217                 VK_IMAGE_LAYOUT_GENERAL
10218         };
10219         const VkImageTiling blitDstTilings[]    =
10220         {
10221                 VK_IMAGE_TILING_OPTIMAL,
10222                 VK_IMAGE_TILING_LINEAR,
10223         };
10224         const VkImageLayout blitDstLayouts[]    =
10225         {
10226                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10227                 VK_IMAGE_LAYOUT_GENERAL
10228         };
10229
10230         for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
10231         {
10232                 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
10233
10234                 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10235                 {
10236                         testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
10237
10238                         // 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
10239                         if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
10240                                 continue;
10241
10242                         for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
10243                         {
10244                                 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
10245
10246                                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10247                                 {
10248                                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
10249
10250                                         // 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
10251                                         if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
10252                                                 continue;
10253
10254                                         if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
10255                                             (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
10256                                                 continue;
10257
10258                                         testParams.params.filter                        = VK_FILTER_NEAREST;
10259                                         const std::string testName                      = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
10260                                                                                                                   getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10261                                         const std::string description           = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
10262                                                                                                                   " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10263                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
10264
10265                                         if (testParams.testFilters & FILTER_MASK_LINEAR)
10266                                         {
10267                                                 testParams.params.filter = VK_FILTER_LINEAR;
10268                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
10269                                         }
10270
10271                                         if (testParams.testFilters & FILTER_MASK_CUBIC)
10272                                         {
10273                                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
10274                                                 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
10275                                         }
10276
10277                                         if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
10278                                         {
10279                                                 const struct
10280                                                 {
10281                                                         FillMode        mode;
10282                                                         const char*     name;
10283                                                 } modeList[] =
10284                                                 {
10285                                                         { FILL_MODE_BLUE_RED_X, "x" },
10286                                                         { FILL_MODE_BLUE_RED_Y, "y" },
10287                                                         { FILL_MODE_BLUE_RED_Z, "z" },
10288                                                 };
10289
10290                                                 auto otherParams = testParams;
10291                                                 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
10292
10293                                                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
10294                                                 {
10295                                                         otherParams.params.src.image.fillMode = modeList[i].mode;
10296
10297                                                         otherParams.params.filter = VK_FILTER_LINEAR;
10298                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
10299
10300                                                         otherParams.params.filter = VK_FILTER_NEAREST;
10301                                                         group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
10302                                                 }
10303                                         }
10304                                 }
10305                         }
10306                 }
10307         }
10308 }
10309
10310 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10311 {
10312         VkFormat srcFormat = testParams.params.src.image.format;
10313
10314         if (testParams.compatibleFormats)
10315         {
10316                 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
10317                 {
10318                         testParams.params.dst.image.format      = testParams.compatibleFormats[dstFormatIndex];
10319                         if (!isSupportedByFramework(testParams.params.dst.image.format))
10320                                 continue;
10321
10322                         if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
10323                                 continue;
10324
10325                         const std::string description   = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
10326                         addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10327                 }
10328         }
10329
10330         // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
10331         // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
10332         // as it is not on compatibleFormats list
10333         if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
10334         {
10335                 testParams.params.dst.image.format = srcFormat;
10336
10337                 const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
10338                 addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10339         }
10340 }
10341
10342 const VkFormat  compatibleFormatsUInts[]        =
10343 {
10344         VK_FORMAT_R8_UINT,
10345         VK_FORMAT_R8G8_UINT,
10346         VK_FORMAT_R8G8B8_UINT,
10347         VK_FORMAT_B8G8R8_UINT,
10348         VK_FORMAT_R8G8B8A8_UINT,
10349         VK_FORMAT_B8G8R8A8_UINT,
10350         VK_FORMAT_A8B8G8R8_UINT_PACK32,
10351         VK_FORMAT_A2R10G10B10_UINT_PACK32,
10352         VK_FORMAT_A2B10G10R10_UINT_PACK32,
10353         VK_FORMAT_R16_UINT,
10354         VK_FORMAT_R16G16_UINT,
10355         VK_FORMAT_R16G16B16_UINT,
10356         VK_FORMAT_R16G16B16A16_UINT,
10357         VK_FORMAT_R32_UINT,
10358         VK_FORMAT_R32G32_UINT,
10359         VK_FORMAT_R32G32B32_UINT,
10360         VK_FORMAT_R32G32B32A32_UINT,
10361         VK_FORMAT_R64_UINT,
10362         VK_FORMAT_R64G64_UINT,
10363         VK_FORMAT_R64G64B64_UINT,
10364         VK_FORMAT_R64G64B64A64_UINT,
10365
10366         VK_FORMAT_UNDEFINED
10367 };
10368 const VkFormat  compatibleFormatsSInts[]        =
10369 {
10370         VK_FORMAT_R8_SINT,
10371         VK_FORMAT_R8G8_SINT,
10372         VK_FORMAT_R8G8B8_SINT,
10373         VK_FORMAT_B8G8R8_SINT,
10374         VK_FORMAT_R8G8B8A8_SINT,
10375         VK_FORMAT_B8G8R8A8_SINT,
10376         VK_FORMAT_A8B8G8R8_SINT_PACK32,
10377         VK_FORMAT_A2R10G10B10_SINT_PACK32,
10378         VK_FORMAT_A2B10G10R10_SINT_PACK32,
10379         VK_FORMAT_R16_SINT,
10380         VK_FORMAT_R16G16_SINT,
10381         VK_FORMAT_R16G16B16_SINT,
10382         VK_FORMAT_R16G16B16A16_SINT,
10383         VK_FORMAT_R32_SINT,
10384         VK_FORMAT_R32G32_SINT,
10385         VK_FORMAT_R32G32B32_SINT,
10386         VK_FORMAT_R32G32B32A32_SINT,
10387         VK_FORMAT_R64_SINT,
10388         VK_FORMAT_R64G64_SINT,
10389         VK_FORMAT_R64G64B64_SINT,
10390         VK_FORMAT_R64G64B64A64_SINT,
10391
10392         VK_FORMAT_UNDEFINED
10393 };
10394 const VkFormat  compatibleFormatsFloats[]       =
10395 {
10396         VK_FORMAT_R4G4_UNORM_PACK8,
10397         VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10398         VK_FORMAT_B4G4R4A4_UNORM_PACK16,
10399         VK_FORMAT_R5G6B5_UNORM_PACK16,
10400         VK_FORMAT_B5G6R5_UNORM_PACK16,
10401         VK_FORMAT_R5G5B5A1_UNORM_PACK16,
10402         VK_FORMAT_B5G5R5A1_UNORM_PACK16,
10403         VK_FORMAT_A1R5G5B5_UNORM_PACK16,
10404         VK_FORMAT_R8_UNORM,
10405         VK_FORMAT_R8_SNORM,
10406         VK_FORMAT_R8_USCALED,
10407         VK_FORMAT_R8_SSCALED,
10408         VK_FORMAT_R8G8_UNORM,
10409         VK_FORMAT_R8G8_SNORM,
10410         VK_FORMAT_R8G8_USCALED,
10411         VK_FORMAT_R8G8_SSCALED,
10412         VK_FORMAT_R8G8B8_UNORM,
10413         VK_FORMAT_R8G8B8_SNORM,
10414         VK_FORMAT_R8G8B8_USCALED,
10415         VK_FORMAT_R8G8B8_SSCALED,
10416         VK_FORMAT_B8G8R8_UNORM,
10417         VK_FORMAT_B8G8R8_SNORM,
10418         VK_FORMAT_B8G8R8_USCALED,
10419         VK_FORMAT_B8G8R8_SSCALED,
10420         VK_FORMAT_R8G8B8A8_UNORM,
10421         VK_FORMAT_R8G8B8A8_SNORM,
10422         VK_FORMAT_R8G8B8A8_USCALED,
10423         VK_FORMAT_R8G8B8A8_SSCALED,
10424         VK_FORMAT_B8G8R8A8_UNORM,
10425         VK_FORMAT_B8G8R8A8_SNORM,
10426         VK_FORMAT_B8G8R8A8_USCALED,
10427         VK_FORMAT_B8G8R8A8_SSCALED,
10428         VK_FORMAT_A8B8G8R8_UNORM_PACK32,
10429         VK_FORMAT_A8B8G8R8_SNORM_PACK32,
10430         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10431         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10432         VK_FORMAT_A2R10G10B10_UNORM_PACK32,
10433         VK_FORMAT_A2R10G10B10_SNORM_PACK32,
10434         VK_FORMAT_A2R10G10B10_USCALED_PACK32,
10435         VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
10436         VK_FORMAT_A2B10G10R10_UNORM_PACK32,
10437         VK_FORMAT_A2B10G10R10_SNORM_PACK32,
10438         VK_FORMAT_A2B10G10R10_USCALED_PACK32,
10439         VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
10440         VK_FORMAT_R16_UNORM,
10441         VK_FORMAT_R16_SNORM,
10442         VK_FORMAT_R16_USCALED,
10443         VK_FORMAT_R16_SSCALED,
10444         VK_FORMAT_R16_SFLOAT,
10445         VK_FORMAT_R16G16_UNORM,
10446         VK_FORMAT_R16G16_SNORM,
10447         VK_FORMAT_R16G16_USCALED,
10448         VK_FORMAT_R16G16_SSCALED,
10449         VK_FORMAT_R16G16_SFLOAT,
10450         VK_FORMAT_R16G16B16_UNORM,
10451         VK_FORMAT_R16G16B16_SNORM,
10452         VK_FORMAT_R16G16B16_USCALED,
10453         VK_FORMAT_R16G16B16_SSCALED,
10454         VK_FORMAT_R16G16B16_SFLOAT,
10455         VK_FORMAT_R16G16B16A16_UNORM,
10456         VK_FORMAT_R16G16B16A16_SNORM,
10457         VK_FORMAT_R16G16B16A16_USCALED,
10458         VK_FORMAT_R16G16B16A16_SSCALED,
10459         VK_FORMAT_R16G16B16A16_SFLOAT,
10460         VK_FORMAT_R32_SFLOAT,
10461         VK_FORMAT_R32G32_SFLOAT,
10462         VK_FORMAT_R32G32B32_SFLOAT,
10463         VK_FORMAT_R32G32B32A32_SFLOAT,
10464         VK_FORMAT_R64_SFLOAT,
10465         VK_FORMAT_R64G64_SFLOAT,
10466         VK_FORMAT_R64G64B64_SFLOAT,
10467         VK_FORMAT_R64G64B64A64_SFLOAT,
10468         VK_FORMAT_B10G11R11_UFLOAT_PACK32,
10469         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10470
10471         VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
10472         VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
10473
10474         VK_FORMAT_UNDEFINED
10475 };
10476
10477 const VkFormat  compressedFormatsFloats[] =
10478 {
10479         VK_FORMAT_BC1_RGB_UNORM_BLOCK,
10480         VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
10481         VK_FORMAT_BC2_UNORM_BLOCK,
10482         VK_FORMAT_BC3_UNORM_BLOCK,
10483         VK_FORMAT_BC4_UNORM_BLOCK,
10484         VK_FORMAT_BC4_SNORM_BLOCK,
10485         VK_FORMAT_BC5_UNORM_BLOCK,
10486         VK_FORMAT_BC5_SNORM_BLOCK,
10487         VK_FORMAT_BC6H_UFLOAT_BLOCK,
10488         VK_FORMAT_BC6H_SFLOAT_BLOCK,
10489         VK_FORMAT_BC7_UNORM_BLOCK,
10490         VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
10491         VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
10492         VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
10493         VK_FORMAT_EAC_R11_UNORM_BLOCK,
10494         VK_FORMAT_EAC_R11_SNORM_BLOCK,
10495         VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
10496         VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
10497
10498         VK_FORMAT_UNDEFINED
10499 };
10500
10501 const VkFormat  compatibleFormatsSrgb[]         =
10502 {
10503         VK_FORMAT_R8_SRGB,
10504         VK_FORMAT_R8G8_SRGB,
10505         VK_FORMAT_R8G8B8_SRGB,
10506         VK_FORMAT_B8G8R8_SRGB,
10507         VK_FORMAT_R8G8B8A8_SRGB,
10508         VK_FORMAT_B8G8R8A8_SRGB,
10509         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10510
10511         VK_FORMAT_UNDEFINED
10512 };
10513
10514 const VkFormat  compressedFormatsSrgb[] =
10515 {
10516         VK_FORMAT_BC1_RGB_SRGB_BLOCK,
10517         VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
10518         VK_FORMAT_BC2_SRGB_BLOCK,
10519         VK_FORMAT_BC3_SRGB_BLOCK,
10520         VK_FORMAT_BC7_SRGB_BLOCK,
10521         VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
10522         VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
10523         VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
10524
10525         VK_FORMAT_UNDEFINED
10526 };
10527
10528 const VkFormat  dedicatedAllocationBlittingFormatsToTest[]      =
10529 {
10530         // compatibleFormatsUInts
10531         VK_FORMAT_R8_UINT,
10532         VK_FORMAT_R64G64B64A64_UINT,
10533
10534         // compatibleFormatsSInts
10535         VK_FORMAT_R8_SINT,
10536         VK_FORMAT_R64G64B64A64_SINT,
10537
10538         // compatibleFormatsFloats
10539         VK_FORMAT_R4G4_UNORM_PACK8,
10540         VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10541
10542         // compatibleFormatsSrgb
10543         VK_FORMAT_R8_SRGB,
10544         VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10545 };
10546
10547 // skip cubic filtering test for the following data formats
10548 const FormatSet onlyNearestAndLinearFormatsToTest =
10549 {
10550         VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10551         VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10552         VK_FORMAT_A8B8G8R8_UINT_PACK32,
10553         VK_FORMAT_A8B8G8R8_SINT_PACK32
10554 };
10555
10556 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight)
10557 {
10558         CopyRegion                              region;
10559         std::vector<CopyRegion> regionsVector;
10560         deInt32                                 fourthOfSrcWidth        = srcWidth / 4;
10561         deInt32                                 fourthOfSrcHeight       = srcHeight / 4;
10562
10563         // to the top of resulting image copy whole source image but with increasingly smaller sizes
10564         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
10565         {
10566                 region.imageBlit =
10567                 {
10568                         defaultSourceLayer,                                             // VkImageSubresourceLayers             srcSubresource;
10569                         {
10570                                 {0, 0, 0},
10571                                 {srcWidth, srcHeight, 1}
10572                         },                                                                              // VkOffset3D                                   srcOffsets[2];
10573
10574                         defaultSourceLayer,                                             // VkImageSubresourceLayers             dstSubresource;
10575                         {
10576                                 {i, 0, 0},
10577                                 {i + defaultFourthSize / j, defaultFourthSize / j, 1}
10578                         }                                                                               // VkOffset3D                                   dstOffset[2];
10579                 };
10580                 regionsVector.push_back(region);
10581         }
10582
10583         // to the bottom of resulting image copy parts of source image
10584         int srcX = 0;
10585         int srcY = 0;
10586         for (int i = 0; i < defaultSize; i += defaultFourthSize)
10587         {
10588                 region.imageBlit =
10589                 {
10590                         defaultSourceLayer,                                             // VkImageSubresourceLayers             srcSubresource;
10591                         {
10592                                 {srcX, srcY, 0},
10593                                 {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
10594                         },                                                                              // VkOffset3D                                   srcOffsets[2];
10595
10596                         defaultSourceLayer,                                             // VkImageSubresourceLayers             dstSubresource;
10597                         {
10598                                 {i, defaultSize / 2, 0},
10599                                 {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
10600                         }                                                                               // VkOffset3D                                   dstOffset[2];
10601                 };
10602                 regionsVector.push_back(region);
10603                 srcX += fourthOfSrcWidth;
10604                 srcY += fourthOfSrcHeight;
10605         }
10606
10607         return regionsVector;
10608 }
10609
10610 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10611 {
10612         const struct {
10613                 const VkFormat* sourceFormats;
10614                 const VkFormat* destinationFormats;
10615                 const bool              onlyNearest;
10616         }       colorImageFormatsToTestBlit[] =
10617         {
10618                 { compatibleFormatsUInts,       compatibleFormatsUInts,         true    },
10619                 { compatibleFormatsSInts,       compatibleFormatsSInts,         true    },
10620                 { compatibleFormatsFloats,      compatibleFormatsFloats,        false   },
10621                 { compressedFormatsFloats,      compatibleFormatsFloats,        false   },
10622                 { compatibleFormatsSrgb,        compatibleFormatsSrgb,          false   },
10623                 { compressedFormatsSrgb,        compatibleFormatsSrgb,          false   },
10624         };
10625
10626         const int       numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
10627
10628         if (allocationKind == ALLOCATION_KIND_DEDICATED)
10629         {
10630                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
10631                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
10632                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
10633         }
10634
10635         // 2D tests.
10636         {
10637                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
10638
10639                 TestParams      params;
10640                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
10641                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
10642                 params.src.image.extent         = defaultExtent;
10643                 params.dst.image.extent         = defaultExtent;
10644                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10645                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10646                 params.allocationKind           = allocationKind;
10647                 params.extensionUse                     = extensionUse;
10648
10649                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10650                 {
10651                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10652                         const VkFormat* destinationFormats      = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
10653                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10654                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10655                         {
10656                                 VkFormat srcFormat              = sourceFormats[srcFormatIndex];
10657                                 params.src.image.format = srcFormat;
10658
10659                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
10660
10661                                 params.regions                  = create2DCopyRegions(64, 64);
10662
10663                                 const VkOffset3D&       srcImageSize    = params.regions[0].imageBlit.srcOffsets[1];
10664                                 VkExtent3D&                     srcImageExtent  = params.src.image.extent;
10665                                 srcImageExtent.width    = srcImageSize.x;
10666                                 srcImageExtent.height   = srcImageSize.y;
10667
10668                                 BlitColorTestParams testParams
10669                                 {
10670                                         params,
10671                                         destinationFormats,
10672                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10673                                 };
10674
10675                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10676                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10677                         }
10678                 }
10679
10680                 group->addChild(subGroup.release());
10681         }
10682
10683         // 1D tests.
10684         {
10685                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
10686
10687                 TestParams      params;
10688                 params.src.image.imageType      = VK_IMAGE_TYPE_1D;
10689                 params.dst.image.imageType      = VK_IMAGE_TYPE_1D;
10690                 params.src.image.extent         = default1dExtent;
10691                 params.dst.image.extent         = default1dExtent;
10692                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10693                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10694                 params.allocationKind           = allocationKind;
10695                 params.extensionUse                     = extensionUse;
10696
10697                 CopyRegion      region;
10698                 for (int i = 0; i < defaultSize; i += defaultSize / 2)
10699                 {
10700                         const VkImageBlit                       imageBlit       =
10701                         {
10702                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10703                                 {
10704                                         {0, 0, 0},
10705                                         {defaultSize, 1, 1}
10706                                 },                                      // VkOffset3D                                   srcOffsets[2];
10707
10708                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10709                                 {
10710                                         {i, 0, 0},
10711                                         {i + defaultFourthSize, 1, 1}
10712                                 }                                       // VkOffset3D                                   dstOffset[2];
10713                         };
10714                         region.imageBlit        = imageBlit;
10715                         params.regions.push_back(region);
10716                 }
10717
10718                 {
10719                         const VkImageBlit                       imageBlit       =
10720                         {
10721                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10722                                 {
10723                                         {0, 0, 0},
10724                                         {defaultFourthSize, 1, 1}
10725                                 },                                      // VkOffset3D                                   srcOffsets[2];
10726
10727                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10728                                 {
10729                                         {defaultFourthSize, 0, 0},
10730                                         {2 * defaultFourthSize, 1, 1}
10731                                 }                                       // VkOffset3D                                   dstOffset[2];
10732                         };
10733                         region.imageBlit        = imageBlit;
10734                         params.regions.push_back(region);
10735                 }
10736
10737                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10738                 {
10739                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10740                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10741                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10742                         {
10743                                 params.src.image.format = sourceFormats[srcFormatIndex];
10744                                 if (!isSupportedByFramework(params.src.image.format))
10745                                         continue;
10746
10747                                 // Cubic filtering can only be used with 2D images.
10748                                 const bool onlyNearestAndLinear = true;
10749
10750                                 BlitColorTestParams testParams
10751                                 {
10752                                         params,
10753                                         nullptr,
10754                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10755                                 };
10756
10757                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10758                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10759                         }
10760                 }
10761
10762                 group->addChild(subGroup.release());
10763         }
10764
10765         // 3D tests. Note we use smaller dimensions here for performance reasons.
10766         {
10767                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
10768
10769                 TestParams      params;
10770                 params.src.image.imageType      = VK_IMAGE_TYPE_3D;
10771                 params.dst.image.imageType      = VK_IMAGE_TYPE_3D;
10772                 params.src.image.extent         = default3dExtent;
10773                 params.dst.image.extent         = default3dExtent;
10774                 params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10775                 params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
10776                 params.allocationKind           = allocationKind;
10777                 params.extensionUse                     = extensionUse;
10778
10779                 CopyRegion      region;
10780                 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
10781                 {
10782                         const VkImageBlit                       imageBlit       =
10783                         {
10784                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10785                                 {
10786                                         {0, 0, 0},
10787                                         {defaultFourthSize, defaultFourthSize, defaultFourthSize}
10788                                 },                                      // VkOffset3D                                   srcOffsets[2];
10789
10790                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10791                                 {
10792                                         {i, 0, i},
10793                                         {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
10794                                 }                                       // VkOffset3D                                   dstOffset[2];
10795                         };
10796                         region.imageBlit        = imageBlit;
10797                         params.regions.push_back(region);
10798                 }
10799                 for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
10800                 {
10801                         const VkImageBlit                       imageBlit       =
10802                         {
10803                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
10804                                 {
10805                                         {i, i, i},
10806                                         {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
10807                                 },                                      // VkOffset3D                                   srcOffsets[2];
10808
10809                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
10810                                 {
10811                                         {i, defaultFourthSize / 2, i},
10812                                         {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
10813                                 }                                       // VkOffset3D                                   dstOffset[2];
10814                         };
10815                         region.imageBlit        = imageBlit;
10816                         params.regions.push_back(region);
10817                 }
10818
10819                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
10820                 {
10821                         const VkFormat* sourceFormats           = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
10822                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
10823                         for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10824                         {
10825                                 params.src.image.format = sourceFormats[srcFormatIndex];
10826                                 if (!isSupportedByFramework(params.src.image.format))
10827                                         continue;
10828
10829                                 // Cubic filtering can only be used with 2D images.
10830                                 const bool onlyNearestAndLinear = true;
10831
10832                                 BlitColorTestParams testParams
10833                                 {
10834                                         params,
10835                                         nullptr,
10836                                         makeFilterMask(onlyNearest, onlyNearestAndLinear)
10837                                 };
10838
10839                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
10840                                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
10841                         }
10842                 }
10843
10844                 group->addChild(subGroup.release());
10845         }
10846 }
10847
10848 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
10849 {
10850         const VkImageLayout blitSrcLayouts[]    =
10851         {
10852                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10853                 VK_IMAGE_LAYOUT_GENERAL
10854         };
10855         const VkImageLayout blitDstLayouts[]    =
10856         {
10857                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10858                 VK_IMAGE_LAYOUT_GENERAL
10859         };
10860
10861         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10862         {
10863                 params.src.image.operationLayout        = blitSrcLayouts[srcLayoutNdx];
10864
10865                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10866                 {
10867                         params.dst.image.operationLayout        = blitDstLayouts[dstLayoutNdx];
10868                         params.filter                                           = VK_FILTER_NEAREST;
10869
10870                         const std::string testName              = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
10871                                                                                           getImageLayoutCaseName(params.dst.image.operationLayout);
10872                         const std::string description   = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
10873                                                                                           " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
10874
10875                         group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
10876                 }
10877         }
10878 }
10879
10880 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10881 {
10882         const VkFormat  depthAndStencilFormats[]        =
10883         {
10884                 VK_FORMAT_D16_UNORM,
10885                 VK_FORMAT_X8_D24_UNORM_PACK32,
10886                 VK_FORMAT_D32_SFLOAT,
10887                 VK_FORMAT_S8_UINT,
10888                 VK_FORMAT_D16_UNORM_S8_UINT,
10889                 VK_FORMAT_D24_UNORM_S8_UINT,
10890                 VK_FORMAT_D32_SFLOAT_S8_UINT,
10891         };
10892
10893         const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
10894         const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
10895         const VkImageSubresourceLayers  defaultDSSourceLayer            = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
10896
10897         // 2D tests
10898         {
10899                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
10900
10901                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
10902                 {
10903                         TestParams      params;
10904                         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
10905                         params.src.image.extent                         = defaultExtent;
10906                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10907                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
10908                         params.dst.image.extent                         = defaultExtent;
10909                         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
10910                         params.dst.image.format                         = params.src.image.format;
10911                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
10912                         params.allocationKind                           = allocationKind;
10913                         params.extensionUse                                     = extensionUse;
10914                         params.separateDepthStencilLayouts      = DE_FALSE;
10915
10916                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10917                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10918
10919                         CopyRegion      region;
10920                         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
10921                         {
10922                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
10923                                 const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
10924                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
10925                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
10926
10927                                 if (hasDepth)
10928                                 {
10929                                         const VkImageBlit                       imageBlit       =
10930                                         {
10931                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
10932                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
10933                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
10934                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
10935                                         };
10936                                         region.imageBlit        = imageBlit;
10937                                         params.regions.push_back(region);
10938                                 }
10939                                 if (hasStencil)
10940                                 {
10941                                         const VkImageBlit                       imageBlit       =
10942                                         {
10943                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
10944                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
10945                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
10946                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
10947                                         };
10948                                         region.imageBlit        = imageBlit;
10949                                         params.regions.push_back(region);
10950                                 }
10951                         }
10952                         for (int i = 0; i < defaultSize; i += defaultFourthSize)
10953                         {
10954                                 const VkOffset3D        srcOffset0      = {i, i, 0};
10955                                 const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
10956                                 const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
10957                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
10958
10959                                 if (hasDepth)
10960                                 {
10961                                         const VkImageBlit                       imageBlit       =
10962                                         {
10963                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
10964                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
10965                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
10966                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
10967                                         };
10968                                         region.imageBlit        = imageBlit;
10969                                         params.regions.push_back(region);
10970                                 }
10971                                 if (hasStencil)
10972                                 {
10973                                         const VkImageBlit                       imageBlit       =
10974                                         {
10975                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
10976                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
10977                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
10978                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
10979                                         };
10980                                         region.imageBlit        = imageBlit;
10981                                         params.regions.push_back(region);
10982                                 }
10983                                 if (hasDepth && hasStencil)
10984                                 {
10985                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultFourthSize, 0};
10986                                         const VkOffset3D                        dstDSOffset1    = {i + defaultFourthSize, defaultSize, 1};
10987                                         const VkImageBlit                       imageBlit       =
10988                                         {
10989                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
10990                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
10991                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
10992                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
10993                                         };
10994                                         region.imageBlit        = imageBlit;
10995                                         params.regions.push_back(region);
10996                                 }
10997                         }
10998
10999                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11000                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11001                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11002                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11003
11004                         if (hasDepth && hasStencil)
11005                         {
11006                                 params.separateDepthStencilLayouts      = DE_TRUE;
11007                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11008                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11009                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11010                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11011                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11012                         }
11013                 }
11014
11015                 group->addChild(subGroup.release());
11016         }
11017
11018         // 1D tests
11019         {
11020                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11021
11022                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11023                 {
11024                         TestParams      params;
11025                         params.src.image.imageType                      = VK_IMAGE_TYPE_1D;
11026                         params.dst.image.imageType                      = VK_IMAGE_TYPE_1D;
11027                         params.src.image.extent                         = default1dExtent;
11028                         params.dst.image.extent                         = default1dExtent;
11029                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
11030                         params.dst.image.format                         = params.src.image.format;
11031                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11032                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11033                         params.allocationKind                           = allocationKind;
11034                         params.extensionUse                                     = extensionUse;
11035
11036                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11037                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11038
11039                         CopyRegion      region;
11040                         for (int i = 0; i < defaultSize; i += defaultSize / 2)
11041                         {
11042                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11043                                 const VkOffset3D        srcOffset1      = {defaultSize, 1, 1};
11044                                 const VkOffset3D        dstOffset0      = {i, 0, 0};
11045                                 const VkOffset3D        dstOffset1      = {i + defaultFourthSize, 1, 1};
11046
11047                                 if (hasDepth)
11048                                 {
11049                                         const VkImageBlit                       imageBlit       =
11050                                         {
11051                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11052                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11053                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11054                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11055                                         };
11056                                         region.imageBlit        = imageBlit;
11057                                         params.regions.push_back(region);
11058                                 }
11059                                 if (hasStencil)
11060                                 {
11061                                         const VkImageBlit                       imageBlit       =
11062                                         {
11063                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11064                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11065                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11066                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11067                                         };
11068                                         region.imageBlit        = imageBlit;
11069                                         params.regions.push_back(region);
11070                                 }
11071                         }
11072
11073                         {
11074                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11075                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, 1, 1};
11076                                 const VkOffset3D        dstOffset0      = {defaultFourthSize, 0, 0};
11077                                 const VkOffset3D        dstOffset1      = {2 * defaultFourthSize, 1, 1};
11078
11079                                 if (hasDepth)
11080                                 {
11081                                         const VkImageBlit                       imageBlit       =
11082                                         {
11083                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11084                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11085                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11086                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11087                                         };
11088                                         region.imageBlit        = imageBlit;
11089                                         params.regions.push_back(region);
11090                                 }
11091                                 if (hasStencil)
11092                                 {
11093                                         const VkImageBlit                       imageBlit       =
11094                                         {
11095                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11096                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11097                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11098                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11099                                         };
11100                                         region.imageBlit        = imageBlit;
11101                                         params.regions.push_back(region);
11102                                 }
11103                                 if (hasDepth && hasStencil)
11104                                 {
11105                                         const VkOffset3D                        dstDSOffset0    = {3 * defaultFourthSize, 0, 0};
11106                                         const VkOffset3D                        dstDSOffset1    = {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
11107                                         const VkImageBlit                       imageBlit       =
11108                                         {
11109                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
11110                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11111                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
11112                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
11113                                         };
11114                                         region.imageBlit        = imageBlit;
11115                                         params.regions.push_back(region);
11116                                 }
11117                         }
11118
11119                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11120                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11121                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11122                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11123
11124                         if (hasDepth && hasStencil)
11125                         {
11126                                 params.separateDepthStencilLayouts      = DE_TRUE;
11127                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11128                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11129                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11130                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11131                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11132                         }
11133                 }
11134
11135                 group->addChild(subGroup.release());
11136         }
11137
11138         // 3D tests. Note we use smaller dimensions here for performance reasons.
11139         {
11140                 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11141
11142                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11143                 {
11144                         TestParams      params;
11145                         params.src.image.imageType                      = VK_IMAGE_TYPE_3D;
11146                         params.dst.image.imageType                      = VK_IMAGE_TYPE_3D;
11147                         params.src.image.extent                         = default3dExtent;
11148                         params.dst.image.extent                         = default3dExtent;
11149                         params.src.image.format                         = depthAndStencilFormats[compatibleFormatsIndex];
11150                         params.dst.image.format                         = params.src.image.format;
11151                         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11152                         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11153                         params.allocationKind                           = allocationKind;
11154                         params.extensionUse                                     = extensionUse;
11155
11156                         bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11157                         bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11158
11159                         CopyRegion      region;
11160                         for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11161                         {
11162                                 const VkOffset3D        srcOffset0      = {0, 0, 0};
11163                                 const VkOffset3D        srcOffset1      = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
11164                                 const VkOffset3D        dstOffset0      = {i, 0, i};
11165                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
11166
11167                                 if (hasDepth)
11168                                 {
11169                                         const VkImageBlit                       imageBlit       =
11170                                         {
11171                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11172                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11173                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11174                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11175                                         };
11176                                         region.imageBlit        = imageBlit;
11177                                         params.regions.push_back(region);
11178                                 }
11179                                 if (hasStencil)
11180                                 {
11181                                         const VkImageBlit                       imageBlit       =
11182                                         {
11183                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11184                                                 { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
11185                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11186                                                 { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
11187                                         };
11188                                         region.imageBlit        = imageBlit;
11189                                         params.regions.push_back(region);
11190                                 }
11191                         }
11192                         for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11193                         {
11194                                 const VkOffset3D        srcOffset0      = {i, i, i};
11195                                 const VkOffset3D        srcOffset1      = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
11196                                 const VkOffset3D        dstOffset0      = {i, defaultFourthSize / 2, i};
11197                                 const VkOffset3D        dstOffset1      = {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
11198
11199                                 if (hasDepth)
11200                                 {
11201                                         const VkImageBlit                       imageBlit       =
11202                                         {
11203                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
11204                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11205                                                 defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
11206                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11207                                         };
11208                                         region.imageBlit        = imageBlit;
11209                                         params.regions.push_back(region);
11210                                 }
11211                                 if (hasStencil)
11212                                 {
11213                                         const VkImageBlit                       imageBlit       =
11214                                         {
11215                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
11216                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11217                                                 defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
11218                                                 { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
11219                                         };
11220                                         region.imageBlit        = imageBlit;
11221                                         params.regions.push_back(region);
11222                                 }
11223                                 if (hasDepth && hasStencil)
11224                                 {
11225                                         const VkOffset3D                        dstDSOffset0    = {i, 3 * defaultSixteenthSize, i};
11226                                         const VkOffset3D                        dstDSOffset1    = {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
11227                                         const VkImageBlit                       imageBlit       =
11228                                         {
11229                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     srcSubresource;
11230                                                 { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
11231                                                 defaultDSSourceLayer,                   // VkImageSubresourceLayers     dstSubresource;
11232                                                 { dstDSOffset0, dstDSOffset1 }  // VkOffset3D                                   dstOffset[2];
11233                                         };
11234                                         region.imageBlit        = imageBlit;
11235                                         params.regions.push_back(region);
11236                                 }
11237                         }
11238
11239                         const std::string testName              = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11240                         const std::string description   = "Blit from " + getFormatCaseName(params.src.image.format) +
11241                                                                                         " to " + getFormatCaseName(params.dst.image.format);
11242                         addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11243
11244                         if (hasDepth && hasStencil)
11245                         {
11246                                 params.separateDepthStencilLayouts      = DE_TRUE;
11247                                 const std::string testName2             = getFormatCaseName(params.src.image.format) + "_" +
11248                                                                                                 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11249                                 const std::string description2  = "Blit from " + getFormatCaseName(params.src.image.format) +
11250                                                                                                 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11251                                 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11252                         }
11253                 }
11254
11255                 group->addChild(subGroup.release());
11256         }
11257 }
11258
11259 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
11260 {
11261         tcu::TestContext& testCtx                               = group->getTestContext();
11262
11263         const VkImageLayout blitSrcLayouts[]    =
11264         {
11265                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11266                 VK_IMAGE_LAYOUT_GENERAL
11267         };
11268         const VkImageLayout blitDstLayouts[]    =
11269         {
11270                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11271                 VK_IMAGE_LAYOUT_GENERAL
11272         };
11273
11274         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11275         {
11276                 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
11277                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11278                 {
11279                         testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
11280
11281                         testParams.params.filter                        = VK_FILTER_NEAREST;
11282                         const std::string testName                      = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
11283                                                                                                   getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11284                         const std::string description           = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
11285                                                                                                   " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11286                         group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
11287
11288                         if (testParams.testFilters & FILTER_MASK_LINEAR)
11289                         {
11290                                 testParams.params.filter = VK_FILTER_LINEAR;
11291                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
11292                         }
11293
11294                         if (testParams.testFilters & FILTER_MASK_CUBIC)
11295                         {
11296                                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
11297                                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
11298                         }
11299                 }
11300         }
11301 }
11302
11303 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11304 {
11305         const struct
11306         {
11307                 const VkFormat* const   compatibleFormats;
11308                 const bool                              onlyNearest;
11309         }       colorImageFormatsToTestBlit[]                   =
11310         {
11311                 { compatibleFormatsUInts,       true    },
11312                 { compatibleFormatsSInts,       true    },
11313                 { compatibleFormatsFloats,      false   },
11314                 { compatibleFormatsSrgb,        false   },
11315         };
11316
11317         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11318
11319         const int       layerCountsToTest[]                             =
11320         {
11321                 1,
11322                 6
11323         };
11324
11325         TestParams      params;
11326         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
11327         params.src.image.extent         = defaultExtent;
11328         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11329         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
11330         params.dst.image.extent         = defaultExtent;
11331         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11332         params.allocationKind           = allocationKind;
11333         params.extensionUse                     = extensionUse;
11334         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11335         params.singleCommand            = DE_TRUE;
11336
11337         CopyRegion      region;
11338         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11339         {
11340                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
11341                 destLayer.mipLevel = mipLevelNdx;
11342
11343                 const VkImageBlit                       imageBlit       =
11344                 {
11345                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
11346                         {
11347                                 {0, 0, 0},
11348                                 {defaultSize, defaultSize, 1}
11349                         },                                      // VkOffset3D                                   srcOffsets[2];
11350
11351                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
11352                         {
11353                                 {0, 0, 0},
11354                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11355                         }                                       // VkOffset3D                                   dstOffset[2];
11356                 };
11357                 region.imageBlit        = imageBlit;
11358                 params.regions.push_back(region);
11359         }
11360
11361         if (allocationKind == ALLOCATION_KIND_DEDICATED)
11362         {
11363                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11364                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11365                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11366         }
11367
11368         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11369         {
11370                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
11371                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
11372                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11373
11374                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11375
11376                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11377                 {
11378                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11379                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11380
11381                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11382                         {
11383                                 params.src.image.format = compatibleFormats[srcFormatIndex];
11384                                 params.dst.image.format = compatibleFormats[srcFormatIndex];
11385
11386                                 if (!isSupportedByFramework(params.src.image.format))
11387                                         continue;
11388
11389                                 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11390
11391                                 const std::string description   = "Blit source format " + getFormatCaseName(params.src.image.format);
11392
11393                                 BlitColorTestParams testParams;
11394                                 testParams.params                               = params;
11395                                 testParams.compatibleFormats    = compatibleFormats;
11396                                 testParams.testFilters                  = makeFilterMask(onlyNearest, onlyNearestAndLinear);
11397
11398                                 testParams.params.src.image.extent.depth = layerCount;
11399                                 testParams.params.dst.image.extent.depth = layerCount;
11400
11401                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11402                                 {
11403                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11404                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11405                                 }
11406
11407                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11408                         }
11409                 }
11410                 group->addChild(layerCountGroup.release());
11411         }
11412 }
11413
11414 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11415 {
11416         const struct
11417         {
11418                 const VkFormat* const   compatibleFormats;
11419                 const bool                              onlyNearest;
11420         }       colorImageFormatsToTestBlit[]                   =
11421         {
11422                 { compatibleFormatsUInts,       true    },
11423                 { compatibleFormatsSInts,       true    },
11424                 { compatibleFormatsFloats,      false   },
11425                 { compatibleFormatsSrgb,        false   },
11426         };
11427
11428         const int       numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11429
11430         const int       layerCountsToTest[]                             =
11431         {
11432                 1,
11433                 6
11434         };
11435
11436         TestParams      params;
11437         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
11438         params.src.image.extent         = defaultExtent;
11439         params.src.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11440         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
11441         params.dst.image.extent         = defaultExtent;
11442         params.dst.image.tiling         = VK_IMAGE_TILING_OPTIMAL;
11443         params.allocationKind           = allocationKind;
11444         params.extensionUse                     = extensionUse;
11445         params.mipLevels                        = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11446         params.singleCommand            = DE_FALSE;
11447
11448         CopyRegion      region;
11449         for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11450         {
11451                 VkImageSubresourceLayers        srcLayer        = defaultSourceLayer;
11452                 VkImageSubresourceLayers        destLayer       = defaultSourceLayer;
11453
11454                 srcLayer.mipLevel       = mipLevelNdx - 1u;
11455                 destLayer.mipLevel      = mipLevelNdx;
11456
11457                 const VkImageBlit                       imageBlit       =
11458                 {
11459                         srcLayer,                       // VkImageSubresourceLayers     srcSubresource;
11460                         {
11461                                 {0, 0, 0},
11462                                 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
11463                         },                                      // VkOffset3D                                   srcOffsets[2];
11464
11465                         destLayer,                      // VkImageSubresourceLayers     dstSubresource;
11466                         {
11467                                 {0, 0, 0},
11468                                 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11469                         }                                       // VkOffset3D                                   dstOffset[2];
11470                 };
11471                 region.imageBlit        = imageBlit;
11472                 params.regions.push_back(region);
11473         }
11474
11475         if (allocationKind == ALLOCATION_KIND_DEDICATED)
11476         {
11477                 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11478                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11479                         dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11480         }
11481
11482         for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11483         {
11484                 const int                                               layerCount              = layerCountsToTest[layerCountIndex];
11485                 const std::string                               layerGroupName  = "layercount_" + de::toString(layerCount);
11486                 const std::string                               layerGroupDesc  = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11487
11488                 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11489
11490                 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11491                 {
11492                         const VkFormat* compatibleFormats       = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11493                         const bool              onlyNearest                     = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11494
11495                         for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11496                         {
11497                                 params.src.image.format                                         = compatibleFormats[srcFormatIndex];
11498                                 params.dst.image.format                                         = compatibleFormats[srcFormatIndex];
11499
11500                                 if (!isSupportedByFramework(params.src.image.format))
11501                                         continue;
11502
11503                                 const bool                      onlyNearestAndLinear    = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11504
11505                                 const std::string       description                             = "Blit source format " + getFormatCaseName(params.src.image.format);
11506
11507                                 BlitColorTestParams     testParams;
11508                                 testParams.params                                                       = params;
11509                                 testParams.compatibleFormats                            = compatibleFormats;
11510                                 testParams.testFilters                                          = makeFilterMask(onlyNearest, onlyNearestAndLinear);
11511
11512                                 testParams.params.src.image.extent.depth        = layerCount;
11513                                 testParams.params.dst.image.extent.depth        = layerCount;
11514
11515                                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11516                                 {
11517                                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11518                                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11519                                 }
11520
11521                                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11522                         }
11523                 }
11524                 group->addChild(layerCountGroup.release());
11525         }
11526
11527         for (int multiLayer = 0; multiLayer < 2; multiLayer++)
11528         {
11529                 const int layerCount = multiLayer ? 6 : 1;
11530
11531                 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
11532                 {
11533                         if (layerCount != 1 || barrierCount != 1)
11534                         {
11535                                 const std::string                               barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
11536                                 const std::string                               barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
11537
11538                                 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
11539
11540                                 params.barrierCount = barrierCount;
11541
11542                                 // Only go through a few common formats
11543                                 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
11544                                 {
11545                                         params.src.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
11546                                         params.dst.image.format                                         = compatibleFormatsUInts[srcFormatIndex];
11547
11548                                         if (!isSupportedByFramework(params.src.image.format))
11549                                                 continue;
11550
11551                                         const std::string description                           = "Blit source format " + getFormatCaseName(params.src.image.format);
11552
11553                                         BlitColorTestParams testParams;
11554                                         testParams.params                                                       = params;
11555                                         testParams.compatibleFormats                            = compatibleFormatsUInts;
11556                                         testParams.testFilters                                          = FILTER_MASK_NEAREST;
11557
11558                                         testParams.params.src.image.extent.depth        = layerCount;
11559                                         testParams.params.dst.image.extent.depth        = layerCount;
11560
11561                                         for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11562                                         {
11563                                                 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11564                                                 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11565                                         }
11566
11567                                         addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11568                                 }
11569                                 group->addChild(barrierCountGroup.release());
11570                         }
11571                 }
11572         }
11573 }
11574
11575 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11576 {
11577         addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
11578         addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
11579 }
11580
11581 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11582 {
11583         addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
11584         addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
11585         addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
11586 }
11587
11588 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11589 {
11590         addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
11591         addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
11592 }
11593
11594 const VkSampleCountFlagBits     samples[]               =
11595 {
11596         VK_SAMPLE_COUNT_2_BIT,
11597         VK_SAMPLE_COUNT_4_BIT,
11598         VK_SAMPLE_COUNT_8_BIT,
11599         VK_SAMPLE_COUNT_16_BIT,
11600         VK_SAMPLE_COUNT_32_BIT,
11601         VK_SAMPLE_COUNT_64_BIT
11602 };
11603 const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
11604
11605 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11606 {
11607         TestParams      params;
11608         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11609         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11610         params.src.image.extent                         = resolveExtent;
11611         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11612         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11613         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11614         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11615         params.dst.image.extent                         = resolveExtent;
11616         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11617         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11618         params.allocationKind                           = allocationKind;
11619         params.extensionUse                                     = extensionUse;
11620
11621         {
11622                 const VkImageSubresourceLayers  sourceLayer     =
11623                 {
11624                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11625                         0u,                                                     // deUint32                             mipLevel;
11626                         0u,                                                     // deUint32                             baseArrayLayer;
11627                         1u                                                      // deUint32                             layerCount;
11628                 };
11629                 const VkImageResolve                    testResolve     =
11630                 {
11631                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11632                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11633                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11634                         {0, 0, 0},              // VkOffset3D                           dstOffset;
11635                         resolveExtent,  // VkExtent3D                           extent;
11636                 };
11637
11638                 CopyRegion      imageResolve;
11639                 imageResolve.imageResolve       = testResolve;
11640                 params.regions.push_back(imageResolve);
11641         }
11642
11643         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11644         {
11645                 params.samples                                  = samples[samplesIndex];
11646                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11647                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11648         }
11649 }
11650
11651 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11652 {
11653         TestParams      params;
11654         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11655         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11656         params.src.image.extent                         = resolveExtent;
11657         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11658         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11659         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11660         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11661         params.dst.image.extent                         = resolveExtent;
11662         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11663         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11664         params.allocationKind                           = allocationKind;
11665         params.extensionUse                                     = extensionUse;
11666
11667         {
11668                 const VkImageSubresourceLayers  sourceLayer     =
11669                 {
11670                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11671                         0u,                                                     // deUint32                             mipLevel;
11672                         0u,                                                     // deUint32                             baseArrayLayer;
11673                         1u                                                      // deUint32                             layerCount;
11674                 };
11675                 const VkImageResolve                    testResolve     =
11676                 {
11677                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11678                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11679                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11680                         {64u, 64u, 0},          // VkOffset3D                           dstOffset;
11681                         {128u, 128u, 1u},       // VkExtent3D                           extent;
11682                 };
11683
11684                 CopyRegion      imageResolve;
11685                 imageResolve.imageResolve = testResolve;
11686                 params.regions.push_back(imageResolve);
11687         }
11688
11689         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11690         {
11691                 params.samples                                  = samples[samplesIndex];
11692                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11693                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11694         }
11695 }
11696
11697 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11698 {
11699         TestParams      params;
11700         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11701         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11702         params.src.image.extent                         = resolveExtent;
11703         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11704         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11705         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11706         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11707         params.dst.image.extent                         = resolveExtent;
11708         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11709         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11710         params.allocationKind                           = allocationKind;
11711         params.extensionUse                                     = extensionUse;
11712
11713         {
11714                 const VkImageSubresourceLayers  sourceLayer     =
11715                 {
11716                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11717                         0u,                                                     // deUint32                             mipLevel;
11718                         0u,                                                     // deUint32                             baseArrayLayer;
11719                         1u                                                      // deUint32                             layerCount;
11720                 };
11721
11722                 for (int i = 0; i < 256; i += 64)
11723                 {
11724                         const VkImageResolve                    testResolve     =
11725                         {
11726                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11727                                 {i, i, 0},              // VkOffset3D                           srcOffset;
11728                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11729                                 {i, 0, 0},              // VkOffset3D                           dstOffset;
11730                                 {64u, 64u, 1u}, // VkExtent3D                           extent;
11731                         };
11732
11733                         CopyRegion      imageResolve;
11734                         imageResolve.imageResolve = testResolve;
11735                         params.regions.push_back(imageResolve);
11736                 }
11737         }
11738
11739         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11740         {
11741                 params.samples                                  = samples[samplesIndex];
11742                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11743                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
11744         }
11745 }
11746
11747 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11748 {
11749         TestParams      params;
11750         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11751         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11752         params.src.image.extent                         = defaultExtent;
11753         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11754         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11755         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11756         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11757         params.dst.image.extent                         = defaultExtent;
11758         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11759         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11760         params.allocationKind                           = allocationKind;
11761         params.extensionUse                                     = extensionUse;
11762
11763         {
11764                 const VkImageSubresourceLayers  sourceLayer     =
11765                 {
11766                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11767                         0u,                                                     // deUint32                             mipLevel;
11768                         0u,                                                     // deUint32                             baseArrayLayer;
11769                         1u                                                      // deUint32                             layerCount;
11770                 };
11771
11772                 const VkImageResolve                    testResolve     =
11773                 {
11774                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11775                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
11776                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11777                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
11778                         defaultExtent,          // VkExtent3D                           extent;
11779                 };
11780
11781                 CopyRegion      imageResolve;
11782                 imageResolve.imageResolve       = testResolve;
11783                 params.regions.push_back(imageResolve);
11784         }
11785
11786         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11787         {
11788                 params.samples                                  = samples[samplesIndex];
11789                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11790                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
11791         }
11792 }
11793
11794 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11795 {
11796         TestParams      params;
11797         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11798         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11799         params.src.image.extent                         = defaultExtent;
11800         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11801         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11802         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11803         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11804         params.dst.image.extent                         = defaultExtent;
11805         params.dst.image.extent.depth           = 5u;
11806         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11807         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11808         params.allocationKind                           = allocationKind;
11809         params.extensionUse                                     = extensionUse;
11810
11811         for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
11812         {
11813                 const VkImageSubresourceLayers  sourceLayer     =
11814                 {
11815                         VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
11816                         0u,                                                             // deUint32                             mipLevel;
11817                         layerNdx,                                               // deUint32                             baseArrayLayer;
11818                         1u                                                              // deUint32                             layerCount;
11819                 };
11820
11821                 const VkImageResolve                    testResolve     =
11822                 {
11823                         sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11824                         {0, 0, 0},                      // VkOffset3D                           srcOffset;
11825                         sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11826                         {0, 0, 0},                      // VkOffset3D                           dstOffset;
11827                         defaultExtent,          // VkExtent3D                           extent;
11828                 };
11829
11830                 CopyRegion      imageResolve;
11831                 imageResolve.imageResolve       = testResolve;
11832                 params.regions.push_back(imageResolve);
11833         }
11834
11835         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11836         {
11837                 params.samples                                  = samples[samplesIndex];
11838                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11839                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
11840         }
11841 }
11842
11843 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11844 {
11845         TestParams      params;
11846         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11847         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11848         params.src.image.extent                         = defaultExtent;
11849         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11850         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11851         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11852         params.dst.image.extent                         = defaultExtent;
11853         params.dst.image.extent.depth           = 5u;
11854         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11855         params.allocationKind                           = allocationKind;
11856         params.extensionUse                                     = extensionUse;
11857
11858         const VkImageSubresourceLayers  sourceLayer     =
11859         {
11860                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
11861                 0u,                                                             // uint32_t                             mipLevel;
11862                 0,                                              // uint32_t                             baseArrayLayer;
11863                 params.dst.image.extent.depth                   // uint32_t                             layerCount;
11864         };
11865
11866         const VkImageResolve                    testResolve     =
11867         {
11868                 sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
11869                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
11870                 sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
11871                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
11872                 defaultExtent,          // VkExtent3D                           extent;
11873         };
11874
11875         CopyRegion      imageResolve;
11876         imageResolve.imageResolve       = testResolve;
11877         params.regions.push_back(imageResolve);
11878
11879         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11880         {
11881                 params.samples                                  = samples[samplesIndex];
11882                 const std::string description   = "With " + getSampleCountCaseName(samples[samplesIndex]);
11883                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
11884         }
11885 }
11886
11887 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11888 {
11889         tcu::TestContext&       testCtx                 = group->getTestContext();
11890         TestParams                      params;
11891         params.src.image.imageType                      = VK_IMAGE_TYPE_2D;
11892         params.src.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11893         params.src.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11894         params.src.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11895         params.dst.image.imageType                      = VK_IMAGE_TYPE_2D;
11896         params.dst.image.format                         = VK_FORMAT_R8G8B8A8_UNORM;
11897         params.dst.image.tiling                         = VK_IMAGE_TILING_OPTIMAL;
11898         params.dst.image.operationLayout        = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11899         params.allocationKind                           = allocationKind;
11900         params.extensionUse                                     = extensionUse;
11901
11902         {
11903                 const VkImageSubresourceLayers  sourceLayer     =
11904                 {
11905                         VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
11906                         0u,                                                     // deUint32                             mipLevel;
11907                         0u,                                                     // deUint32                             baseArrayLayer;
11908                         1u                                                      // deUint32                             layerCount;
11909                 };
11910                 const VkImageResolve                    testResolve     =
11911                 {
11912                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
11913                         {0, 0, 0},              // VkOffset3D                           srcOffset;
11914                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
11915                         {0, 0, 0},              // VkOffset3D                           dstOffset;
11916                         resolveExtent,  // VkExtent3D                           extent;
11917                 };
11918                 CopyRegion      imageResolve;
11919                 imageResolve.imageResolve       = testResolve;
11920                 params.regions.push_back(imageResolve);
11921         }
11922
11923         const VkExtent3D imageExtents[]         =
11924         {
11925                 { resolveExtent.width + 10,     resolveExtent.height,           resolveExtent.depth },
11926                 { resolveExtent.width,          resolveExtent.height * 2,       resolveExtent.depth },
11927                 { resolveExtent.width,          resolveExtent.height,           resolveExtent.depth + 10 }
11928         };
11929
11930         for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
11931         {
11932                 const VkExtent3D&       srcImageSize    = imageExtents[srcImageExtentIndex];
11933                 params.src.image.extent                         = srcImageSize;
11934                 params.dst.image.extent                         = resolveExtent;
11935                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11936                 {
11937                         params.samples  = samples[samplesIndex];
11938                         std::ostringstream testName;
11939                         testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
11940                         std::ostringstream description;
11941                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
11942                                                 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
11943                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
11944                 }
11945         }
11946         for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
11947         {
11948                 const VkExtent3D&       dstImageSize    = imageExtents[dstImageExtentIndex];
11949                 params.src.image.extent                         = resolveExtent;
11950                 params.dst.image.extent                         = dstImageSize;
11951                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
11952                 {
11953                         params.samples  = samples[samplesIndex];
11954                         std::ostringstream testName;
11955                         testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
11956                         std::ostringstream description;
11957                         description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
11958                                                 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
11959                         group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
11960                 }
11961         }
11962 }
11963
11964 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
11965 {
11966         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"));
11967
11968         for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
11969         for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
11970         {
11971                 BufferOffsetParams params{srcOffset, dstOffset};
11972                 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
11973         }
11974
11975         group->addChild(subGroup.release());
11976 }
11977
11978 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11979 {
11980         addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
11981         addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
11982         addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
11983         addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
11984         addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
11985         addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
11986         addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
11987 }
11988
11989 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11990 {
11991         addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
11992         addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
11993         addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
11994         addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
11995         addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
11996         addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
11997         addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
11998 }
11999
12000 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12001 {
12002         addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
12003         addBufferCopyOffsetTests(group);
12004 }
12005
12006
12007 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
12008 {
12009         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
12010 }
12011
12012 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12013 {
12014         addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
12015 }
12016
12017 } // anonymous
12018
12019 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
12020 {
12021         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
12022
12023         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
12024         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",       "Copies And Blitting Tests For Dedicated Memory Allocation",    addDedicatedAllocationCopiesAndBlittingTests));
12025         copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
12026
12027         return copiesAndBlittingTests.release();
12028 }
12029
12030 } // api
12031 } // vkt