xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 #include "tcuCommandLine.hpp"
40 
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkQueryUtil.hpp"
45 #include "vkDeviceUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50 #include "vkTypeUtil.hpp"
51 #include "vkCmdUtil.hpp"
52 #include "vkObjUtil.hpp"
53 #include "vkBuilderUtil.hpp"
54 #include "vkImageWithMemory.hpp"
55 #include "vkBufferWithMemory.hpp"
56 #include "vkBarrierUtil.hpp"
57 
58 #include "pipeline/vktPipelineImageUtil.hpp" // required for compressed image blit
59 #include "vktCustomInstancesDevices.hpp"
60 #include "vkSafetyCriticalUtil.hpp"
61 
62 #include <set>
63 #include <array>
64 #include <algorithm>
65 #include <iterator>
66 #include <limits>
67 #include <sstream>
68 
69 #ifdef CTS_USES_VULKANSC
70 // VulkanSC has VK_KHR_copy_commands2 entry points, but not core entry points.
71 #define cmdCopyImage2 cmdCopyImage2KHR
72 #define cmdCopyBuffer2 cmdCopyBuffer2KHR
73 #define cmdCopyImageToBuffer2 cmdCopyImageToBuffer2KHR
74 #define cmdCopyBufferToImage2 cmdCopyBufferToImage2KHR
75 #define cmdBlitImage2 cmdBlitImage2KHR
76 #define cmdResolveImage2 cmdResolveImage2KHR
77 #endif // CTS_USES_VULKANSC
78 
79 namespace vkt
80 {
81 
82 namespace api
83 {
84 
85 namespace
86 {
87 
88 enum FillMode
89 {
90     FILL_MODE_GRADIENT = 0,
91     FILL_MODE_PYRAMID,
92     FILL_MODE_WHITE,
93     FILL_MODE_BLACK,
94     FILL_MODE_RED,
95     FILL_MODE_MULTISAMPLE,
96     FILL_MODE_BLUE_RED_X,
97     FILL_MODE_BLUE_RED_Y,
98     FILL_MODE_BLUE_RED_Z,
99 
100     FILL_MODE_LAST
101 };
102 
103 enum MirrorModeBits
104 {
105     MIRROR_MODE_X    = (1 << 0),
106     MIRROR_MODE_Y    = (1 << 1),
107     MIRROR_MODE_Z    = (1 << 2),
108     MIRROR_MODE_LAST = (1 << 3),
109 };
110 
111 using MirrorMode = uint32_t;
112 
113 enum AllocationKind
114 {
115     ALLOCATION_KIND_SUBALLOCATED,
116     ALLOCATION_KIND_DEDICATED,
117 };
118 
119 // In the case of testing new extension, add a flag to this enum and
120 // handle it in the checkExtensionSupport() function
121 enum ExtensionUseBits
122 {
123     NONE                          = 0,
124     COPY_COMMANDS_2               = (1 << 0),
125     SEPARATE_DEPTH_STENCIL_LAYOUT = (1 << 1),
126     MAINTENANCE_1                 = (1 << 2),
127     MAINTENANCE_5                 = (1 << 3),
128     SPARSE_BINDING                = (1 << 4),
129 };
130 
131 template <typename Type>
132 class BinaryCompare
133 {
134 public:
operator ()(const Type & a,const Type & b) const135     bool operator()(const Type &a, const Type &b) const
136     {
137         return deMemCmp(&a, &b, sizeof(Type)) < 0;
138     }
139 };
140 
141 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat>> FormatSet;
142 
143 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
144 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
145 
146 using namespace vk;
147 
148 const int32_t defaultSize                      = 64;
149 const int32_t defaultHalfSize                  = defaultSize / 2;
150 const int32_t defaultQuarterSize               = defaultSize / 4;
151 const int32_t defaultSixteenthSize             = defaultSize / 16;
152 const int32_t defaultQuarterSquaredSize        = defaultQuarterSize * defaultQuarterSize;
153 const uint32_t defaultRootSize                 = static_cast<uint32_t>(deSqrt(defaultSize));
154 const VkExtent3D defaultExtent                 = {defaultSize, defaultSize, 1};
155 const VkExtent3D defaultHalfExtent             = {defaultHalfSize, defaultHalfSize, 1};
156 const VkExtent3D defaultQuarterExtent          = {defaultQuarterSize, defaultQuarterSize, 1};
157 const VkExtent3D defaultRootExtent             = {defaultRootSize, defaultRootSize, 1};
158 const VkExtent3D default1dExtent               = {defaultSize, 1, 1};
159 const VkExtent3D default1dQuarterSquaredExtent = {defaultQuarterSquaredSize, 1, 1};
160 const VkExtent3D default3dExtent               = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
161 const VkExtent3D default3dSmallExtent          = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
162 
163 const VkImageSubresourceLayers defaultSourceLayer = {
164     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
165     0u,                        // uint32_t mipLevel;
166     0u,                        // uint32_t baseArrayLayer;
167     1u,                        // uint32_t layerCount;
168 };
169 
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)170 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
171 {
172     const VkImageCopy2KHR imageCopy2 = {
173         VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
174         DE_NULL,                            // const void* pNext;
175         imageCopy.srcSubresource,           // VkImageSubresourceLayers srcSubresource;
176         imageCopy.srcOffset,                // VkOffset3D srcOffset;
177         imageCopy.dstSubresource,           // VkImageSubresourceLayers dstSubresource;
178         imageCopy.dstOffset,                // VkOffset3D dstOffset;
179         imageCopy.extent                    // VkExtent3D extent;
180     };
181     return imageCopy2;
182 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)183 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
184 {
185     const VkBufferCopy2KHR bufferCopy2 = {
186         VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR, // VkStructureType sType;
187         DE_NULL,                             // const void* pNext;
188         bufferCopy.srcOffset,                // VkDeviceSize srcOffset;
189         bufferCopy.dstOffset,                // VkDeviceSize dstOffset;
190         bufferCopy.size,                     // VkDeviceSize size;
191     };
192     return bufferCopy2;
193 }
194 
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)195 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
196 {
197     const VkBufferImageCopy2KHR bufferImageCopy2 = {
198         VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR, // VkStructureType sType;
199         DE_NULL,                                   // const void* pNext;
200         bufferImageCopy.bufferOffset,              // VkDeviceSize bufferOffset;
201         bufferImageCopy.bufferRowLength,           // uint32_t bufferRowLength;
202         bufferImageCopy.bufferImageHeight,         // uint32_t bufferImageHeight;
203         bufferImageCopy.imageSubresource,          // VkImageSubresourceLayers imageSubresource;
204         bufferImageCopy.imageOffset,               // VkOffset3D imageOffset;
205         bufferImageCopy.imageExtent                // VkExtent3D imageExtent;
206     };
207     return bufferImageCopy2;
208 }
209 
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)210 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
211 {
212     const VkImageBlit2KHR imageBlit2 = {VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR, // VkStructureType sType;
213                                         DE_NULL,                            // const void* pNext;
214                                         imageBlit.srcSubresource,           // VkImageSubresourceLayers srcSubresource;
215                                         {                                   // VkOffset3D srcOffsets[2];
216                                          {
217                                              imageBlit.srcOffsets[0].x, // VkOffset3D srcOffsets[0].x;
218                                              imageBlit.srcOffsets[0].y, // VkOffset3D srcOffsets[0].y;
219                                              imageBlit.srcOffsets[0].z  // VkOffset3D srcOffsets[0].z;
220                                          },
221                                          {
222                                              imageBlit.srcOffsets[1].x, // VkOffset3D srcOffsets[1].x;
223                                              imageBlit.srcOffsets[1].y, // VkOffset3D srcOffsets[1].y;
224                                              imageBlit.srcOffsets[1].z  // VkOffset3D srcOffsets[1].z;
225                                          }},
226                                         imageBlit.dstSubresource, // VkImageSubresourceLayers dstSubresource;
227                                         {                         // VkOffset3D srcOffsets[2];
228                                          {
229                                              imageBlit.dstOffsets[0].x, // VkOffset3D dstOffsets[0].x;
230                                              imageBlit.dstOffsets[0].y, // VkOffset3D dstOffsets[0].y;
231                                              imageBlit.dstOffsets[0].z  // VkOffset3D dstOffsets[0].z;
232                                          },
233                                          {
234                                              imageBlit.dstOffsets[1].x, // VkOffset3D dstOffsets[1].x;
235                                              imageBlit.dstOffsets[1].y, // VkOffset3D dstOffsets[1].y;
236                                              imageBlit.dstOffsets[1].z  // VkOffset3D dstOffsets[1].z;
237                                          }}};
238     return imageBlit2;
239 }
240 
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)241 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
242 {
243     const VkImageResolve2KHR imageResolve2 = {
244         VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, // VkStructureType sType;
245         DE_NULL,                               // const void* pNext;
246         imageResolve.srcSubresource,           // VkImageSubresourceLayers srcSubresource;
247         imageResolve.srcOffset,                // VkOffset3D srcOffset;
248         imageResolve.dstSubresource,           // VkImageSubresourceLayers dstSubresource;
249         imageResolve.dstOffset,                // VkOffset3D dstOffset;
250         imageResolve.extent                    // VkExtent3D extent;
251     };
252     return imageResolve2;
253 }
254 
getAspectFlags(tcu::TextureFormat format)255 VkImageAspectFlags getAspectFlags(tcu::TextureFormat format)
256 {
257     VkImageAspectFlags aspectFlag = 0;
258     aspectFlag |= (tcu::hasDepthComponent(format.order) ? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
259     aspectFlag |= (tcu::hasStencilComponent(format.order) ? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
260 
261     if (!aspectFlag)
262         aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
263 
264     return aspectFlag;
265 }
266 
getAspectFlags(VkFormat format)267 VkImageAspectFlags getAspectFlags(VkFormat format)
268 {
269     if (isCompressedFormat(format))
270         return VK_IMAGE_ASPECT_COLOR_BIT;
271     else
272         return getAspectFlags(mapVkFormat(format));
273 }
274 
getSizeCompatibleTcuTextureFormat(VkFormat format)275 tcu::TextureFormat getSizeCompatibleTcuTextureFormat(VkFormat format)
276 {
277     if (isCompressedFormat(format))
278         return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) :
279                                                     mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
280     else
281         return mapVkFormat(format);
282 }
283 
284 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
285 // except that it supports some formats that are not mappable to VkFormat.
286 // When we are checking combined depth and stencil formats, each aspect is
287 // checked separately, and in some cases we construct PBA with a format that
288 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)289 bool isFloatFormat(tcu::TextureFormat format)
290 {
291     return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
292 }
293 
294 union CopyRegion
295 {
296     VkBufferCopy bufferCopy;
297     VkImageCopy imageCopy;
298     VkBufferImageCopy bufferImageCopy;
299     VkImageBlit imageBlit;
300     VkImageResolve imageResolve;
301 };
302 
303 struct ImageParms
304 {
305     VkImageType imageType;
306     VkFormat format;
307     VkExtent3D extent;
308     VkImageTiling tiling;
309     VkImageLayout operationLayout;
310     VkImageCreateFlags createFlags;
311     FillMode fillMode;
312 
texelBlockDimensionsvkt::api::__anonbd1d8d730111::ImageParms313     std::pair<uint32_t, uint32_t> texelBlockDimensions() const
314     {
315         const bool isCompressed    = isCompressedFormat(format);
316         const uint32_t blockWidth  = (isCompressed) ? getBlockWidth(format) : 1u;
317         const uint32_t blockHeight = (isCompressed) ? getBlockHeight(format) : 1u;
318         return std::make_pair(blockWidth, blockHeight);
319     }
320 };
321 
322 enum class QueueSelectionOptions
323 {
324     Universal = 0,
325     ComputeOnly,
326     TransferOnly
327 };
328 
329 struct CustomDeviceData
330 {
331     Move<VkDevice> device;
332     de::MovePtr<Allocator> allocator;
333     uint32_t queueFamilyIndex{0};
334 };
335 
336 struct BufferParams
337 {
338     VkDeviceSize size;
339     FillMode fillMode;
340 };
341 
342 struct TestParams
343 {
344     union Data
345     {
346         BufferParams buffer;
347         ImageParms image;
348     } src, dst;
349 
350     std::vector<CopyRegion> regions;
351 
352     union
353     {
354         VkFilter filter;
355         VkSampleCountFlagBits samples;
356     };
357 
358     AllocationKind allocationKind;
359     uint32_t extensionFlags;
360     QueueSelectionOptions queueSelection;
361     uint32_t mipLevels;
362     uint32_t arrayLayers;
363     bool singleCommand;
364     uint32_t barrierCount;
365     bool
366         clearDestinationWithRed; // Used for CopyImageToImage tests to clear dst image with vec4(1.0f, 0.0f, 0.0f, 1.0f)
367     bool imageOffset;
368     bool useSecondaryCmdBuffer;
369     bool useSparseBinding;
370 
TestParamsvkt::api::__anonbd1d8d730111::TestParams371     TestParams(void)
372     {
373         allocationKind          = ALLOCATION_KIND_DEDICATED;
374         extensionFlags          = NONE;
375         queueSelection          = QueueSelectionOptions::Universal;
376         mipLevels               = 1u;
377         arrayLayers             = 1u;
378         singleCommand           = true;
379         barrierCount            = 1u;
380         src.image.createFlags   = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
381         dst.image.createFlags   = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
382         src.buffer.fillMode     = FILL_MODE_GRADIENT;
383         src.image.fillMode      = FILL_MODE_GRADIENT;
384         dst.buffer.fillMode     = FILL_MODE_GRADIENT;
385         dst.image.fillMode      = FILL_MODE_WHITE;
386         clearDestinationWithRed = false;
387         samples                 = VK_SAMPLE_COUNT_1_BIT;
388         imageOffset             = false;
389         useSecondaryCmdBuffer   = false;
390         useSparseBinding        = false;
391     }
392 
usesNonUniversalQueuevkt::api::__anonbd1d8d730111::TestParams393     bool usesNonUniversalQueue() const
394     {
395         return queueSelection != QueueSelectionOptions::Universal;
396     }
397 };
398 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)399 de::MovePtr<Allocation> allocateBuffer(const InstanceInterface &vki, const DeviceInterface &vkd,
400                                        const VkPhysicalDevice &physDevice, const VkDevice device,
401                                        const VkBuffer &buffer, const MemoryRequirement requirement,
402                                        Allocator &allocator, AllocationKind allocationKind)
403 {
404     switch (allocationKind)
405     {
406     case ALLOCATION_KIND_SUBALLOCATED:
407     {
408         const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
409 
410         return allocator.allocate(memoryRequirements, requirement);
411     }
412 
413     case ALLOCATION_KIND_DEDICATED:
414     {
415         return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
416     }
417 
418     default:
419     {
420         TCU_THROW(InternalError, "Invalid allocation kind");
421     }
422     }
423 }
424 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind,const uint32_t offset)425 de::MovePtr<Allocation> allocateImage(const InstanceInterface &vki, const DeviceInterface &vkd,
426                                       const VkPhysicalDevice &physDevice, const VkDevice device, const VkImage &image,
427                                       const MemoryRequirement requirement, Allocator &allocator,
428                                       AllocationKind allocationKind, const uint32_t offset)
429 {
430     switch (allocationKind)
431     {
432     case ALLOCATION_KIND_SUBALLOCATED:
433     {
434         VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
435         memoryRequirements.size += offset;
436 
437         return allocator.allocate(memoryRequirements, requirement);
438     }
439 
440     case ALLOCATION_KIND_DEDICATED:
441     {
442         VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
443         memoryRequirements.size += offset;
444 
445         const VkMemoryDedicatedAllocateInfo dedicatedAllocationInfo = {
446             VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType        sType
447             DE_NULL,                                          // const void*            pNext
448             image,                                            // VkImage                image
449             DE_NULL                                           // VkBuffer                buffer
450         };
451 
452         return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement,
453                                 &dedicatedAllocationInfo);
454     }
455 
456     default:
457     {
458         TCU_THROW(InternalError, "Invalid allocation kind");
459     }
460     }
461 }
462 
checkExtensionSupport(Context & context,uint32_t flags)463 void checkExtensionSupport(Context &context, uint32_t flags)
464 {
465     if (flags & COPY_COMMANDS_2)
466     {
467         if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
468             TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
469     }
470 
471     if (flags & SEPARATE_DEPTH_STENCIL_LAYOUT)
472     {
473         if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
474             TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
475     }
476 
477     if (flags & MAINTENANCE_1)
478     {
479         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
480             TCU_THROW(NotSupportedError, "VK_KHR_maintenance1 is not supported");
481     }
482 
483     if (flags & MAINTENANCE_5)
484     {
485         if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
486             TCU_THROW(NotSupportedError, "VK_KHR_maintenance5 is not supported");
487     }
488 
489     if (flags & SPARSE_BINDING)
490         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
491 }
492 
getArraySize(const ImageParms & parms)493 inline uint32_t getArraySize(const ImageParms &parms)
494 {
495     return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
496 }
497 
getCreateFlags(const ImageParms & parms)498 inline VkImageCreateFlags getCreateFlags(const ImageParms &parms)
499 {
500     if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
501         return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ?
502                    VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT :
503                    0;
504     else
505         return parms.createFlags;
506 }
507 
getExtent3D(const ImageParms & parms,uint32_t mipLevel=0u)508 inline VkExtent3D getExtent3D(const ImageParms &parms, uint32_t mipLevel = 0u)
509 {
510     const bool isCompressed    = isCompressedFormat(parms.format);
511     const uint32_t blockWidth  = (isCompressed) ? getBlockWidth(parms.format) : 1u;
512     const uint32_t blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
513 
514     if (isCompressed && mipLevel != 0u)
515         DE_FATAL("Not implemented");
516 
517     const VkExtent3D extent = {
518         (parms.extent.width >> mipLevel) * blockWidth,
519         (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
520         (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
521     };
522     return extent;
523 }
524 
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)525 const tcu::TextureFormat mapCombinedToDepthTransferFormat(const tcu::TextureFormat &combinedFormat)
526 {
527     tcu::TextureFormat format;
528     switch (combinedFormat.type)
529     {
530     case tcu::TextureFormat::UNORM_INT16:
531     case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
532         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
533         break;
534     case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
535         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
536         break;
537     case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
538     case tcu::TextureFormat::FLOAT:
539         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
540         break;
541     default:
542         DE_ASSERT(false);
543         break;
544     }
545     return format;
546 }
547 
548 class CopiesAndBlittingTestInstance : public vkt::TestInstance
549 {
550 public:
551     CopiesAndBlittingTestInstance(Context &context, TestParams testParams);
552     virtual tcu::TestStatus iterate(void) = 0;
553 
554 protected:
555     const TestParams m_params;
556     VkDevice m_device;
557     Allocator *m_allocator;
558     VkQueue m_universalQueue{VK_NULL_HANDLE};
559     Move<VkCommandPool> m_universalCmdPool;
560     Move<VkCommandBuffer> m_universalCmdBuffer;
561     VkQueue m_otherQueue{VK_NULL_HANDLE}; // Dedicated compute/transfer queue
562     Move<VkCommandPool> m_otherCmdPool;   // Dedicated compute/transfer command bool & buffer
563     Move<VkCommandBuffer> m_otherCmdBuffer;
564     Move<VkCommandPool> m_secondaryCmdPool;
565     Move<VkCommandBuffer> m_secondaryCmdBuffer;
566     Move<VkCommandPool> m_sparseCmdPool;
567     Move<VkCommandBuffer> m_sparseCmdBuffer;
568 
569     de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
570     de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
571     de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16];
572 
573     // For tests that use multiple queues, this will be a >1 sized array containing the queue familiy indices,
574     // used for setting up concurrently accessed resources.
575     std::vector<uint32_t> m_queueFamilyIndices;
576 
577     void generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1,
578                         FillMode = FILL_MODE_GRADIENT);
579     virtual void generateExpectedResult(void);
580     void uploadBuffer(const tcu::ConstPixelBufferAccess &bufferAccess, const Allocation &bufferAlloc);
581     void uploadImage(const tcu::ConstPixelBufferAccess &src, VkImage dst, const ImageParms &parms,
582                      const uint32_t mipLevels = 1u);
583     virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
584     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
585                                           CopyRegion region, uint32_t mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const586     uint32_t calculateSize(tcu::ConstPixelBufferAccess src) const
587     {
588         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
589     }
590 
591     de::MovePtr<tcu::TextureLevel> readImage(vk::VkImage image, const ImageParms &imageParms,
592                                              const uint32_t mipLevel = 0u);
593 
594     using ExecutionCtx = std::tuple<VkQueue, VkCommandBuffer, VkCommandPool>;
activeExecutionCtx()595     ExecutionCtx activeExecutionCtx()
596     {
597         if (m_params.queueSelection != QueueSelectionOptions::Universal)
598         {
599             return std::make_tuple(m_otherQueue, *m_otherCmdBuffer, *m_otherCmdPool);
600         }
601         else
602         {
603             return std::make_tuple(m_universalQueue, *m_universalCmdBuffer, *m_universalCmdPool);
604         }
605     }
606 
activeQueueFamilyIndex() const607     uint32_t activeQueueFamilyIndex() const
608     {
609         int familyIndex = -1;
610         switch (m_params.queueSelection)
611         {
612         case QueueSelectionOptions::ComputeOnly:
613             familyIndex = m_context.getComputeQueueFamilyIndex();
614             break;
615         case QueueSelectionOptions::TransferOnly:
616             familyIndex = m_context.getTransferQueueFamilyIndex();
617             break;
618         case QueueSelectionOptions::Universal:
619             familyIndex = m_context.getUniversalQueueFamilyIndex();
620             break;
621         }
622         TCU_CHECK_INTERNAL(familyIndex >= 0);
623         return (uint32_t)familyIndex;
624     }
625 
626 private:
627     void uploadImageAspect(const tcu::ConstPixelBufferAccess &src, const VkImage &dst, const ImageParms &parms,
628                            const uint32_t mipLevels = 1u);
629     void readImageAspect(vk::VkImage src, const tcu::PixelBufferAccess &dst, const ImageParms &parms,
630                          const uint32_t mipLevel = 0u);
631 };
632 
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)633 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance(Context &context, TestParams testParams)
634     : vkt::TestInstance(context)
635     , m_params(testParams)
636 {
637     // Store default device, queue and allocator. Some tests override these with custom device and queue.
638     m_device    = context.getDevice();
639     m_allocator = &context.getDefaultAllocator();
640 
641     const DeviceInterface &vk = context.getDeviceInterface();
642 
643     int queueFamilyIdx = context.getUniversalQueueFamilyIndex();
644     m_queueFamilyIndices.push_back(queueFamilyIdx);
645 
646     switch (m_params.queueSelection)
647     {
648     case QueueSelectionOptions::ComputeOnly:
649     {
650         m_otherQueue   = context.getComputeQueue();
651         queueFamilyIdx = context.getComputeQueueFamilyIndex();
652         TCU_CHECK_INTERNAL(queueFamilyIdx != -1);
653         m_queueFamilyIndices.push_back(queueFamilyIdx);
654         m_otherCmdPool =
655             createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
656         m_otherCmdBuffer = allocateCommandBuffer(vk, m_device, *m_otherCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
657         break;
658     }
659     case QueueSelectionOptions::TransferOnly:
660     {
661         m_otherQueue   = context.getTransferQueue();
662         queueFamilyIdx = context.getTransferQueueFamilyIndex();
663         TCU_CHECK_INTERNAL(queueFamilyIdx != -1);
664         m_queueFamilyIndices.push_back(queueFamilyIdx);
665         m_otherCmdPool =
666             createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
667         m_otherCmdBuffer = allocateCommandBuffer(vk, m_device, *m_otherCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
668         break;
669     }
670     case QueueSelectionOptions::Universal:
671     {
672         break; // Unconditionally created below.
673     }
674     }
675 
676     m_universalQueue     = context.getUniversalQueue();
677     m_universalCmdPool   = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
678                                              context.getUniversalQueueFamilyIndex());
679     m_universalCmdBuffer = allocateCommandBuffer(vk, m_device, *m_universalCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
680 
681     if (m_params.useSecondaryCmdBuffer)
682     {
683         m_secondaryCmdPool =
684             createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIdx);
685         m_secondaryCmdBuffer =
686             allocateCommandBuffer(vk, m_device, *m_secondaryCmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
687     }
688 }
689 
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)690 void CopiesAndBlittingTestInstance::generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth,
691                                                    FillMode mode)
692 {
693     const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type);
694     tcu::Vec4 maxValue(1.0f);
695 
696     if (buffer.getFormat().order == tcu::TextureFormat::S)
697     {
698         // Stencil-only is stored in the first component. Stencil is always 8 bits.
699         maxValue.x() = 1 << 8;
700     }
701     else if (buffer.getFormat().order == tcu::TextureFormat::DS)
702     {
703         // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
704         maxValue.w() = 1 << 8;
705     }
706     else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
707              channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
708     {
709         // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
710         const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
711         const int signBit     = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
712 
713         for (int i = 0; i < 4; ++i)
714         {
715             if (bits[i] != 0)
716                 maxValue[i] = static_cast<float>((uint64_t(1) << (bits[i] - signBit)) - 1);
717         }
718     }
719 
720     if (mode == FILL_MODE_GRADIENT)
721     {
722         tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
723         return;
724     }
725 
726     if (mode == FILL_MODE_PYRAMID)
727     {
728         tcu::fillWithComponentGradients3(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
729         return;
730     }
731 
732     const tcu::Vec4 redColor(maxValue.x(), 0.0, 0.0, maxValue.w());
733     const tcu::Vec4 greenColor(0.0, maxValue.y(), 0.0, maxValue.w());
734     const tcu::Vec4 blueColor(0.0, 0.0, maxValue.z(), maxValue.w());
735     const tcu::Vec4 whiteColor(maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w());
736     const tcu::Vec4 blackColor(0.0f, 0.0f, 0.0f, 0.0f);
737 
738     for (int z = 0; z < depth; ++z)
739         for (int y = 0; y < height; ++y)
740             for (int x = 0; x < width; ++x)
741             {
742                 switch (mode)
743                 {
744                 case FILL_MODE_WHITE:
745                     if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
746                     {
747                         buffer.setPixDepth(1.0f, x, y, z);
748                         if (tcu::hasStencilComponent(buffer.getFormat().order))
749                             buffer.setPixStencil(255, x, y, z);
750                     }
751                     else
752                         buffer.setPixel(whiteColor, x, y, z);
753                     break;
754 
755                 case FILL_MODE_BLACK:
756                     if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
757                     {
758                         buffer.setPixDepth(0.0f, x, y, z);
759                         if (tcu::hasStencilComponent(buffer.getFormat().order))
760                             buffer.setPixStencil(0, x, y, z);
761                     }
762                     else
763                         buffer.setPixel(blackColor, x, y, z);
764                     break;
765 
766                 case FILL_MODE_RED:
767                     if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
768                     {
769                         buffer.setPixDepth(redColor[0], x, y, z);
770                         if (tcu::hasStencilComponent(buffer.getFormat().order))
771                             buffer.setPixStencil((int)redColor[3], x, y, z);
772                     }
773                     else
774                         buffer.setPixel(redColor, x, y, z);
775                     break;
776 
777                 case FILL_MODE_BLUE_RED_X:
778                 case FILL_MODE_BLUE_RED_Y:
779                 case FILL_MODE_BLUE_RED_Z:
780                     bool useBlue;
781                     switch (mode)
782                     {
783                     case FILL_MODE_BLUE_RED_X:
784                         useBlue = (x & 1);
785                         break;
786                     case FILL_MODE_BLUE_RED_Y:
787                         useBlue = (y & 1);
788                         break;
789                     case FILL_MODE_BLUE_RED_Z:
790                         useBlue = (z & 1);
791                         break;
792                     default:
793                         DE_ASSERT(false);
794                         break;
795                     }
796                     if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
797                     {
798                         buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
799                         if (tcu::hasStencilComponent(buffer.getFormat().order))
800                             buffer.setPixStencil((useBlue ? (int)blueColor[3] : (int)redColor[3]), x, y, z);
801                     }
802                     else
803                         buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
804                     break;
805 
806                 case FILL_MODE_MULTISAMPLE:
807                 {
808                     float xScaled = static_cast<float>(x) / static_cast<float>(width);
809                     float yScaled = static_cast<float>(y) / static_cast<float>(height);
810                     buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) :
811                                                            ((xScaled > yScaled) ? greenColor : blueColor),
812                                     x, y, z);
813                     break;
814                 }
815 
816                 default:
817                     break;
818                 }
819             }
820 }
821 
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)822 void CopiesAndBlittingTestInstance::uploadBuffer(const tcu::ConstPixelBufferAccess &bufferAccess,
823                                                  const Allocation &bufferAlloc)
824 {
825     const DeviceInterface &vk = m_context.getDeviceInterface();
826     const uint32_t bufferSize = calculateSize(bufferAccess);
827 
828     // Write buffer data
829     deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
830     flushAlloc(vk, m_device, bufferAlloc);
831 }
832 
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const uint32_t mipLevels)833 void CopiesAndBlittingTestInstance::uploadImageAspect(const tcu::ConstPixelBufferAccess &imageAccess,
834                                                       const VkImage &image, const ImageParms &parms,
835                                                       const uint32_t mipLevels)
836 {
837     const InstanceInterface &vki        = m_context.getInstanceInterface();
838     const DeviceInterface &vk           = m_context.getDeviceInterface();
839     const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
840     const VkDevice vkDevice             = m_device;
841     Allocator &memAlloc                 = *m_allocator;
842     Move<VkBuffer> buffer;
843     const uint32_t bufferSize = calculateSize(imageAccess);
844     de::MovePtr<Allocation> bufferAlloc;
845     const uint32_t arraySize     = getArraySize(parms);
846     const VkExtent3D imageExtent = getExtent3D(parms);
847     std::vector<VkBufferImageCopy> copyRegions;
848 
849     // Create source buffer
850     {
851         const VkBufferCreateInfo bufferParams = {
852             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
853             DE_NULL,                              // const void* pNext;
854             0u,                                   // VkBufferCreateFlags flags;
855             bufferSize,                           // VkDeviceSize size;
856             VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
857             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
858                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
859             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
860             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
861         };
862 
863         buffer      = createBuffer(vk, vkDevice, &bufferParams);
864         bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc,
865                                      m_params.allocationKind);
866         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
867     }
868 
869     // Barriers for copying buffer to image
870     const VkBufferMemoryBarrier preBufferBarrier =
871         makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, *buffer, 0u, bufferSize);
872 
873     const VkImageAspectFlags formatAspect = (m_params.extensionFlags & SEPARATE_DEPTH_STENCIL_LAYOUT) ?
874                                                 getAspectFlags(imageAccess.getFormat()) :
875                                                 getAspectFlags(parms.format);
876     const bool skipPreImageBarrier        = (m_params.extensionFlags & SEPARATE_DEPTH_STENCIL_LAYOUT) ?
877                                                 false :
878                                                 ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
879                                            getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
880 
881     const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(
882         0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image,
883         makeImageSubresourceRange(formatAspect, 0u, mipLevels, 0u, arraySize));
884 
885     const VkImageMemoryBarrier postImageBarrier =
886         makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
887                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image,
888                                makeImageSubresourceRange(formatAspect, 0u, mipLevels, 0u, arraySize));
889 
890     uint32_t blockWidth, blockHeight;
891     std::tie(blockWidth, blockHeight) = parms.texelBlockDimensions();
892 
893     for (uint32_t mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
894     {
895         const VkExtent3D copyExtent =
896             makeExtent3D(imageExtent.width >> mipLevelNdx, imageExtent.height >> mipLevelNdx, imageExtent.depth);
897         uint32_t rowLength                 = ((copyExtent.width + blockWidth - 1) / blockWidth) * blockWidth;
898         uint32_t imageHeight               = ((copyExtent.height + blockHeight - 1) / blockHeight) * blockHeight;
899         const VkBufferImageCopy copyRegion = {
900             0u,          // VkDeviceSize bufferOffset;
901             rowLength,   // uint32_t bufferRowLength;
902             imageHeight, // uint32_t bufferImageHeight;
903             {
904                 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect;
905                 mipLevelNdx,                             // uint32_t mipLevel;
906                 0u,                                      // uint32_t baseArrayLayer;
907                 arraySize,                               // uint32_t layerCount;
908             },                                           // VkImageSubresourceLayers imageSubresource;
909             {0, 0, 0},                                   // VkOffset3D imageOffset;
910             copyExtent                                   // VkExtent3D imageExtent;
911         };
912 
913         copyRegions.push_back(copyRegion);
914     }
915 
916     // Write buffer data
917     deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
918     flushAlloc(vk, vkDevice, *bufferAlloc);
919 
920     // Copy buffer to image on the universal queue, since not all image aspects may be transferred on dedicated queues.
921     beginCommandBuffer(vk, *m_universalCmdBuffer);
922     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
923                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier,
924                           (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
925     vk.cmdCopyBufferToImage(*m_universalCmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
926                             (uint32_t)copyRegions.size(), &copyRegions[0]);
927     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
928                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
929                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
930     endCommandBuffer(vk, *m_universalCmdBuffer);
931 
932     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
933     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
934 }
935 
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const uint32_t mipLevels)936 void CopiesAndBlittingTestInstance::uploadImage(const tcu::ConstPixelBufferAccess &src, VkImage dst,
937                                                 const ImageParms &parms, const uint32_t mipLevels)
938 {
939     if (tcu::isCombinedDepthStencilType(src.getFormat().type))
940     {
941         if (tcu::hasDepthComponent(src.getFormat().order))
942         {
943             tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(),
944                                            src.getHeight(), src.getDepth());
945             tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
946             uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
947         }
948 
949         if (tcu::hasStencilComponent(src.getFormat().order))
950         {
951             tcu::TextureLevel stencilTexture(
952                 tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(),
953                 src.getHeight(), src.getDepth());
954             tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
955             uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
956         }
957     }
958     else
959         uploadImageAspect(src, dst, parms, mipLevels);
960 }
961 
checkTestResult(tcu::ConstPixelBufferAccess result)962 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult(tcu::ConstPixelBufferAccess result)
963 {
964     const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
965 
966     if (isFloatFormat(result.getFormat()))
967     {
968         const tcu::Vec4 threshold(0.0f);
969         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
970                                         result, threshold, tcu::COMPARE_LOG_RESULT))
971             return tcu::TestStatus::fail("CopiesAndBlitting test");
972     }
973     else
974     {
975         const tcu::UVec4 threshold(0u);
976         if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
977         {
978             if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
979                                          result, 0.1f, tcu::COMPARE_LOG_RESULT))
980                 return tcu::TestStatus::fail("CopiesAndBlitting test");
981         }
982         else
983         {
984             if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
985                                           result, threshold, tcu::COMPARE_LOG_RESULT))
986                 return tcu::TestStatus::fail("CopiesAndBlitting test");
987         }
988     }
989 
990     return tcu::TestStatus::pass("CopiesAndBlitting test");
991 }
992 
generateExpectedResult(void)993 void CopiesAndBlittingTestInstance::generateExpectedResult(void)
994 {
995     const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
996     const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
997 
998     m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(
999         new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
1000     tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
1001 
1002     for (uint32_t i = 0; i < m_params.regions.size(); i++)
1003         copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
1004 }
1005 
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const uint32_t mipLevel)1006 void CopiesAndBlittingTestInstance::readImageAspect(vk::VkImage image, const tcu::PixelBufferAccess &dst,
1007                                                     const ImageParms &imageParms, const uint32_t mipLevel)
1008 {
1009     const InstanceInterface &vki      = m_context.getInstanceInterface();
1010     const DeviceInterface &vk         = m_context.getDeviceInterface();
1011     const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1012     const VkDevice device             = m_device;
1013     Allocator &allocator              = *m_allocator;
1014 
1015     Move<VkBuffer> buffer;
1016     de::MovePtr<Allocation> bufferAlloc;
1017     const VkDeviceSize pixelDataSize = calculateSize(dst);
1018     const VkExtent3D imageExtent     = getExtent3D(imageParms, mipLevel);
1019 
1020     // Create destination buffer
1021     {
1022         const VkBufferCreateInfo bufferParams = {
1023             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1024             DE_NULL,                              // const void* pNext;
1025             0u,                                   // VkBufferCreateFlags flags;
1026             pixelDataSize,                        // VkDeviceSize size;
1027             VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
1028             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1029                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1030             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
1031             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
1032         };
1033 
1034         buffer      = createBuffer(vk, device, &bufferParams);
1035         bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator,
1036                                      m_params.allocationKind);
1037         VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1038 
1039         deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
1040         flushAlloc(vk, device, *bufferAlloc);
1041     }
1042 
1043     // Barriers for copying image to buffer
1044     const VkImageAspectFlags formatAspect   = getAspectFlags(imageParms.format);
1045     const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1046                                                DE_NULL,                                // const void* pNext;
1047                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
1048                                                VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
1049                                                imageParms.operationLayout,             // VkImageLayout oldLayout;
1050                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,   // VkImageLayout newLayout;
1051                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1052                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1053                                                image,                                  // VkImage image;
1054                                                {
1055                                                    // VkImageSubresourceRange subresourceRange;
1056                                                    formatAspect,            // VkImageAspectFlags aspectMask;
1057                                                    mipLevel,                // uint32_t baseMipLevel;
1058                                                    1u,                      // uint32_t mipLevels;
1059                                                    0u,                      // uint32_t baseArraySlice;
1060                                                    getArraySize(imageParms) // uint32_t arraySize;
1061                                                }};
1062 
1063     const VkBufferMemoryBarrier bufferBarrier = {
1064         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1065         DE_NULL,                                 // const void* pNext;
1066         VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags srcAccessMask;
1067         VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags dstAccessMask;
1068         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t srcQueueFamilyIndex;
1069         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t dstQueueFamilyIndex;
1070         *buffer,                                 // VkBuffer buffer;
1071         0u,                                      // VkDeviceSize offset;
1072         pixelDataSize                            // VkDeviceSize size;
1073     };
1074 
1075     const VkImageMemoryBarrier postImageBarrier = {
1076         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1077         DE_NULL,                                // const void* pNext;
1078         VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags srcAccessMask;
1079         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
1080         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,   // VkImageLayout oldLayout;
1081         imageParms.operationLayout,             // VkImageLayout newLayout;
1082         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1083         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1084         image,                                  // VkImage image;
1085         {
1086             formatAspect,            // VkImageAspectFlags aspectMask;
1087             mipLevel,                // uint32_t baseMipLevel;
1088             1u,                      // uint32_t mipLevels;
1089             0u,                      // uint32_t baseArraySlice;
1090             getArraySize(imageParms) // uint32_t arraySize;
1091         }                            // VkImageSubresourceRange subresourceRange;
1092     };
1093 
1094     // Copy image to buffer
1095     const bool isCompressed    = isCompressedFormat(imageParms.format);
1096     const uint32_t blockWidth  = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
1097     const uint32_t blockHeight = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
1098     uint32_t rowLength         = ((imageExtent.width + blockWidth - 1) / blockWidth) * blockWidth;
1099     uint32_t imageHeight       = ((imageExtent.height + blockHeight - 1) / blockHeight) * blockHeight;
1100 
1101     // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
1102     const VkImageAspectFlags aspect    = isCompressedFormat(m_params.dst.image.format) ?
1103                                              static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
1104                                              getAspectFlags(dst.getFormat());
1105     const VkBufferImageCopy copyRegion = {
1106         0u,          // VkDeviceSize bufferOffset;
1107         rowLength,   // uint32_t bufferRowLength;
1108         imageHeight, // uint32_t bufferImageHeight;
1109         {
1110             aspect,                   // VkImageAspectFlags aspect;
1111             mipLevel,                 // uint32_t mipLevel;
1112             0u,                       // uint32_t baseArrayLayer;
1113             getArraySize(imageParms), // uint32_t layerCount;
1114         },                            // VkImageSubresourceLayers imageSubresource;
1115         {0, 0, 0},                    // VkOffset3D imageOffset;
1116         imageExtent                   // VkExtent3D imageExtent;
1117     };
1118 
1119     beginCommandBuffer(vk, *m_universalCmdBuffer);
1120     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1121                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1122                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
1123     vk.cmdCopyImageToBuffer(*m_universalCmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u,
1124                             &copyRegion);
1125     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1126                           VK_PIPELINE_STAGE_HOST_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
1127                           (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
1128     endCommandBuffer(vk, *m_universalCmdBuffer);
1129 
1130     submitCommandsAndWait(vk, device, m_universalQueue, *m_universalCmdBuffer);
1131     m_context.resetCommandPoolForVKSC(device, *m_universalCmdPool);
1132 
1133     // Read buffer data
1134     invalidateAlloc(vk, device, *bufferAlloc);
1135     tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
1136 }
1137 
readImage(vk::VkImage image,const ImageParms & parms,const uint32_t mipLevel)1138 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage(vk::VkImage image, const ImageParms &parms,
1139                                                                         const uint32_t mipLevel)
1140 {
1141     const tcu::TextureFormat imageFormat = getSizeCompatibleTcuTextureFormat(parms.format);
1142     de::MovePtr<tcu::TextureLevel> resultLevel(new tcu::TextureLevel(
1143         imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1144 
1145     if (tcu::isCombinedDepthStencilType(imageFormat.type))
1146     {
1147         if (tcu::hasDepthComponent(imageFormat.order))
1148         {
1149             tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(imageFormat),
1150                                            parms.extent.width >> mipLevel, parms.extent.height >> mipLevel,
1151                                            parms.extent.depth);
1152             readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1153             tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH),
1154                       depthTexture.getAccess());
1155         }
1156 
1157         if (tcu::hasStencilComponent(imageFormat.order))
1158         {
1159             tcu::TextureLevel stencilTexture(
1160                 tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL),
1161                 parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1162             readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1163             tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL),
1164                       stencilTexture.getAccess());
1165         }
1166     }
1167     else
1168         readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1169 
1170     return resultLevel;
1171 }
1172 
1173 // Copy from image to image.
1174 
1175 class CopyImageToImage final : public CopiesAndBlittingTestInstance
1176 {
1177 public:
1178     CopyImageToImage(Context &context, TestParams params);
1179     tcu::TestStatus iterate(void) override;
1180 
1181 private:
1182     tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess()) override;
1183     void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region,
1184                                   uint32_t mipLevel = 0u) override;
1185 
1186     Move<VkImage> m_source;
1187     de::MovePtr<Allocation> m_sourceImageAlloc;
1188     Move<VkImage> m_destination;
1189     de::MovePtr<Allocation> m_destinationImageAlloc;
1190     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
1191     Move<VkSemaphore> m_sparseSemaphore;
1192 };
1193 
CopyImageToImage(Context & context,TestParams params)1194 CopyImageToImage::CopyImageToImage(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
1195 {
1196     const InstanceInterface &vki        = context.getInstanceInterface();
1197     const DeviceInterface &vk           = context.getDeviceInterface();
1198     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1199 
1200     // Create source image
1201     {
1202         VkImageCreateInfo sourceImageParams = {
1203             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
1204             DE_NULL,                                                           // const void* pNext;
1205             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
1206             m_params.src.image.imageType,                                      // VkImageType imageType;
1207             m_params.src.image.format,                                         // VkFormat format;
1208             getExtent3D(m_params.src.image),                                   // VkExtent3D extent;
1209             1u,                                                                // uint32_t mipLevels;
1210             getArraySize(m_params.src.image),                                  // uint32_t arraySize;
1211             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
1212             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
1213             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1214             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1215                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1216             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
1217             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
1218             VK_IMAGE_LAYOUT_UNDEFINED,                                   // VkImageLayout initialLayout;
1219         };
1220 
1221 #ifndef CTS_USES_VULKANSC
1222         if (!params.useSparseBinding)
1223         {
1224 #endif
1225             m_source           = createImage(vk, m_device, &sourceImageParams);
1226             m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
1227                                                *m_allocator, m_params.allocationKind, 0u);
1228             VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
1229                                         m_sourceImageAlloc->getOffset()));
1230 #ifndef CTS_USES_VULKANSC
1231         }
1232         else
1233         {
1234             sourceImageParams.flags |=
1235                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
1236             vk::VkImageFormatProperties imageFormatProperties;
1237             if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
1238                                                            sourceImageParams.imageType, sourceImageParams.tiling,
1239                                                            sourceImageParams.usage, sourceImageParams.flags,
1240                                                            &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1241             {
1242                 TCU_THROW(NotSupportedError, "Image format not supported");
1243             }
1244             m_source = createImage(
1245                 vk, m_device,
1246                 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
1247             m_sparseSemaphore = createSemaphore(vk, m_device);
1248             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
1249                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
1250                                        mapVkFormat(sourceImageParams.format), m_source.get());
1251         }
1252 #endif
1253     }
1254 
1255     // Create destination image
1256     {
1257         const VkImageCreateInfo destinationImageParams = {
1258             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
1259             DE_NULL,                                                           // const void* pNext;
1260             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
1261             m_params.dst.image.imageType,                                      // VkImageType imageType;
1262             m_params.dst.image.format,                                         // VkFormat format;
1263             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
1264             1u,                                                                // uint32_t mipLevels;
1265             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
1266             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
1267             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
1268             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1269             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1270                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1271             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
1272             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
1273             VK_IMAGE_LAYOUT_UNDEFINED,                                   // VkImageLayout initialLayout;
1274         };
1275 
1276         m_destination           = createImage(vk, m_device, &destinationImageParams);
1277         m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::Any,
1278                                                 *m_allocator, m_params.allocationKind, 0u);
1279         VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
1280                                     m_destinationImageAlloc->getOffset()));
1281     }
1282 }
1283 
iterate(void)1284 tcu::TestStatus CopyImageToImage::iterate(void)
1285 {
1286     const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1287     const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1288 
1289     const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1290     const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1291 
1292     m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
1293         new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
1294                               (int)m_params.src.image.extent.depth));
1295     generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
1296                    m_params.src.image.extent.depth, m_params.src.image.fillMode);
1297     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
1298         new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
1299                               (int)m_params.dst.image.extent.depth));
1300     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
1301                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth,
1302                    m_params.clearDestinationWithRed ? FILL_MODE_RED : m_params.dst.image.fillMode);
1303     generateExpectedResult();
1304 
1305     uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1306     uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1307 
1308     const DeviceInterface &vk = m_context.getDeviceInterface();
1309     const VkDevice vkDevice   = m_device;
1310 
1311     VkQueue queue                    = VK_NULL_HANDLE;
1312     VkCommandBuffer cmdbuf           = VK_NULL_HANDLE;
1313     VkCommandPool cmdpool            = VK_NULL_HANDLE;
1314     std::tie(queue, cmdbuf, cmdpool) = activeExecutionCtx();
1315 
1316     std::vector<VkImageCopy> imageCopies;
1317     std::vector<VkImageCopy2KHR> imageCopies2KHR;
1318     for (uint32_t i = 0; i < m_params.regions.size(); i++)
1319     {
1320         VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1321 
1322         // When copying between compressed and uncompressed formats the extent
1323         // members represent the texel dimensions of the source image.
1324         if (srcCompressed)
1325         {
1326             const uint32_t blockWidth  = getBlockWidth(m_params.src.image.format);
1327             const uint32_t blockHeight = getBlockHeight(m_params.src.image.format);
1328 
1329             imageCopy.srcOffset.x *= blockWidth;
1330             imageCopy.extent.width *= blockWidth;
1331 
1332             // VUID-vkCmdCopyImage-srcImage-00146
1333             if (m_params.src.image.imageType != vk::VK_IMAGE_TYPE_1D)
1334             {
1335                 imageCopy.srcOffset.y *= blockHeight;
1336                 imageCopy.extent.height *= blockHeight;
1337             }
1338         }
1339 
1340         if (dstCompressed)
1341         {
1342             const uint32_t blockWidth  = getBlockWidth(m_params.dst.image.format);
1343             const uint32_t blockHeight = getBlockHeight(m_params.dst.image.format);
1344 
1345             imageCopy.dstOffset.x *= blockWidth;
1346 
1347             // VUID-vkCmdCopyImage-dstImage-00152
1348             if (m_params.dst.image.imageType != vk::VK_IMAGE_TYPE_1D)
1349             {
1350                 imageCopy.dstOffset.y *= blockHeight;
1351             }
1352         }
1353 
1354         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1355         {
1356             imageCopies.push_back(imageCopy);
1357         }
1358         else
1359         {
1360             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1361             imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1362         }
1363     }
1364 
1365     VkImageMemoryBarrier imageBarriers[] = {
1366         // source image
1367         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1368          DE_NULL,                                // const void* pNext;
1369          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
1370          VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
1371          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
1372          m_params.src.image.operationLayout,     // VkImageLayout newLayout;
1373          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1374          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1375          m_source.get(),                         // VkImage image;
1376          {
1377              // VkImageSubresourceRange subresourceRange;
1378              getAspectFlags(srcTcuFormat),    // VkImageAspectFlags aspectMask;
1379              0u,                              // uint32_t baseMipLevel;
1380              1u,                              // uint32_t mipLevels;
1381              0u,                              // uint32_t baseArraySlice;
1382              getArraySize(m_params.src.image) // uint32_t arraySize;
1383          }},
1384         // destination image
1385         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1386          DE_NULL,                                // const void* pNext;
1387          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
1388          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
1389          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
1390          m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
1391          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1392          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1393          m_destination.get(),                    // VkImage image;
1394          {
1395              // VkImageSubresourceRange subresourceRange;
1396              getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
1397              0u,                              // uint32_t baseMipLevel;
1398              1u,                              // uint32_t mipLevels;
1399              0u,                              // uint32_t baseArraySlice;
1400              getArraySize(m_params.dst.image) // uint32_t arraySize;
1401          }},
1402     };
1403 
1404     VkCommandBuffer recordingBuf = cmdbuf;
1405     if (m_params.useSecondaryCmdBuffer)
1406     {
1407         beginSecondaryCommandBuffer(vk, *m_secondaryCmdBuffer);
1408         recordingBuf = *m_secondaryCmdBuffer;
1409     }
1410     else
1411     {
1412         beginCommandBuffer(vk, cmdbuf);
1413     }
1414 
1415     vk.cmdPipelineBarrier(recordingBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1416                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1417                           (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1418 
1419     if (m_params.clearDestinationWithRed)
1420     {
1421         VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
1422         VkClearColorValue clearColor;
1423 
1424         clearColor.float32[0] = 1.0f;
1425         clearColor.float32[1] = 0.0f;
1426         clearColor.float32[2] = 0.0f;
1427         clearColor.float32[3] = 1.0f;
1428         vk.cmdClearColorImage(recordingBuf, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u,
1429                               &range);
1430         imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1431         imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1432         vk.cmdPipelineBarrier(recordingBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1433                               (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1434                               (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1435     }
1436 
1437     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1438     {
1439         vk.cmdCopyImage(recordingBuf, m_source.get(), m_params.src.image.operationLayout, m_destination.get(),
1440                         m_params.dst.image.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
1441     }
1442     else
1443     {
1444         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1445         const VkCopyImageInfo2KHR copyImageInfo2KHR = {
1446             VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1447             DE_NULL,                                 // const void* pNext;
1448             m_source.get(),                          // VkImage srcImage;
1449             m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
1450             m_destination.get(),                     // VkImage dstImage;
1451             m_params.dst.image.operationLayout,      // VkImageLayout dstImageLayout;
1452             (uint32_t)imageCopies2KHR.size(),        // uint32_t regionCount;
1453             imageCopies2KHR.data()                   // const VkImageCopy2KHR* pRegions;
1454         };
1455 
1456         vk.cmdCopyImage2(recordingBuf, &copyImageInfo2KHR);
1457     }
1458 
1459     endCommandBuffer(vk, recordingBuf);
1460 
1461     if (m_params.useSecondaryCmdBuffer)
1462     {
1463         beginCommandBuffer(vk, cmdbuf);
1464         vk.cmdExecuteCommands(cmdbuf, 1, &recordingBuf);
1465         endCommandBuffer(vk, cmdbuf);
1466     }
1467 
1468     submitCommandsAndWait(vk, vkDevice, queue, cmdbuf);
1469     m_context.resetCommandPoolForVKSC(vkDevice, cmdpool);
1470 
1471     if (m_params.useSecondaryCmdBuffer)
1472         m_context.resetCommandPoolForVKSC(vkDevice, *m_secondaryCmdPool);
1473 
1474     de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1475 
1476     return checkTestResult(resultTextureLevel->getAccess());
1477 }
1478 
checkTestResult(tcu::ConstPixelBufferAccess result)1479 tcu::TestStatus CopyImageToImage::checkTestResult(tcu::ConstPixelBufferAccess result)
1480 {
1481     const tcu::Vec4 fThreshold(0.0f);
1482     const tcu::UVec4 uThreshold(0u);
1483 
1484     if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1485     {
1486         if (tcu::hasDepthComponent(result.getFormat().order))
1487         {
1488             const tcu::Sampler::DepthStencilMode mode     = tcu::Sampler::MODE_DEPTH;
1489             const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1490             const tcu::ConstPixelBufferAccess expectedResult =
1491                 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1492 
1493             if (isFloatFormat(result.getFormat()))
1494             {
1495                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1496                                                 expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1497                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1498             }
1499             else
1500             {
1501                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1502                                               expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1503                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1504             }
1505         }
1506 
1507         if (tcu::hasStencilComponent(result.getFormat().order))
1508         {
1509             const tcu::Sampler::DepthStencilMode mode       = tcu::Sampler::MODE_STENCIL;
1510             const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1511             const tcu::ConstPixelBufferAccess expectedResult =
1512                 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1513 
1514             if (isFloatFormat(result.getFormat()))
1515             {
1516                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1517                                                 expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1518                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1519             }
1520             else
1521             {
1522                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1523                                               expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1524                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1525             }
1526         }
1527     }
1528     else
1529     {
1530         if (!tcu::bitwiseCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1531                                  m_expectedTextureLevel[0]->getAccess(), result, tcu::COMPARE_LOG_RESULT))
1532             return tcu::TestStatus::fail("CopiesAndBlitting test");
1533     }
1534 
1535     return tcu::TestStatus::pass("CopiesAndBlitting test");
1536 }
1537 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)1538 void CopyImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
1539                                                 CopyRegion region, uint32_t mipLevel)
1540 {
1541     DE_UNREF(mipLevel);
1542 
1543     VkOffset3D srcOffset = region.imageCopy.srcOffset;
1544     VkOffset3D dstOffset = region.imageCopy.dstOffset;
1545     VkExtent3D extent    = region.imageCopy.extent;
1546 
1547     if (region.imageCopy.dstSubresource.baseArrayLayer > region.imageCopy.srcSubresource.baseArrayLayer)
1548     {
1549         dstOffset.z  = srcOffset.z;
1550         extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1551     }
1552 
1553     if (region.imageCopy.dstSubresource.baseArrayLayer < region.imageCopy.srcSubresource.baseArrayLayer)
1554     {
1555         srcOffset.z  = dstOffset.z;
1556         extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1557     }
1558 
1559     if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1560     {
1561         DE_ASSERT(src.getFormat() == dst.getFormat());
1562 
1563         // Copy depth.
1564         if (tcu::hasDepthComponent(src.getFormat().order))
1565         {
1566             const tcu::ConstPixelBufferAccess srcSubRegion =
1567                 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
1568                                                                  extent.width, extent.height, extent.depth),
1569                                                tcu::Sampler::MODE_DEPTH);
1570             const tcu::PixelBufferAccess dstSubRegion =
1571                 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
1572                                                                  extent.width, extent.height, extent.depth),
1573                                                tcu::Sampler::MODE_DEPTH);
1574             tcu::copy(dstSubRegion, srcSubRegion);
1575         }
1576 
1577         // Copy stencil.
1578         if (tcu::hasStencilComponent(src.getFormat().order))
1579         {
1580             const tcu::ConstPixelBufferAccess srcSubRegion =
1581                 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
1582                                                                  extent.width, extent.height, extent.depth),
1583                                                tcu::Sampler::MODE_STENCIL);
1584             const tcu::PixelBufferAccess dstSubRegion =
1585                 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
1586                                                                  extent.width, extent.height, extent.depth),
1587                                                tcu::Sampler::MODE_STENCIL);
1588             tcu::copy(dstSubRegion, srcSubRegion);
1589         }
1590     }
1591     else
1592     {
1593         const tcu::ConstPixelBufferAccess srcSubRegion =
1594             tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1595         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1596         const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1597         const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
1598             dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1599 
1600         tcu::copy(dstSubRegion, srcSubRegion);
1601     }
1602 }
1603 
1604 class CopyImageToImageTestCase : public vkt::TestCase
1605 {
1606 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)1607     CopyImageToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
1608         : vkt::TestCase(testCtx, name)
1609         , m_params(params)
1610     {
1611     }
1612 
createInstance(Context & context) const1613     virtual TestInstance *createInstance(Context &context) const
1614     {
1615         return new CopyImageToImage(context, m_params);
1616     }
1617 
checkSupport(Context & context) const1618     virtual void checkSupport(Context &context) const
1619     {
1620         if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1621         {
1622             if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1623                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1624         }
1625 
1626 #ifndef CTS_USES_VULKANSC
1627         if (m_params.src.image.format == VK_FORMAT_A8_UNORM_KHR ||
1628             m_params.dst.image.format == VK_FORMAT_A8_UNORM_KHR ||
1629             m_params.src.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR ||
1630             m_params.dst.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
1631             context.requireDeviceFunctionality("VK_KHR_maintenance5");
1632 #endif // CTS_USES_VULKANSC
1633 
1634         checkExtensionSupport(context, m_params.extensionFlags);
1635 
1636         const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1637         VkImageFormatProperties properties;
1638 
1639         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
1640                  context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
1641                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
1642                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1643             (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
1644                  context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
1645                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
1646                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1647         {
1648             TCU_THROW(NotSupportedError, "Format not supported");
1649         }
1650 
1651         // Check maxImageDimension1D
1652         {
1653             if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D &&
1654                 m_params.src.image.extent.width > limits.maxImageDimension1D)
1655                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1656 
1657             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D &&
1658                 m_params.dst.image.extent.width > limits.maxImageDimension1D)
1659                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1660         }
1661 
1662         // Check maxImageDimension2D
1663         {
1664             if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D &&
1665                 (m_params.src.image.extent.width > limits.maxImageDimension2D ||
1666                  m_params.src.image.extent.height > limits.maxImageDimension2D))
1667             {
1668                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1669             }
1670 
1671             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D &&
1672                 (m_params.dst.image.extent.width > limits.maxImageDimension2D ||
1673                  m_params.dst.image.extent.height > limits.maxImageDimension2D))
1674             {
1675                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1676             }
1677         }
1678 
1679         // Check maxImageDimension3D
1680         {
1681             if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D &&
1682                 (m_params.src.image.extent.width > limits.maxImageDimension3D ||
1683                  m_params.src.image.extent.height > limits.maxImageDimension3D ||
1684                  m_params.src.image.extent.depth > limits.maxImageDimension3D))
1685             {
1686                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1687             }
1688 
1689             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D &&
1690                 (m_params.dst.image.extent.width > limits.maxImageDimension3D ||
1691                  m_params.dst.image.extent.height > limits.maxImageDimension3D ||
1692                  m_params.src.image.extent.depth > limits.maxImageDimension3D))
1693             {
1694                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1695             }
1696         }
1697     }
1698 
1699 private:
1700     TestParams m_params;
1701 };
1702 
1703 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1704 {
1705 public:
1706     CopyImageToImageMipmap(Context &context, TestParams params);
1707     virtual tcu::TestStatus iterate(void);
1708 
1709 protected:
1710     tcu::TestStatus checkResult(tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1711 
1712 private:
1713     Move<VkImage> m_source;
1714     de::MovePtr<Allocation> m_sourceImageAlloc;
1715     Move<VkImage> m_destination;
1716     de::MovePtr<Allocation> m_destinationImageAlloc;
1717     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
1718     Move<VkSemaphore> m_sparseSemaphore;
1719 
1720     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
1721                                           CopyRegion region, uint32_t mipLevel = 0u);
1722 };
1723 
CopyImageToImageMipmap(Context & context,TestParams params)1724 CopyImageToImageMipmap::CopyImageToImageMipmap(Context &context, TestParams params)
1725     : CopiesAndBlittingTestInstance(context, params)
1726 {
1727     const InstanceInterface &vki        = context.getInstanceInterface();
1728     const DeviceInterface &vk           = context.getDeviceInterface();
1729     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1730 
1731     // Create source image
1732     {
1733         VkImageCreateInfo sourceImageParams = {
1734             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
1735             DE_NULL,                                                           // const void* pNext;
1736             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
1737             m_params.src.image.imageType,                                      // VkImageType imageType;
1738             m_params.src.image.format,                                         // VkFormat format;
1739             getExtent3D(m_params.src.image),                                   // VkExtent3D extent;
1740             params.mipLevels,                                                  // uint32_t mipLevels;
1741             getArraySize(m_params.src.image),                                  // uint32_t arraySize;
1742             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
1743             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
1744             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1745             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1746                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1747             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
1748             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
1749             VK_IMAGE_LAYOUT_UNDEFINED,                                   // VkImageLayout initialLayout;
1750         };
1751 
1752 #ifndef CTS_USES_VULKANSC
1753         if (!params.useSparseBinding)
1754         {
1755 #endif
1756             m_source           = createImage(vk, m_device, &sourceImageParams);
1757             m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
1758                                                *m_allocator, m_params.allocationKind, 0u);
1759             VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
1760                                         m_sourceImageAlloc->getOffset()));
1761 #ifndef CTS_USES_VULKANSC
1762         }
1763         else
1764         {
1765             sourceImageParams.flags |=
1766                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
1767             vk::VkImageFormatProperties imageFormatProperties;
1768             if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
1769                                                            sourceImageParams.imageType, sourceImageParams.tiling,
1770                                                            sourceImageParams.usage, sourceImageParams.flags,
1771                                                            &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1772             {
1773                 TCU_THROW(NotSupportedError, "Image format not supported");
1774             }
1775             m_source = createImage(
1776                 vk, m_device,
1777                 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
1778             m_sparseSemaphore = createSemaphore(vk, m_device);
1779             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
1780                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
1781                                        mapVkFormat(sourceImageParams.format), m_source.get());
1782         }
1783 #endif
1784     }
1785 
1786     // Create destination image
1787     {
1788         const VkImageCreateInfo destinationImageParams = {
1789             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
1790             DE_NULL,                                                           // const void* pNext;
1791             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
1792             m_params.dst.image.imageType,                                      // VkImageType imageType;
1793             m_params.dst.image.format,                                         // VkFormat format;
1794             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
1795             params.mipLevels,                                                  // uint32_t mipLevels;
1796             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
1797             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
1798             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
1799             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1800             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
1801                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1802             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
1803             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
1804             VK_IMAGE_LAYOUT_UNDEFINED,                                   // VkImageLayout initialLayout;
1805         };
1806 
1807         m_destination           = createImage(vk, m_device, &destinationImageParams);
1808         m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::Any,
1809                                                 *m_allocator, m_params.allocationKind, 0u);
1810         VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
1811                                     m_destinationImageAlloc->getOffset()));
1812     }
1813 }
1814 
iterate(void)1815 tcu::TestStatus CopyImageToImageMipmap::iterate(void)
1816 {
1817     const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1818     const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1819 
1820     m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
1821         new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
1822                               (int)m_params.src.image.extent.depth));
1823     generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
1824                    m_params.src.image.extent.depth, m_params.src.image.fillMode);
1825     uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1826 
1827     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
1828         new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
1829                               (int)m_params.dst.image.extent.depth));
1830     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
1831                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1832     uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1833 
1834     const DeviceInterface &vk                   = m_context.getDeviceInterface();
1835     const VkDevice vkDevice                     = m_device;
1836     VkQueue queue                               = VK_NULL_HANDLE;
1837     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
1838     VkCommandPool commandPool                   = VK_NULL_HANDLE;
1839     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
1840 
1841     std::vector<VkImageCopy> imageCopies;
1842     std::vector<VkImageCopy2KHR> imageCopies2KHR;
1843     for (uint32_t i = 0; i < m_params.regions.size(); i++)
1844     {
1845         VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1846         uint32_t blockWidth, blockHeight;
1847         std::tie(blockWidth, blockHeight) = m_params.src.image.texelBlockDimensions();
1848         if (blockWidth != 1 || blockHeight != 1)
1849         {
1850             imageCopy.srcOffset.x *= blockWidth;
1851             imageCopy.srcOffset.y *= blockHeight;
1852             // When copying between compressed and uncompressed formats the extent
1853             // members represent the texel dimensions of the source image.
1854             imageCopy.extent.width *= blockWidth;
1855             imageCopy.extent.height *= blockHeight;
1856         }
1857 
1858         std::tie(blockWidth, blockHeight) = m_params.dst.image.texelBlockDimensions();
1859         if (blockWidth != 1 || blockHeight != 1)
1860         {
1861             imageCopy.dstOffset.x *= blockWidth;
1862             imageCopy.dstOffset.y *= blockHeight;
1863         }
1864 
1865         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1866         {
1867             imageCopies.push_back(imageCopy);
1868         }
1869         else
1870         {
1871             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1872             imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1873         }
1874     }
1875 
1876     VkImageMemoryBarrier imageBarriers[] = {
1877         // source image
1878         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1879          DE_NULL,                                // const void* pNext;
1880          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
1881          VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
1882          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
1883          m_params.src.image.operationLayout,     // VkImageLayout newLayout;
1884          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1885          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1886          m_source.get(),                         // VkImage image;
1887          {
1888              // VkImageSubresourceRange subresourceRange;
1889              getAspectFlags(srcTcuFormat),    // VkImageAspectFlags aspectMask;
1890              0u,                              // uint32_t baseMipLevel;
1891              m_params.mipLevels,              // uint32_t mipLevels;
1892              0u,                              // uint32_t baseArraySlice;
1893              getArraySize(m_params.src.image) // uint32_t arraySize;
1894          }},
1895         // destination image
1896         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1897          DE_NULL,                                // const void* pNext;
1898          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
1899          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
1900          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
1901          m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
1902          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
1903          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
1904          m_destination.get(),                    // VkImage image;
1905          {
1906              // VkImageSubresourceRange subresourceRange;
1907              getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
1908              0u,                              // uint32_t baseMipLevel;
1909              m_params.mipLevels,              // uint32_t mipLevels;
1910              0u,                              // uint32_t baseArraySlice;
1911              getArraySize(m_params.dst.image) // uint32_t arraySize;
1912          }},
1913     };
1914 
1915     beginCommandBuffer(vk, commandBuffer);
1916     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1917                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
1918                           (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1919 
1920     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
1921     {
1922         vk.cmdCopyImage(commandBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(),
1923                         m_params.dst.image.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
1924     }
1925     else
1926     {
1927         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
1928         const VkCopyImageInfo2KHR copyImageInfo2KHR = {
1929             VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1930             DE_NULL,                                 // const void* pNext;
1931             m_source.get(),                          // VkImage srcImage;
1932             m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
1933             m_destination.get(),                     // VkImage dstImage;
1934             m_params.dst.image.operationLayout,      // VkImageLayout dstImageLayout;
1935             (uint32_t)imageCopies2KHR.size(),        // uint32_t regionCount;
1936             imageCopies2KHR.data()                   // const VkImageCopy2KHR* pRegions;
1937         };
1938 
1939         vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
1940     }
1941 
1942     endCommandBuffer(vk, commandBuffer);
1943 
1944     submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
1945     m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
1946 
1947     for (uint32_t miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1948     {
1949         de::MovePtr<tcu::TextureLevel> resultTextureLevel   = readImage(*m_destination, m_params.dst.image, miplevel);
1950         de::MovePtr<tcu::TextureLevel> expectedTextureLevel = readImage(*m_source, m_params.src.image, miplevel);
1951 
1952         tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1953         if (result.getCode() != QP_TEST_RESULT_PASS)
1954             return result;
1955     }
1956     return tcu::TestStatus::pass("Pass");
1957 }
1958 
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1959 tcu::TestStatus CopyImageToImageMipmap::checkResult(tcu::ConstPixelBufferAccess result,
1960                                                     tcu::ConstPixelBufferAccess expected)
1961 {
1962     const tcu::Vec4 fThreshold(0.0f);
1963     const tcu::UVec4 uThreshold(0u);
1964 
1965     if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1966     {
1967         if (tcu::hasDepthComponent(result.getFormat().order))
1968         {
1969             const tcu::Sampler::DepthStencilMode mode        = tcu::Sampler::MODE_DEPTH;
1970             const tcu::ConstPixelBufferAccess depthResult    = tcu::getEffectiveDepthStencilAccess(result, mode);
1971             const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1972 
1973             if (isFloatFormat(result.getFormat()))
1974             {
1975                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1976                                                 expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1977                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1978             }
1979             else
1980             {
1981                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1982                                               expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1983                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1984             }
1985         }
1986 
1987         if (tcu::hasStencilComponent(result.getFormat().order))
1988         {
1989             const tcu::Sampler::DepthStencilMode mode        = tcu::Sampler::MODE_STENCIL;
1990             const tcu::ConstPixelBufferAccess stencilResult  = tcu::getEffectiveDepthStencilAccess(result, mode);
1991             const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1992 
1993             if (isFloatFormat(result.getFormat()))
1994             {
1995                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
1996                                                 expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1997                     return tcu::TestStatus::fail("CopiesAndBlitting test");
1998             }
1999             else
2000             {
2001                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2002                                               expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
2003                     return tcu::TestStatus::fail("CopiesAndBlitting test");
2004             }
2005         }
2006     }
2007     else
2008     {
2009         if (isFloatFormat(result.getFormat()))
2010         {
2011             if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2012                                             expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
2013                 return tcu::TestStatus::fail("CopiesAndBlitting test");
2014         }
2015         else if (isSnormFormat(mapTextureFormat(result.getFormat())))
2016         {
2017             // There may be an ambiguity between two possible binary representations of 1.0.
2018             // Get rid of that by expanding the data to floats and re-normalizing again.
2019 
2020             tcu::TextureLevel resultSnorm(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
2021             {
2022                 tcu::TextureLevel resultFloat(
2023                     tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT),
2024                     resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
2025 
2026                 tcu::copy(resultFloat.getAccess(), result);
2027                 tcu::copy(resultSnorm, resultFloat.getAccess());
2028             }
2029 
2030             tcu::TextureLevel expectedSnorm(expected.getFormat(), expected.getWidth(), expected.getHeight(),
2031                                             expected.getDepth());
2032 
2033             {
2034                 tcu::TextureLevel expectedFloat(
2035                     tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT),
2036                     expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
2037 
2038                 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
2039                 tcu::copy(expectedSnorm, expectedFloat.getAccess());
2040             }
2041 
2042             if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison",
2043                                           expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold,
2044                                           tcu::COMPARE_LOG_RESULT))
2045                 return tcu::TestStatus::fail("CopiesAndBlitting test");
2046         }
2047         else
2048         {
2049             if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected,
2050                                           result, uThreshold, tcu::COMPARE_LOG_RESULT))
2051                 return tcu::TestStatus::fail("CopiesAndBlitting test");
2052         }
2053     }
2054 
2055     return tcu::TestStatus::pass("CopiesAndBlitting test");
2056 }
2057 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2058 void CopyImageToImageMipmap::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2059                                                       CopyRegion region, uint32_t mipLevel)
2060 {
2061     DE_UNREF(mipLevel);
2062 
2063     VkOffset3D srcOffset = region.imageCopy.srcOffset;
2064     VkOffset3D dstOffset = region.imageCopy.dstOffset;
2065     VkExtent3D extent    = region.imageCopy.extent;
2066 
2067     if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
2068     {
2069         dstOffset.z  = srcOffset.z;
2070         extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
2071     }
2072     if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
2073     {
2074         srcOffset.z  = dstOffset.z;
2075         extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
2076     }
2077 
2078     if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2079     {
2080         DE_ASSERT(src.getFormat() == dst.getFormat());
2081 
2082         // Copy depth.
2083         if (tcu::hasDepthComponent(src.getFormat().order))
2084         {
2085             const tcu::ConstPixelBufferAccess srcSubRegion =
2086                 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
2087                                                                  extent.width, extent.height, extent.depth),
2088                                                tcu::Sampler::MODE_DEPTH);
2089             const tcu::PixelBufferAccess dstSubRegion =
2090                 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
2091                                                                  extent.width, extent.height, extent.depth),
2092                                                tcu::Sampler::MODE_DEPTH);
2093             tcu::copy(dstSubRegion, srcSubRegion);
2094         }
2095 
2096         // Copy stencil.
2097         if (tcu::hasStencilComponent(src.getFormat().order))
2098         {
2099             const tcu::ConstPixelBufferAccess srcSubRegion =
2100                 getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z,
2101                                                                  extent.width, extent.height, extent.depth),
2102                                                tcu::Sampler::MODE_STENCIL);
2103             const tcu::PixelBufferAccess dstSubRegion =
2104                 getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z,
2105                                                                  extent.width, extent.height, extent.depth),
2106                                                tcu::Sampler::MODE_STENCIL);
2107             tcu::copy(dstSubRegion, srcSubRegion);
2108         }
2109     }
2110     else
2111     {
2112         const tcu::ConstPixelBufferAccess srcSubRegion =
2113             tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
2114         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
2115         const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
2116         const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
2117             dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
2118 
2119         tcu::copy(dstSubRegion, srcSubRegion);
2120     }
2121 }
2122 
2123 class CopyImageToImageMipmapTestCase : public vkt::TestCase
2124 {
2125 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2126     CopyImageToImageMipmapTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2127         : vkt::TestCase(testCtx, name)
2128         , m_params(params)
2129     {
2130     }
2131 
createInstance(Context & context) const2132     virtual TestInstance *createInstance(Context &context) const
2133     {
2134         return new CopyImageToImageMipmap(context, m_params);
2135     }
2136 
checkSupport(Context & context) const2137     virtual void checkSupport(Context &context) const
2138     {
2139         if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
2140         {
2141             if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
2142                 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
2143         }
2144 
2145         checkExtensionSupport(context, m_params.extensionFlags);
2146 
2147         const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
2148         VkImageFormatProperties properties;
2149 
2150         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
2151                  context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
2152                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2153                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2154             (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
2155                  context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
2156                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
2157                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2158         {
2159             TCU_THROW(NotSupportedError, "Format not supported");
2160         }
2161 
2162         // Check maxImageDimension1D
2163         {
2164             if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D &&
2165                 m_params.src.image.extent.width > limits.maxImageDimension1D)
2166                 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
2167 
2168             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D &&
2169                 m_params.dst.image.extent.width > limits.maxImageDimension1D)
2170                 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
2171         }
2172 
2173         // Check maxImageDimension2D
2174         {
2175             if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D &&
2176                 (m_params.src.image.extent.width > limits.maxImageDimension2D ||
2177                  m_params.src.image.extent.height > limits.maxImageDimension2D))
2178             {
2179                 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
2180             }
2181 
2182             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D &&
2183                 (m_params.dst.image.extent.width > limits.maxImageDimension2D ||
2184                  m_params.dst.image.extent.height > limits.maxImageDimension2D))
2185             {
2186                 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
2187             }
2188         }
2189 
2190         // Check maxImageDimension3D
2191         {
2192             if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D &&
2193                 (m_params.src.image.extent.width > limits.maxImageDimension3D ||
2194                  m_params.src.image.extent.height > limits.maxImageDimension3D ||
2195                  m_params.src.image.extent.depth > limits.maxImageDimension3D))
2196             {
2197                 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
2198             }
2199 
2200             if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D &&
2201                 (m_params.dst.image.extent.width > limits.maxImageDimension3D ||
2202                  m_params.dst.image.extent.height > limits.maxImageDimension3D ||
2203                  m_params.src.image.extent.depth > limits.maxImageDimension3D))
2204             {
2205                 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
2206             }
2207         }
2208     }
2209 
2210 private:
2211     TestParams m_params;
2212 };
2213 
2214 // Copy from buffer to buffer.
2215 
2216 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
2217 {
2218 public:
2219     CopyBufferToBuffer(Context &context, TestParams params);
2220     virtual tcu::TestStatus iterate(void);
2221 
2222 private:
2223     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion,
2224                                           uint32_t mipLevel = 0u);
2225     Move<VkBuffer> m_source;
2226     de::MovePtr<Allocation> m_sourceBufferAlloc;
2227     Move<VkBuffer> m_destination;
2228     de::MovePtr<Allocation> m_destinationBufferAlloc;
2229 };
2230 
CopyBufferToBuffer(Context & context,TestParams params)2231 CopyBufferToBuffer::CopyBufferToBuffer(Context &context, TestParams params)
2232     : CopiesAndBlittingTestInstance(context, params)
2233 {
2234     const InstanceInterface &vki        = context.getInstanceInterface();
2235     const DeviceInterface &vk           = context.getDeviceInterface();
2236     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2237 
2238     // Create source buffer
2239     {
2240         const VkBufferCreateInfo sourceBufferParams = {
2241             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2242             DE_NULL,                              // const void* pNext;
2243             0u,                                   // VkBufferCreateFlags flags;
2244             m_params.src.buffer.size,             // VkDeviceSize size;
2245             VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
2246             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
2247             0u,                                   // uint32_t queueFamilyIndexCount;
2248             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
2249         };
2250 
2251         m_source            = createBuffer(vk, m_device, &sourceBufferParams);
2252         m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::HostVisible,
2253                                              *m_allocator, m_params.allocationKind);
2254         VK_CHECK(vk.bindBufferMemory(m_device, *m_source, m_sourceBufferAlloc->getMemory(),
2255                                      m_sourceBufferAlloc->getOffset()));
2256     }
2257 
2258     // Create destination buffer
2259     {
2260         const VkBufferCreateInfo destinationBufferParams = {
2261             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2262             DE_NULL,                              // const void* pNext;
2263             0u,                                   // VkBufferCreateFlags flags;
2264             m_params.dst.buffer.size,             // VkDeviceSize size;
2265             VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
2266             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
2267             0u,                                   // uint32_t queueFamilyIndexCount;
2268             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
2269         };
2270 
2271         m_destination = createBuffer(vk, m_device, &destinationBufferParams);
2272         m_destinationBufferAlloc =
2273             allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::HostVisible,
2274                            *m_allocator, m_params.allocationKind);
2275         VK_CHECK(vk.bindBufferMemory(m_device, *m_destination, m_destinationBufferAlloc->getMemory(),
2276                                      m_destinationBufferAlloc->getOffset()));
2277     }
2278 }
2279 
iterate(void)2280 tcu::TestStatus CopyBufferToBuffer::iterate(void)
2281 {
2282     const int srcLevelWidth = (int)(m_params.src.buffer.size /
2283                                     4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
2284     m_sourceTextureLevel =
2285         de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2286     generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2287 
2288     const int dstLevelWidth = (int)(m_params.dst.buffer.size / 4);
2289     m_destinationTextureLevel =
2290         de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2291     generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2292 
2293     generateExpectedResult();
2294 
2295     uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2296     uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2297 
2298     const DeviceInterface &vk                   = m_context.getDeviceInterface();
2299     VkQueue queue                               = VK_NULL_HANDLE;
2300     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
2301     VkCommandPool commandPool                   = VK_NULL_HANDLE;
2302     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2303 
2304     const VkBufferMemoryBarrier srcBufferBarrier = {
2305         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2306         DE_NULL,                                 // const void* pNext;
2307         VK_ACCESS_HOST_WRITE_BIT,                // VkAccessFlags srcAccessMask;
2308         VK_ACCESS_TRANSFER_READ_BIT,             // VkAccessFlags dstAccessMask;
2309         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t srcQueueFamilyIndex;
2310         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t dstQueueFamilyIndex;
2311         *m_source,                               // VkBuffer buffer;
2312         0u,                                      // VkDeviceSize offset;
2313         m_params.src.buffer.size                 // VkDeviceSize size;
2314     };
2315 
2316     const VkBufferMemoryBarrier dstBufferBarrier = {
2317         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2318         DE_NULL,                                 // const void* pNext;
2319         VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags srcAccessMask;
2320         VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags dstAccessMask;
2321         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t srcQueueFamilyIndex;
2322         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t dstQueueFamilyIndex;
2323         *m_destination,                          // VkBuffer buffer;
2324         0u,                                      // VkDeviceSize offset;
2325         m_params.dst.buffer.size                 // VkDeviceSize size;
2326     };
2327 
2328     std::vector<VkBufferCopy> bufferCopies;
2329     std::vector<VkBufferCopy2KHR> bufferCopies2KHR;
2330     for (uint32_t i = 0; i < m_params.regions.size(); i++)
2331     {
2332         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2333         {
2334             bufferCopies.push_back(m_params.regions[i].bufferCopy);
2335         }
2336         else
2337         {
2338             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2339             bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2340         }
2341     }
2342 
2343     beginCommandBuffer(vk, commandBuffer);
2344     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2345                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &srcBufferBarrier, 0,
2346                           (const VkImageMemoryBarrier *)DE_NULL);
2347 
2348     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2349     {
2350         vk.cmdCopyBuffer(commandBuffer, m_source.get(), m_destination.get(), (uint32_t)m_params.regions.size(),
2351                          &bufferCopies[0]);
2352     }
2353     else
2354     {
2355         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2356         const VkCopyBufferInfo2KHR copyBufferInfo2KHR = {
2357             VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR, // VkStructureType sType;
2358             DE_NULL,                                  // const void* pNext;
2359             m_source.get(),                           // VkBuffer srcBuffer;
2360             m_destination.get(),                      // VkBuffer dstBuffer;
2361             (uint32_t)m_params.regions.size(),        // uint32_t regionCount;
2362             &bufferCopies2KHR[0]                      // const VkBufferCopy2KHR* pRegions;
2363         };
2364 
2365         vk.cmdCopyBuffer2(commandBuffer, &copyBufferInfo2KHR);
2366     }
2367 
2368     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2369                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &dstBufferBarrier, 0,
2370                           (const VkImageMemoryBarrier *)DE_NULL);
2371     endCommandBuffer(vk, commandBuffer);
2372     submitCommandsAndWait(vk, m_device, queue, commandBuffer);
2373     m_context.resetCommandPoolForVKSC(m_device, commandPool);
2374 
2375     // Read buffer data
2376     de::MovePtr<tcu::TextureLevel> resultLevel(
2377         new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2378     invalidateAlloc(vk, m_device, *m_destinationBufferAlloc);
2379     tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(),
2380                                                         m_destinationBufferAlloc->getHostPtr()));
2381 
2382     return checkTestResult(resultLevel->getAccess());
2383 }
2384 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2385 void CopyBufferToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2386                                                   CopyRegion region, uint32_t mipLevel)
2387 {
2388     DE_UNREF(mipLevel);
2389 
2390     deMemcpy((uint8_t *)dst.getDataPtr() + region.bufferCopy.dstOffset,
2391              (uint8_t *)src.getDataPtr() + region.bufferCopy.srcOffset, (size_t)region.bufferCopy.size);
2392 }
2393 
2394 class BufferToBufferTestCase : public vkt::TestCase
2395 {
2396 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2397     BufferToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2398         : vkt::TestCase(testCtx, name)
2399         , m_params(params)
2400     {
2401     }
2402 
createInstance(Context & context) const2403     virtual TestInstance *createInstance(Context &context) const
2404     {
2405         return new CopyBufferToBuffer(context, m_params);
2406     }
2407 
checkSupport(Context & context) const2408     virtual void checkSupport(Context &context) const
2409     {
2410         checkExtensionSupport(context, m_params.extensionFlags);
2411     }
2412 
2413 private:
2414     TestParams m_params;
2415 };
2416 
2417 // Copy from image to buffer.
2418 
2419 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2420 {
2421 public:
2422     CopyImageToBuffer(Context &context, TestParams testParams);
2423     virtual tcu::TestStatus iterate(void);
2424 
2425 private:
2426     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2427                                           CopyRegion region, uint32_t mipLevel = 0u);
2428 
2429     tcu::TextureFormat m_textureFormat;
2430     VkDeviceSize m_bufferSize;
2431 
2432     Move<VkImage> m_source;
2433     de::MovePtr<Allocation> m_sourceImageAlloc;
2434     Move<VkBuffer> m_destination;
2435     de::MovePtr<Allocation> m_destinationBufferAlloc;
2436 
2437     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
2438     Move<VkSemaphore> m_sparseSemaphore;
2439 };
2440 
CopyImageToBuffer(Context & context,TestParams testParams)2441 CopyImageToBuffer::CopyImageToBuffer(Context &context, TestParams testParams)
2442     : CopiesAndBlittingTestInstance(context, testParams)
2443     , m_textureFormat(mapVkFormat(testParams.src.image.format))
2444     , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2445 {
2446     const InstanceInterface &vki        = context.getInstanceInterface();
2447     const DeviceInterface &vk           = context.getDeviceInterface();
2448     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2449 
2450     // Create source image
2451     {
2452         VkImageCreateInfo sourceImageParams = {
2453             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
2454             DE_NULL,                                                           // const void* pNext;
2455             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
2456             m_params.src.image.imageType,                                      // VkImageType imageType;
2457             m_params.src.image.format,                                         // VkFormat format;
2458             getExtent3D(m_params.src.image),                                   // VkExtent3D extent;
2459             1u,                                                                // uint32_t mipLevels;
2460             getArraySize(m_params.src.image),                                  // uint32_t arraySize;
2461             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
2462             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
2463             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2464             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
2465             0u,                                                                // uint32_t queueFamilyIndexCount;
2466             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
2467             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
2468         };
2469 
2470 #ifndef CTS_USES_VULKANSC
2471         if (!testParams.useSparseBinding)
2472         {
2473 #endif
2474             m_source           = createImage(vk, m_device, &sourceImageParams);
2475             m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
2476                                                *m_allocator, m_params.allocationKind, 0u);
2477             VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
2478                                         m_sourceImageAlloc->getOffset()));
2479 #ifndef CTS_USES_VULKANSC
2480         }
2481         else
2482         {
2483             sourceImageParams.flags |=
2484                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
2485             vk::VkImageFormatProperties imageFormatProperties;
2486             if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
2487                                                            sourceImageParams.imageType, sourceImageParams.tiling,
2488                                                            sourceImageParams.usage, sourceImageParams.flags,
2489                                                            &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
2490             {
2491                 TCU_THROW(NotSupportedError, "Image format not supported");
2492             }
2493             m_source = createImage(
2494                 vk, m_device,
2495                 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
2496             m_sparseSemaphore = createSemaphore(vk, m_device);
2497             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
2498                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
2499                                        mapVkFormat(sourceImageParams.format), m_source.get());
2500         }
2501 #endif
2502     }
2503 
2504     // Create destination buffer
2505     {
2506         const VkBufferCreateInfo destinationBufferParams = {
2507             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2508             DE_NULL,                              // const void* pNext;
2509             0u,                                   // VkBufferCreateFlags flags;
2510             m_bufferSize,                         // VkDeviceSize size;
2511             VK_BUFFER_USAGE_TRANSFER_DST_BIT,     // VkBufferUsageFlags usage;
2512             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
2513             0u,                                   // uint32_t queueFamilyIndexCount;
2514             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
2515         };
2516 
2517         m_destination = createBuffer(vk, m_device, &destinationBufferParams);
2518         m_destinationBufferAlloc =
2519             allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_destination, MemoryRequirement::HostVisible,
2520                            *m_allocator, m_params.allocationKind);
2521         VK_CHECK(vk.bindBufferMemory(m_device, *m_destination, m_destinationBufferAlloc->getMemory(),
2522                                      m_destinationBufferAlloc->getOffset()));
2523     }
2524 }
2525 
iterate(void)2526 tcu::TestStatus CopyImageToBuffer::iterate(void)
2527 {
2528     m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
2529         new tcu::TextureLevel(m_textureFormat, m_params.src.image.extent.width, m_params.src.image.extent.height,
2530                               m_params.src.image.extent.depth));
2531     generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
2532                    m_params.src.image.extent.depth, m_params.src.image.fillMode);
2533     m_destinationTextureLevel =
2534         de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2535     generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1,
2536                    m_params.dst.buffer.fillMode);
2537 
2538     generateExpectedResult();
2539 
2540     uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2541     uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2542 
2543     const DeviceInterface &vk                   = m_context.getDeviceInterface();
2544     const VkDevice vkDevice                     = m_device;
2545     VkQueue queue                               = VK_NULL_HANDLE;
2546     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
2547     VkCommandPool commandPool                   = VK_NULL_HANDLE;
2548     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2549 
2550     // Barriers for copying image to buffer
2551     const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2552                                                DE_NULL,                                // const void* pNext;
2553                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
2554                                                VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
2555                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
2556                                                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,   // VkImageLayout newLayout;
2557                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
2558                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
2559                                                *m_source,                              // VkImage image;
2560                                                {
2561                                                    // VkImageSubresourceRange subresourceRange;
2562                                                    getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2563                                                    0u,                              // uint32_t baseMipLevel;
2564                                                    1u,                              // uint32_t mipLevels;
2565                                                    0u,                              // uint32_t baseArraySlice;
2566                                                    getArraySize(m_params.src.image) // uint32_t arraySize;
2567                                                }};
2568 
2569     const VkBufferMemoryBarrier bufferBarrier = {
2570         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2571         DE_NULL,                                 // const void* pNext;
2572         VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags srcAccessMask;
2573         VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags dstAccessMask;
2574         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t srcQueueFamilyIndex;
2575         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t dstQueueFamilyIndex;
2576         *m_destination,                          // VkBuffer buffer;
2577         0u,                                      // VkDeviceSize offset;
2578         m_bufferSize                             // VkDeviceSize size;
2579     };
2580 
2581     // Copy from image to buffer
2582     std::vector<VkBufferImageCopy> bufferImageCopies;
2583     std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2584     for (uint32_t i = 0; i < m_params.regions.size(); i++)
2585     {
2586         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2587         {
2588             bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2589         }
2590         else
2591         {
2592             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2593             bufferImageCopies2KHR.push_back(
2594                 convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2595         }
2596     }
2597 
2598     beginCommandBuffer(vk, commandBuffer);
2599     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2600                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
2601                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
2602 
2603     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2604     {
2605         vk.cmdCopyImageToBuffer(commandBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2606                                 m_destination.get(), (uint32_t)m_params.regions.size(), &bufferImageCopies[0]);
2607     }
2608     else
2609     {
2610         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2611         const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR = {
2612             VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2613             DE_NULL,                                           // const void* pNext;
2614             m_source.get(),                                    // VkImage srcImage;
2615             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,              // VkImageLayout srcImageLayout;
2616             m_destination.get(),                               // VkBuffer dstBuffer;
2617             (uint32_t)m_params.regions.size(),                 // uint32_t regionCount;
2618             &bufferImageCopies2KHR[0]                          // const VkBufferImageCopy2KHR* pRegions;
2619         };
2620 
2621         vk.cmdCopyImageToBuffer2(commandBuffer, &copyImageToBufferInfo2KHR);
2622     }
2623 
2624     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2625                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 0,
2626                           (const VkImageMemoryBarrier *)DE_NULL);
2627     endCommandBuffer(vk, commandBuffer);
2628 
2629     submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
2630     m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
2631 
2632     // Read buffer data
2633     de::MovePtr<tcu::TextureLevel> resultLevel(
2634         new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2635     invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2636     tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(),
2637                                                         m_destinationBufferAlloc->getHostPtr()));
2638 
2639     return checkTestResult(resultLevel->getAccess());
2640 }
2641 
2642 class CopyImageToBufferTestCase : public vkt::TestCase
2643 {
2644 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2645     CopyImageToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2646         : vkt::TestCase(testCtx, name)
2647         , m_params(params)
2648     {
2649     }
2650 
createInstance(Context & context) const2651     virtual TestInstance *createInstance(Context &context) const
2652     {
2653         return new CopyImageToBuffer(context, m_params);
2654     }
2655 
checkSupport(Context & context) const2656     virtual void checkSupport(Context &context) const
2657     {
2658         checkExtensionSupport(context, m_params.extensionFlags);
2659     }
2660 
2661 private:
2662     TestParams m_params;
2663 };
2664 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)2665 void CopyImageToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2666                                                  CopyRegion region, uint32_t mipLevel)
2667 {
2668     DE_UNREF(mipLevel);
2669 
2670     uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
2671     if (!rowLength)
2672         rowLength = region.bufferImageCopy.imageExtent.width;
2673 
2674     uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
2675     if (!imageHeight)
2676         imageHeight = region.bufferImageCopy.imageExtent.height;
2677 
2678     const int texelSize           = src.getFormat().getPixelSize();
2679     const VkExtent3D extent       = region.bufferImageCopy.imageExtent;
2680     const VkOffset3D srcOffset    = region.bufferImageCopy.imageOffset;
2681     const int texelOffset         = (int)region.bufferImageCopy.bufferOffset / texelSize;
2682     const uint32_t baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2683 
2684     for (uint32_t z = 0; z < extent.depth; z++)
2685     {
2686         for (uint32_t y = 0; y < extent.height; y++)
2687         {
2688             int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2689             const tcu::ConstPixelBufferAccess srcSubRegion =
2690                 tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2691                                   region.bufferImageCopy.imageExtent.width, 1, 1);
2692             const tcu::PixelBufferAccess dstSubRegion =
2693                 tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2694             tcu::copy(dstSubRegion, srcSubRegion);
2695         }
2696     }
2697 }
2698 
2699 // Copy levels from compressed mipmap images into a buffer.
2700 class CopyCompressedImageToBuffer final : public CopiesAndBlittingTestInstance
2701 {
2702 public:
2703     CopyCompressedImageToBuffer(Context &context, TestParams testParams);
2704 
2705     virtual tcu::TestStatus iterate(void) override;
2706 
2707 private:
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess,tcu::PixelBufferAccess,CopyRegion,uint32_t)2708     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion,
2709                                           uint32_t) override
2710     {
2711         TCU_THROW(InternalError, "copyRegionToTextureLevel not implemented for CopyCompressedImageToBuffer");
2712     }
2713 
2714     // Contains a randomly generated compressed texture pyramid.
2715     using TestTexture2DSp = de::SharedPtr<pipeline::TestTexture2DArray>;
2716     TestTexture2DSp m_texture;
2717     de::MovePtr<ImageWithMemory> m_source;
2718     de::MovePtr<BufferWithMemory> m_sourceBuffer;
2719     de::MovePtr<BufferWithMemory> m_destination;
2720 };
2721 
CopyCompressedImageToBuffer(Context & context,TestParams testParams)2722 CopyCompressedImageToBuffer::CopyCompressedImageToBuffer(Context &context, TestParams testParams)
2723     : CopiesAndBlittingTestInstance(context, testParams)
2724     , m_texture(TestTexture2DSp(new pipeline::TestTexture2DArray(
2725           mapVkCompressedFormat(testParams.src.image.format), testParams.src.image.extent.width,
2726           testParams.src.image.extent.height, testParams.arrayLayers)))
2727 {
2728 }
2729 
iterate(void)2730 tcu::TestStatus CopyCompressedImageToBuffer::iterate(void)
2731 {
2732     const DeviceInterface &vk        = m_context.getDeviceInterface();
2733     const VkDevice vkDevice          = m_device;
2734     Allocator &memAlloc              = *m_allocator;
2735     const ImageParms &srcImageParams = m_params.src.image;
2736 
2737     VkQueue queue                               = VK_NULL_HANDLE;
2738     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
2739     VkCommandPool commandPool                   = VK_NULL_HANDLE;
2740     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
2741 
2742     // Create source image, containing all the mip levels.
2743     {
2744         const VkImageCreateInfo sourceImageParams = {
2745             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
2746             DE_NULL,                                                           // const void* pNext;
2747             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
2748             m_params.src.image.imageType,                                      // VkImageType imageType;
2749             m_params.src.image.format,                                         // VkFormat format;
2750             m_params.src.image.extent,                                         // VkExtent3D extent;
2751             (uint32_t)m_texture->getNumLevels(),                               // uint32_t mipLevels;
2752             m_params.arrayLayers,                                              // uint32_t arraySize;
2753             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
2754             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
2755             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2756             m_queueFamilyIndices.size() > 1 ? VK_SHARING_MODE_CONCURRENT :
2757                                               VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2758             (uint32_t)m_queueFamilyIndices.size(),                       // uint32_t queueFamilyIndexCount;
2759             m_queueFamilyIndices.data(),                                 // const uint32_t* pQueueFamilyIndices;
2760             VK_IMAGE_LAYOUT_UNDEFINED,                                   // VkImageLayout initialLayout;
2761         };
2762 
2763         m_source = de::MovePtr<ImageWithMemory>(
2764             new ImageWithMemory(vk, vkDevice, memAlloc, sourceImageParams, vk::MemoryRequirement::Any));
2765     }
2766 
2767     // Upload the compressed image.
2768     // FIXME: This could be a utility.
2769     //    pipeline::uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, m_source->get(), vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2770     // Does not allow using an external command pool, the utilities there could fruitfully be generalised.
2771     m_sourceBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2772         vk, vkDevice, memAlloc, makeBufferCreateInfo(m_texture->getCompressedSize(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
2773         vk::MemoryRequirement::HostVisible));
2774     m_texture->write(reinterpret_cast<uint8_t *>(m_sourceBuffer->getAllocation().getHostPtr()));
2775     flushAlloc(vk, vkDevice, m_sourceBuffer->getAllocation());
2776     std::vector<VkBufferImageCopy> copyRegions = m_texture->getBufferCopyRegions();
2777     copyBufferToImage(vk, vkDevice, queue, activeQueueFamilyIndex(), m_sourceBuffer->get(),
2778                       m_texture->getCompressedSize(), copyRegions, nullptr, VK_IMAGE_ASPECT_COLOR_BIT,
2779                       m_texture->getNumLevels(), m_texture->getArraySize(), m_source->get(),
2780                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2781                       &commandPool, 0);
2782 
2783     // VKSC requires static allocation, so allocate a large enough buffer for each individual mip level of
2784     // the compressed source image, rather than creating a corresponding buffer for each level in the loop
2785     // below.
2786     auto level0BuferSize = m_texture->getCompressedLevel(0, 0).getDataSize();
2787     m_destination        = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
2788         vk, vkDevice, memAlloc, makeBufferCreateInfo(level0BuferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT),
2789         MemoryRequirement::HostVisible));
2790 
2791     // Copy each miplevel of the uploaded image into a buffer, and
2792     // check the buffer matches the appropriate test texture level.
2793     for (uint32_t mipLevelToCheckIdx = 0; mipLevelToCheckIdx < (uint32_t)m_texture->getNumLevels();
2794          mipLevelToCheckIdx++)
2795         for (uint32_t arrayLayerToCheckIdx = 0; arrayLayerToCheckIdx < (uint32_t)m_texture->getArraySize();
2796              arrayLayerToCheckIdx++)
2797         {
2798             const tcu::CompressedTexture compressedMipLevelToCheck =
2799                 m_texture->getCompressedLevel(mipLevelToCheckIdx, arrayLayerToCheckIdx);
2800             uint32_t bufferSize = compressedMipLevelToCheck.getDataSize();
2801 
2802             // Clear the buffer to zero before copying into it as a precaution.
2803             deMemset(m_destination->getAllocation().getHostPtr(), 0, bufferSize);
2804             flushAlloc(vk, vkDevice, m_destination->getAllocation());
2805 
2806             // Barrier to get the source image's selected mip-level / layer in the right format for transfer.
2807             const auto imageBarrier = makeImageMemoryBarrier(
2808                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2809                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_source->get(),
2810                 {
2811                     // VkImageSubresourceRange subresourceRange;
2812                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2813                     mipLevelToCheckIdx,        // uint32_t baseMipLevel;
2814                     1u,                        // uint32_t mipLevels;
2815                     arrayLayerToCheckIdx,      // uint32_t baseArraySlice;
2816                     1u,                        // uint32_t arraySize;
2817                 });
2818 
2819             // Barrier to wait for the transfer from image to buffer to complete.
2820             const auto bufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
2821                                                                m_destination->get(), 0, bufferSize);
2822 
2823             // Copy from image to buffer
2824             VkBufferImageCopy copyRegion;
2825             copyRegion = makeBufferImageCopy(
2826                 mipLevelExtents(srcImageParams.extent, mipLevelToCheckIdx),
2827                 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelToCheckIdx, arrayLayerToCheckIdx, 1));
2828 
2829             VkBufferImageCopy bufferImageCopy;
2830             VkBufferImageCopy2KHR bufferImageCopy2KHR;
2831             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2832             {
2833                 bufferImageCopy = copyRegion;
2834             }
2835             else
2836             {
2837                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2838                 bufferImageCopy2KHR = convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyRegion);
2839             }
2840 
2841             beginCommandBuffer(vk, commandBuffer);
2842             // Transition the selected miplevel to the right format for the transfer.
2843             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2844                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
2845                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
2846 
2847             // Copy the mip level to the buffer.
2848             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
2849             {
2850                 vk.cmdCopyImageToBuffer(commandBuffer, m_source->get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2851                                         m_destination->get(), 1u, &bufferImageCopy);
2852             }
2853             else
2854             {
2855                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
2856                 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR = {
2857                     VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2858                     DE_NULL,                                           // const void* pNext;
2859                     m_source->get(),                                   // VkImage srcImage;
2860                     VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,              // VkImageLayout srcImageLayout;
2861                     m_destination->get(),                              // VkBuffer dstBuffer;
2862                     1u,                                                // uint32_t regionCount;
2863                     &bufferImageCopy2KHR                               // const VkBufferImageCopy2KHR* pRegions;
2864                 };
2865 
2866                 vk.cmdCopyImageToBuffer2(commandBuffer, &copyImageToBufferInfo2KHR);
2867             }
2868 
2869             // Prepare to read from the host visible barrier.
2870             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2871                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 0,
2872                                   (const VkImageMemoryBarrier *)DE_NULL);
2873             endCommandBuffer(vk, commandBuffer);
2874 
2875             submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
2876             m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
2877 
2878             invalidateAlloc(vk, vkDevice, m_destination->getAllocation());
2879             // Read and compare buffer data.
2880             const uint8_t *referenceData = (uint8_t *)compressedMipLevelToCheck.getData();
2881             const uint8_t *resultData    = (uint8_t *)m_destination->getAllocation().getHostPtr();
2882             int result                   = deMemCmp(referenceData, resultData, bufferSize);
2883             if (result != 0)
2884             {
2885                 std::ostringstream msg;
2886                 msg << "Incorrect data retrieved for mip level " << mipLevelToCheckIdx << ", layer "
2887                     << arrayLayerToCheckIdx << " - extents (" << compressedMipLevelToCheck.getWidth() << ", "
2888                     << compressedMipLevelToCheck.getHeight() << ")";
2889                 return tcu::TestStatus::fail(msg.str());
2890             }
2891         }
2892 
2893     return tcu::TestStatus::pass("OK");
2894 }
2895 
2896 class CopyCompressedImageToBufferTestCase : public vkt::TestCase
2897 {
2898 public:
CopyCompressedImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)2899     CopyCompressedImageToBufferTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
2900         : vkt::TestCase(testCtx, name)
2901         , m_params(params)
2902     {
2903     }
2904 
createInstance(Context & context) const2905     virtual TestInstance *createInstance(Context &context) const
2906     {
2907         return new CopyCompressedImageToBuffer(context, m_params);
2908     }
2909     virtual void checkSupport(Context &context) const;
2910 
2911 private:
2912     TestParams m_params;
2913 };
2914 
checkSupport(Context & context) const2915 void CopyCompressedImageToBufferTestCase::checkSupport(Context &context) const
2916 {
2917     DE_ASSERT(m_params.src.image.tiling == VK_IMAGE_TILING_OPTIMAL);
2918     DE_ASSERT(m_params.src.image.imageType == vk::VK_IMAGE_TYPE_2D);
2919 
2920     checkExtensionSupport(context, m_params.extensionFlags);
2921 
2922     VkFormatProperties formatProps;
2923     context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(),
2924                                                                      m_params.src.image.format, &formatProps);
2925 
2926     VkImageFormatProperties imageFormatProperties;
2927 
2928     const auto &instance = context.getInstanceInterface();
2929     if (instance.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), m_params.src.image.format,
2930                                                         m_params.src.image.imageType, VK_IMAGE_TILING_OPTIMAL,
2931                                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2932                                                         &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
2933     {
2934         TCU_THROW(NotSupportedError, "Format not supported");
2935     }
2936 
2937     if (!(formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT))
2938         TCU_THROW(NotSupportedError, "TRANSFER_SRC is not supported on this image type");
2939 }
2940 
2941 // Copy from buffer to image.
2942 
2943 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2944 {
2945 public:
2946     CopyBufferToImage(Context &context, TestParams testParams);
2947     virtual tcu::TestStatus iterate(void);
2948 
2949 private:
2950     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
2951                                           CopyRegion region, uint32_t mipLevel = 0u);
2952 
2953     tcu::TextureFormat m_textureFormat;
2954     VkDeviceSize m_bufferSize;
2955 
2956     Move<VkBuffer> m_source;
2957     de::MovePtr<Allocation> m_sourceBufferAlloc;
2958     Move<VkImage> m_destination;
2959     de::MovePtr<Allocation> m_destinationImageAlloc;
2960     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
2961     Move<VkSemaphore> m_sparseSemaphore;
2962 };
2963 
CopyBufferToImage(Context & context,TestParams testParams)2964 CopyBufferToImage::CopyBufferToImage(Context &context, TestParams testParams)
2965     : CopiesAndBlittingTestInstance(context, testParams)
2966     , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2967     , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2968 {
2969     const InstanceInterface &vki        = context.getInstanceInterface();
2970     const DeviceInterface &vk           = context.getDeviceInterface();
2971     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2972 
2973     // Create source buffer
2974     {
2975         const VkBufferCreateInfo sourceBufferParams = {
2976             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2977             DE_NULL,                              // const void* pNext;
2978             0u,                                   // VkBufferCreateFlags flags;
2979             m_bufferSize,                         // VkDeviceSize size;
2980             VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
2981             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
2982             0u,                                   // uint32_t queueFamilyIndexCount;
2983             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
2984         };
2985 
2986         m_source            = createBuffer(vk, m_device, &sourceBufferParams);
2987         m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::HostVisible,
2988                                              *m_allocator, m_params.allocationKind);
2989         VK_CHECK(vk.bindBufferMemory(m_device, *m_source, m_sourceBufferAlloc->getMemory(),
2990                                      m_sourceBufferAlloc->getOffset()));
2991     }
2992 
2993     // Create destination image
2994     {
2995         VkImageCreateInfo destinationImageParams = {
2996             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
2997             DE_NULL,                                                           // const void* pNext;
2998             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
2999             m_params.dst.image.imageType,                                      // VkImageType imageType;
3000             m_params.dst.image.format,                                         // VkFormat format;
3001             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
3002             1u,                                                                // uint32_t mipLevels;
3003             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
3004             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
3005             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
3006             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3007             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
3008             0u,                                                                // uint32_t queueFamilyIndexCount;
3009             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
3010             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
3011         };
3012 
3013 #ifndef CTS_USES_VULKANSC
3014         if (!testParams.useSparseBinding)
3015         {
3016 #endif
3017             m_destination           = createImage(vk, m_device, &destinationImageParams);
3018             m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
3019                                                     MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
3020             VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
3021                                         m_destinationImageAlloc->getOffset()));
3022 #ifndef CTS_USES_VULKANSC
3023         }
3024         else
3025         {
3026             destinationImageParams.flags |=
3027                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3028             vk::VkImageFormatProperties imageFormatProperties;
3029             if (vki.getPhysicalDeviceImageFormatProperties(
3030                     vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
3031                     destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
3032                     &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3033             {
3034                 TCU_THROW(NotSupportedError, "Image format not supported");
3035             }
3036             m_destination     = createImage(vk, m_device, &destinationImageParams);
3037             m_sparseSemaphore = createSemaphore(vk, m_device);
3038             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
3039                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3040                                        mapVkFormat(destinationImageParams.format), m_destination.get());
3041         }
3042 #endif
3043     }
3044 }
3045 
iterate(void)3046 tcu::TestStatus CopyBufferToImage::iterate(void)
3047 {
3048     m_sourceTextureLevel =
3049         de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
3050     generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1,
3051                    m_params.src.buffer.fillMode);
3052     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
3053         new tcu::TextureLevel(m_textureFormat, m_params.dst.image.extent.width, m_params.dst.image.extent.height,
3054                               m_params.dst.image.extent.depth));
3055 
3056     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
3057                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
3058 
3059     generateExpectedResult();
3060 
3061     uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
3062     uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
3063 
3064     const DeviceInterface &vk                   = m_context.getDeviceInterface();
3065     const VkDevice vkDevice                     = m_device;
3066     VkQueue queue                               = VK_NULL_HANDLE;
3067     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
3068     VkCommandPool commandPool                   = VK_NULL_HANDLE;
3069     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
3070 
3071     const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3072                                                DE_NULL,                                // const void* pNext;
3073                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
3074                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
3075                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
3076                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
3077                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
3078                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
3079                                                *m_destination,                         // VkImage image;
3080                                                {
3081                                                    // VkImageSubresourceRange subresourceRange;
3082                                                    getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
3083                                                    0u,                              // uint32_t baseMipLevel;
3084                                                    1u,                              // uint32_t mipLevels;
3085                                                    0u,                              // uint32_t baseArraySlice;
3086                                                    getArraySize(m_params.dst.image) // uint32_t arraySize;
3087                                                }};
3088 
3089     // Copy from buffer to image
3090     std::vector<VkBufferImageCopy> bufferImageCopies;
3091     std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
3092     for (uint32_t i = 0; i < m_params.regions.size(); i++)
3093     {
3094         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3095         {
3096             bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
3097         }
3098         else
3099         {
3100             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3101             bufferImageCopies2KHR.push_back(
3102                 convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
3103         }
3104     }
3105 
3106     beginCommandBuffer(vk, commandBuffer);
3107     vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3108                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3109                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
3110 
3111     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3112     {
3113         vk.cmdCopyBufferToImage(commandBuffer, m_source.get(), m_destination.get(),
3114                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)m_params.regions.size(),
3115                                 bufferImageCopies.data());
3116     }
3117     else
3118     {
3119         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3120         const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3121             VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3122             DE_NULL,                                           // const void* pNext;
3123             m_source.get(),                                    // VkBuffer srcBuffer;
3124             m_destination.get(),                               // VkImage dstImage;
3125             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,              // VkImageLayout dstImageLayout;
3126             (uint32_t)m_params.regions.size(),                 // uint32_t regionCount;
3127             bufferImageCopies2KHR.data()                       // const VkBufferImageCopy2KHR* pRegions;
3128         };
3129 
3130         vk.cmdCopyBufferToImage2(commandBuffer, &copyBufferToImageInfo2KHR);
3131     }
3132 
3133     endCommandBuffer(vk, commandBuffer);
3134 
3135     submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
3136     m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
3137 
3138     de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
3139     return checkTestResult(resultLevel->getAccess());
3140 }
3141 
3142 class CopyBufferToImageTestCase : public vkt::TestCase
3143 {
3144 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)3145     CopyBufferToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
3146         : vkt::TestCase(testCtx, name)
3147         , m_params(params)
3148     {
3149     }
3150 
~CopyBufferToImageTestCase(void)3151     virtual ~CopyBufferToImageTestCase(void)
3152     {
3153     }
3154 
createInstance(Context & context) const3155     virtual TestInstance *createInstance(Context &context) const
3156     {
3157         return new CopyBufferToImage(context, m_params);
3158     }
3159 
checkSupport(Context & context) const3160     virtual void checkSupport(Context &context) const
3161     {
3162         checkExtensionSupport(context, m_params.extensionFlags);
3163     }
3164 
3165 private:
3166     TestParams m_params;
3167 };
3168 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)3169 void CopyBufferToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3170                                                  CopyRegion region, uint32_t mipLevel)
3171 {
3172     DE_UNREF(mipLevel);
3173 
3174     uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
3175     if (!rowLength)
3176         rowLength = region.bufferImageCopy.imageExtent.width;
3177 
3178     uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
3179     if (!imageHeight)
3180         imageHeight = region.bufferImageCopy.imageExtent.height;
3181 
3182     const int texelSize           = dst.getFormat().getPixelSize();
3183     const VkExtent3D extent       = region.bufferImageCopy.imageExtent;
3184     const VkOffset3D dstOffset    = region.bufferImageCopy.imageOffset;
3185     const int texelOffset         = (int)region.bufferImageCopy.bufferOffset / texelSize;
3186     const uint32_t baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
3187 
3188     for (uint32_t z = 0; z < extent.depth; z++)
3189     {
3190         for (uint32_t y = 0; y < extent.height; y++)
3191         {
3192             int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
3193             const tcu::ConstPixelBufferAccess srcSubRegion =
3194                 tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
3195             const tcu::PixelBufferAccess dstSubRegion =
3196                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
3197                                   region.bufferImageCopy.imageExtent.width, 1, 1);
3198             tcu::copy(dstSubRegion, srcSubRegion);
3199         }
3200     }
3201 }
3202 
3203 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
3204 {
3205 public:
3206     CopyBufferToDepthStencil(Context &context, TestParams testParams);
3207     virtual tcu::TestStatus iterate(void);
3208 
3209 private:
3210     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3211                                           CopyRegion region, uint32_t mipLevel = 0u);
3212 
3213     tcu::TextureFormat m_textureFormat;
3214     VkDeviceSize m_bufferSize;
3215 
3216     Move<VkBuffer> m_source;
3217     de::MovePtr<Allocation> m_sourceBufferAlloc;
3218     Move<VkImage> m_destination;
3219     de::MovePtr<Allocation> m_destinationImageAlloc;
3220     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
3221     Move<VkSemaphore> m_sparseSemaphore;
3222 };
3223 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)3224 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3225                                                         CopyRegion region, uint32_t mipLevel)
3226 {
3227     DE_UNREF(mipLevel);
3228 
3229     uint32_t rowLength = region.bufferImageCopy.bufferRowLength;
3230     if (!rowLength)
3231         rowLength = region.bufferImageCopy.imageExtent.width;
3232 
3233     uint32_t imageHeight = region.bufferImageCopy.bufferImageHeight;
3234     if (!imageHeight)
3235         imageHeight = region.bufferImageCopy.imageExtent.height;
3236 
3237     const int texelSize        = dst.getFormat().getPixelSize();
3238     const VkExtent3D extent    = region.bufferImageCopy.imageExtent;
3239     const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
3240     const int texelOffset      = (int)region.bufferImageCopy.bufferOffset / texelSize;
3241 
3242     for (uint32_t z = 0; z < extent.depth; z++)
3243     {
3244         for (uint32_t y = 0; y < extent.height; y++)
3245         {
3246             int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
3247             const tcu::ConstPixelBufferAccess srcSubRegion =
3248                 tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
3249             const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(
3250                 dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z, region.bufferImageCopy.imageExtent.width, 1, 1);
3251 
3252             if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
3253             {
3254                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH),
3255                           false);
3256             }
3257             else
3258             {
3259                 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL),
3260                           false);
3261             }
3262         }
3263     }
3264 }
3265 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)3266 bool isSupportedDepthStencilFormat(const InstanceInterface &vki, const VkPhysicalDevice physDevice,
3267                                    const VkFormat format)
3268 {
3269     VkFormatProperties formatProps;
3270     vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
3271     return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
3272 }
3273 
CopyBufferToDepthStencil(Context & context,TestParams testParams)3274 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context &context, TestParams testParams)
3275     : CopiesAndBlittingTestInstance(context, testParams)
3276     , m_textureFormat(mapVkFormat(testParams.dst.image.format))
3277     , m_bufferSize(0)
3278 {
3279     const InstanceInterface &vki        = context.getInstanceInterface();
3280     const DeviceInterface &vk           = context.getDeviceInterface();
3281     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3282     const VkDevice vkDevice             = m_device;
3283     Allocator &memAlloc                 = context.getDefaultAllocator();
3284     const bool hasDepth                 = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
3285     const bool hasStencil               = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
3286 
3287     if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
3288     {
3289         TCU_THROW(NotSupportedError, "Image format not supported.");
3290     }
3291 
3292     if (hasDepth)
3293     {
3294         glw::GLuint texelSize = m_textureFormat.getPixelSize();
3295         if (texelSize > sizeof(float))
3296         {
3297             // We must have D32F_S8 format, depth must be packed so we only need
3298             // to allocate space for the D32F part. Stencil will be separate
3299             texelSize = sizeof(float);
3300         }
3301         m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) *
3302                         static_cast<VkDeviceSize>(m_params.dst.image.extent.height) *
3303                         static_cast<VkDeviceSize>(texelSize);
3304     }
3305     if (hasStencil)
3306     {
3307         // Stencil is always 8bits and packed.
3308         m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) *
3309                         static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
3310     }
3311 
3312     // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
3313     {
3314         const VkBufferCreateInfo sourceBufferParams = {
3315             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3316             DE_NULL,                              // const void* pNext;
3317             0u,                                   // VkBufferCreateFlags flags;
3318             m_bufferSize,                         // VkDeviceSize size;
3319             VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
3320             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
3321             0u,                                   // uint32_t queueFamilyIndexCount;
3322             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
3323         };
3324 
3325         m_source            = createBuffer(vk, vkDevice, &sourceBufferParams);
3326         m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible,
3327                                              memAlloc, m_params.allocationKind);
3328         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(),
3329                                      m_sourceBufferAlloc->getOffset()));
3330     }
3331 
3332     // Create destination image
3333     {
3334         VkImageCreateInfo destinationImageParams = {
3335             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
3336             DE_NULL,                                                           // const void* pNext;
3337             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
3338             m_params.dst.image.imageType,                                      // VkImageType imageType;
3339             m_params.dst.image.format,                                         // VkFormat format;
3340             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
3341             1u,                                                                // uint32_t mipLevels;
3342             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
3343             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
3344             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
3345             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3346             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
3347             0u,                                                                // uint32_t queueFamilyIndexCount;
3348             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
3349             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
3350         };
3351 
3352 #ifndef CTS_USES_VULKANSC
3353         if (!testParams.useSparseBinding)
3354         {
3355 #endif
3356             m_destination           = createImage(vk, m_device, &destinationImageParams);
3357             m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
3358                                                     MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
3359             VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
3360                                         m_destinationImageAlloc->getOffset()));
3361 #ifndef CTS_USES_VULKANSC
3362         }
3363         else
3364         {
3365             destinationImageParams.flags |=
3366                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3367             vk::VkImageFormatProperties imageFormatProperties;
3368             if (vki.getPhysicalDeviceImageFormatProperties(
3369                     vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
3370                     destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
3371                     &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3372             {
3373                 TCU_THROW(NotSupportedError, "Image format not supported");
3374             }
3375             m_destination     = createImage(vk, m_device, &destinationImageParams);
3376             m_sparseSemaphore = createSemaphore(vk, m_device);
3377             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
3378                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3379                                        mapVkFormat(destinationImageParams.format), m_destination.get());
3380         }
3381 #endif
3382     }
3383 }
3384 
iterate(void)3385 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
3386 {
3387     // Create source depth/stencil content. Treat as 1D texture to get different pattern
3388     m_sourceTextureLevel =
3389         de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
3390     // Fill buffer with linear gradiant
3391     generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
3392 
3393     // Create image layer for depth/stencil
3394     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
3395         new tcu::TextureLevel(m_textureFormat, m_params.dst.image.extent.width, m_params.dst.image.extent.height,
3396                               m_params.dst.image.extent.depth));
3397 
3398     // Fill image layer with 2D gradiant
3399     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
3400                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
3401 
3402     // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
3403     // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
3404     // This emulates what the HW will be doing.
3405     generateExpectedResult();
3406 
3407     // Upload our source depth/stencil content to the source buffer
3408     // This is the buffer that will be used by region commands
3409     std::vector<VkBufferImageCopy> bufferImageCopies;
3410     std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
3411     VkDeviceSize bufferOffset  = 0;
3412     const VkDevice vkDevice    = m_device;
3413     const DeviceInterface &vk  = m_context.getDeviceInterface();
3414     char *dstPtr               = reinterpret_cast<char *>(m_sourceBufferAlloc->getHostPtr());
3415     bool depthLoaded           = false;
3416     bool stencilLoaded         = false;
3417     VkDeviceSize depthOffset   = 0;
3418     VkDeviceSize stencilOffset = 0;
3419 
3420     // To be able to test ordering depth & stencil differently
3421     // we take the given copy regions and use that as the desired order
3422     // and copy the appropriate data into place and compute the appropriate
3423     // data offsets to be used in the copy command.
3424     for (uint32_t i = 0; i < m_params.regions.size(); i++)
3425     {
3426         tcu::ConstPixelBufferAccess bufferAccess = m_sourceTextureLevel->getAccess();
3427         uint32_t bufferSize        = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
3428         VkBufferImageCopy copyData = m_params.regions[i].bufferImageCopy;
3429         char *srcPtr;
3430 
3431         if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
3432         {
3433             // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
3434             tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()),
3435                                            bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
3436             bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
3437             // Copy depth component only from source data. This gives us packed depth-only data.
3438             tcu::copy(depthTexture.getAccess(),
3439                       tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
3440             srcPtr = (char *)depthTexture.getAccess().getDataPtr();
3441             // Copy packed depth-only data to output buffer
3442             deMemcpy(dstPtr, srcPtr, bufferSize);
3443             depthLoaded = true;
3444             depthOffset = bufferOffset;
3445             dstPtr += bufferSize;
3446             bufferOffset += bufferSize;
3447             copyData.bufferOffset += depthOffset;
3448         }
3449         else if (!stencilLoaded)
3450         {
3451             // Create level that is same component as stencil buffer (always 8-bits)
3452             tcu::TextureLevel stencilTexture(
3453                 tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL),
3454                 bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
3455             // Copy stencil component only from source data. This gives us packed stencil-only data.
3456             tcu::copy(stencilTexture.getAccess(),
3457                       tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
3458             srcPtr = (char *)stencilTexture.getAccess().getDataPtr();
3459             // Copy packed stencil-only data to output buffer
3460             deMemcpy(dstPtr, srcPtr, bufferSize);
3461             stencilLoaded = true;
3462             stencilOffset = bufferOffset;
3463             dstPtr += bufferSize;
3464             bufferOffset += bufferSize;
3465 
3466             // Reference image generation uses pixel offsets based on buffer offset.
3467             // We need to adjust the offset now that the stencil data is not interleaved.
3468             copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
3469 
3470             copyData.bufferOffset += stencilOffset;
3471         }
3472 
3473         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3474         {
3475             bufferImageCopies.push_back(copyData);
3476         }
3477         else
3478         {
3479             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3480             bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
3481         }
3482     }
3483 
3484     flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
3485 
3486     // Upload the depth/stencil data from m_destinationTextureLevel to initialize
3487     // depth and stencil to known values.
3488     // Uses uploadImageAspect so makes its own buffers for depth and stencil
3489     // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
3490     uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
3491 
3492     const VkImageMemoryBarrier imageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3493                                                DE_NULL,                                // const void* pNext;
3494                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
3495                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
3496                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
3497                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
3498                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
3499                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
3500                                                *m_destination,                         // VkImage image;
3501                                                {
3502                                                    // VkImageSubresourceRange subresourceRange;
3503                                                    getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
3504                                                    0u,                              // uint32_t baseMipLevel;
3505                                                    1u,                              // uint32_t mipLevels;
3506                                                    0u,                              // uint32_t baseArraySlice;
3507                                                    1u                               // uint32_t arraySize;
3508                                                }};
3509 
3510     // Copy from buffer to depth/stencil image
3511 
3512     beginCommandBuffer(vk, *m_universalCmdBuffer);
3513     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3514                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3515                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &imageBarrier);
3516 
3517     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3518     {
3519         if (m_params.singleCommand)
3520         {
3521             // Issue a single copy command with regions defined by the test.
3522             vk.cmdCopyBufferToImage(*m_universalCmdBuffer, m_source.get(), m_destination.get(),
3523                                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (uint32_t)m_params.regions.size(),
3524                                     bufferImageCopies.data());
3525         }
3526         else
3527         {
3528             // Issue a a copy command per region defined by the test.
3529             for (uint32_t i = 0; i < bufferImageCopies.size(); i++)
3530             {
3531                 if (i > 0)
3532                     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3533                                           VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
3534                                           (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3535                                           1, &imageBarrier);
3536 
3537                 vk.cmdCopyBufferToImage(*m_universalCmdBuffer, m_source.get(), m_destination.get(),
3538                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
3539             }
3540         }
3541     }
3542     else
3543     {
3544         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3545 
3546         if (m_params.singleCommand)
3547         {
3548             // Issue a single copy command with regions defined by the test.
3549             const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3550                 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3551                 DE_NULL,                                           // const void* pNext;
3552                 m_source.get(),                                    // VkBuffer srcBuffer;
3553                 m_destination.get(),                               // VkImage dstImage;
3554                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,              // VkImageLayout dstImageLayout;
3555                 (uint32_t)m_params.regions.size(),                 // uint32_t regionCount;
3556                 bufferImageCopies2KHR.data()                       // const VkBufferImageCopy2KHR* pRegions;
3557             };
3558             vk.cmdCopyBufferToImage2(*m_universalCmdBuffer, &copyBufferToImageInfo2KHR);
3559         }
3560         else
3561         {
3562             // Issue a a copy command per region defined by the test.
3563             for (uint32_t i = 0; i < bufferImageCopies2KHR.size(); i++)
3564             {
3565                 if (i > 0)
3566                     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
3567                                           VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
3568                                           (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
3569                                           1, &imageBarrier);
3570 
3571                 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR = {
3572                     VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
3573                     DE_NULL,                                           // const void* pNext;
3574                     m_source.get(),                                    // VkBuffer srcBuffer;
3575                     m_destination.get(),                               // VkImage dstImage;
3576                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,              // VkImageLayout dstImageLayout;
3577                     1,                                                 // uint32_t regionCount;
3578                     &bufferImageCopies2KHR[i]                          // const VkBufferImageCopy2KHR* pRegions;
3579                 };
3580                 // Issue a single copy command with regions defined by the test.
3581                 vk.cmdCopyBufferToImage2(*m_universalCmdBuffer, &copyBufferToImageInfo2KHR);
3582             }
3583         }
3584     }
3585 
3586     endCommandBuffer(vk, *m_universalCmdBuffer);
3587 
3588     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
3589     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
3590 
3591     de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
3592 
3593     // For combined depth/stencil formats both aspects are checked even when the test only
3594     // copies one. Clear such aspects here for both the result and the reference.
3595     if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
3596     {
3597         tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
3598         tcu::clearDepth(resultLevel->getAccess(), 0.0f);
3599     }
3600     if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
3601     {
3602         tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
3603         tcu::clearStencil(resultLevel->getAccess(), 0);
3604     }
3605 
3606     return checkTestResult(resultLevel->getAccess());
3607 }
3608 
3609 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3610 {
3611 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)3612     CopyBufferToDepthStencilTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
3613         : vkt::TestCase(testCtx, name)
3614         , m_params(params)
3615     {
3616     }
3617 
~CopyBufferToDepthStencilTestCase(void)3618     virtual ~CopyBufferToDepthStencilTestCase(void)
3619     {
3620     }
3621 
createInstance(Context & context) const3622     virtual TestInstance *createInstance(Context &context) const
3623     {
3624         return new CopyBufferToDepthStencil(context, m_params);
3625     }
3626 
checkSupport(Context & context) const3627     virtual void checkSupport(Context &context) const
3628     {
3629         checkExtensionSupport(context, m_params.extensionFlags);
3630     }
3631 
3632 private:
3633     TestParams m_params;
3634 };
3635 
3636 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3637 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3638 // and has special cases needed for blits to some formats.
3639 
3640 class CompressedTextureForBlit
3641 {
3642 public:
3643     CompressedTextureForBlit(const tcu::CompressedTexFormat &srcFormat, int width, int height, int depth);
3644 
3645     tcu::PixelBufferAccess getDecompressedAccess() const;
3646     const tcu::CompressedTexture &getCompressedTexture() const;
3647 
3648 protected:
3649     tcu::CompressedTexture m_compressedTexture;
3650     de::ArrayBuffer<uint8_t> m_decompressedData;
3651     tcu::PixelBufferAccess m_decompressedAccess;
3652 };
3653 
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3654 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat &srcFormat, int width, int height,
3655                                                    int depth)
3656     : m_compressedTexture(srcFormat, width, height, depth)
3657 {
3658     de::Random random(123);
3659 
3660     const int compressedDataSize(m_compressedTexture.getDataSize());
3661     uint8_t *compressedData((uint8_t *)m_compressedTexture.getData());
3662 
3663     tcu::TextureFormat decompressedSrcFormat(tcu::getUncompressedFormat(srcFormat));
3664     const int decompressedDataSize(tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3665 
3666     // generate random data for compresed textre
3667     if (tcu::isAstcFormat(srcFormat))
3668     {
3669         // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3670         tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3671                                              srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3672     }
3673     else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3674              (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3675     {
3676         // special case - when we are blitting compressed floating-point image we can't have both big and small values
3677         // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3678         // blocks that after decompression will have components in proper range
3679 
3680         typedef std::array<uint32_t, 4> BC6HBlock;
3681         DE_STATIC_ASSERT(sizeof(BC6HBlock) == (4 * sizeof(uint32_t)));
3682         std::vector<BC6HBlock> validBlocks;
3683 
3684         if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3685         {
3686             // define set of few valid blocks that contain values from <0; 1> range
3687             validBlocks = {
3688                 {{1686671500, 3957317723, 3010132342, 2420137890}}, {{3538027716, 298848033, 1925786021, 2022072301}},
3689                 {{2614043466, 1636155440, 1023731774, 1894349986}}, {{3433039318, 1294346072, 1587319645, 1738449906}},
3690                 {{1386298160, 1639492154, 1273285776, 361562050}},  {{1310110688, 526460754, 3630858047, 537617591}},
3691                 {{3270356556, 2432993217, 2415924417, 1792488857}}, {{1204947583, 353249154, 3739153467, 2068076443}},
3692             };
3693         }
3694         else
3695         {
3696             // define set of few valid blocks that contain values from <-1; 1> range
3697             validBlocks = {
3698                 {{2120678840, 3264271120, 4065378848, 3479743703}}, {{1479697556, 3480872527, 3369382558, 568252340}},
3699                 {{1301480032, 1607738094, 3055221704, 3663953681}}, {{3531657186, 2285472028, 1429601507, 1969308187}},
3700                 {{73229044, 650504649, 1120954865, 2626631975}},    {{3872486086, 15326178, 2565171269, 2857722432}},
3701                 {{1301480032, 1607738094, 3055221704, 3663953681}}, {{73229044, 650504649, 1120954865, 2626631975}},
3702             };
3703         }
3704 
3705         uint32_t *compressedDataUint32 = reinterpret_cast<uint32_t *>(compressedData);
3706         const int blocksCount          = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3707 
3708         // fill data using randomly selected valid blocks
3709         for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3710         {
3711             uint32_t selectedBlock = random.getUint32() % static_cast<uint32_t>(validBlocks.size());
3712             deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data(), sizeof(BC6HBlock));
3713             compressedDataUint32 += 4;
3714         }
3715     }
3716     else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3717     {
3718         // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3719         for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3720             compressedData[byteNdx] = 0xFF & random.getUint32();
3721     }
3722 
3723     // alocate space for decompressed texture
3724     m_decompressedData.setStorage(decompressedDataSize);
3725     m_decompressedAccess =
3726         tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3727 
3728     // store decompressed data
3729     m_compressedTexture.decompress(m_decompressedAccess,
3730                                    tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3731 }
3732 
getDecompressedAccess() const3733 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3734 {
3735     return m_decompressedAccess;
3736 }
3737 
getCompressedTexture() const3738 const tcu::CompressedTexture &CompressedTextureForBlit::getCompressedTexture() const
3739 {
3740     return m_compressedTexture;
3741 }
3742 
3743 // Copy from image to image with scaling.
3744 
3745 class BlittingImages : public CopiesAndBlittingTestInstance
3746 {
3747 public:
3748     BlittingImages(Context &context, TestParams params);
3749     virtual tcu::TestStatus iterate(void);
3750 
3751 protected:
3752     virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
3753     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
3754                                           CopyRegion region, uint32_t mipLevel = 0u);
3755     virtual void generateExpectedResult(void);
3756     void uploadCompressedImage(const VkImage &image, const ImageParms &parms);
3757 
3758 private:
3759     bool checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3760                                        const tcu::ConstPixelBufferAccess &clampedReference,
3761                                        const tcu::ConstPixelBufferAccess &unclampedReference,
3762                                        const tcu::TextureFormat &sourceFormat);
3763     bool checkNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3764                                     const tcu::ConstPixelBufferAccess &source);
3765 
3766     bool checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3767                                                  const tcu::ConstPixelBufferAccess &clampedReference,
3768                                                  const tcu::ConstPixelBufferAccess &unclampedReference,
3769                                                  const tcu::CompressedTexFormat format);
3770     bool checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
3771                                               const tcu::ConstPixelBufferAccess &source,
3772                                               const tcu::CompressedTexFormat format);
3773 
3774     Move<VkImage> m_source;
3775     de::MovePtr<Allocation> m_sourceImageAlloc;
3776     Move<VkImage> m_destination;
3777     de::MovePtr<Allocation> m_destinationImageAlloc;
3778     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
3779     Move<VkSemaphore> m_sparseSemaphore;
3780 
3781     de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel;
3782 
3783     // helper used only when bliting from compressed formats
3784     typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3785     CompressedTextureForBlitSp m_sourceCompressedTexture;
3786     CompressedTextureForBlitSp m_destinationCompressedTexture;
3787 };
3788 
BlittingImages(Context & context,TestParams params)3789 BlittingImages::BlittingImages(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
3790 {
3791     const InstanceInterface &vki        = context.getInstanceInterface();
3792     const DeviceInterface &vk           = context.getDeviceInterface();
3793     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3794     const VkDevice vkDevice             = m_device;
3795     Allocator &memAlloc                 = context.getDefaultAllocator();
3796 
3797     // Create source image
3798     {
3799         VkImageCreateInfo sourceImageParams = {
3800             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
3801             DE_NULL,                                                           // const void* pNext;
3802             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
3803             m_params.src.image.imageType,                                      // VkImageType imageType;
3804             m_params.src.image.format,                                         // VkFormat format;
3805             getExtent3D(m_params.src.image),                                   // VkExtent3D extent;
3806             1u,                                                                // uint32_t mipLevels;
3807             getArraySize(m_params.src.image),                                  // uint32_t arraySize;
3808             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
3809             m_params.src.image.tiling,                                         // VkImageTiling tiling;
3810             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3811             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
3812             0u,                                                                // uint32_t queueFamilyIndexCount;
3813             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
3814             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
3815         };
3816 
3817 #ifndef CTS_USES_VULKANSC
3818         if (!params.useSparseBinding)
3819         {
3820 #endif
3821             m_source           = createImage(vk, m_device, &sourceImageParams);
3822             m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
3823                                                *m_allocator, m_params.allocationKind, 0u);
3824             VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
3825                                         m_sourceImageAlloc->getOffset()));
3826 #ifndef CTS_USES_VULKANSC
3827         }
3828         else
3829         {
3830             sourceImageParams.flags |=
3831                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
3832             vk::VkImageFormatProperties imageFormatProperties;
3833             if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
3834                                                            sourceImageParams.imageType, sourceImageParams.tiling,
3835                                                            sourceImageParams.usage, sourceImageParams.flags,
3836                                                            &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
3837             {
3838                 TCU_THROW(NotSupportedError, "Image format not supported");
3839             }
3840             m_source = createImage(
3841                 vk, m_device,
3842                 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
3843             m_sparseSemaphore = createSemaphore(vk, m_device);
3844             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
3845                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
3846                                        mapVkFormat(sourceImageParams.format), m_source.get());
3847         }
3848 #endif
3849     }
3850 
3851     // Create destination image
3852     {
3853         const VkImageCreateInfo destinationImageParams = {
3854             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
3855             DE_NULL,                                                           // const void* pNext;
3856             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
3857             m_params.dst.image.imageType,                                      // VkImageType imageType;
3858             m_params.dst.image.format,                                         // VkFormat format;
3859             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
3860             1u,                                                                // uint32_t mipLevels;
3861             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
3862             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
3863             m_params.dst.image.tiling,                                         // VkImageTiling tiling;
3864             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3865             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
3866             0u,                                                                // uint32_t queueFamilyIndexCount;
3867             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
3868             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
3869         };
3870 
3871         m_destination           = createImage(vk, vkDevice, &destinationImageParams);
3872         m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any,
3873                                                 memAlloc, m_params.allocationKind, 0u);
3874         VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(),
3875                                     m_destinationImageAlloc->getOffset()));
3876     }
3877 }
3878 
iterate(void)3879 tcu::TestStatus BlittingImages::iterate(void)
3880 {
3881     const DeviceInterface &vk        = m_context.getDeviceInterface();
3882     const VkDevice vkDevice          = m_device;
3883     const ImageParms &srcImageParams = m_params.src.image;
3884     const int srcWidth               = static_cast<int>(srcImageParams.extent.width);
3885     const int srcHeight              = static_cast<int>(srcImageParams.extent.height);
3886     const int srcDepth               = static_cast<int>(srcImageParams.extent.depth);
3887     const ImageParms &dstImageParams = m_params.dst.image;
3888     const int dstWidth               = static_cast<int>(dstImageParams.extent.width);
3889     const int dstHeight              = static_cast<int>(dstImageParams.extent.height);
3890     const int dstDepth               = static_cast<int>(dstImageParams.extent.depth);
3891 
3892     std::vector<VkImageBlit> regions;
3893     std::vector<VkImageBlit2KHR> regions2KHR;
3894 
3895     // setup blit regions - they are also needed for reference generation
3896     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3897     {
3898         regions.reserve(m_params.regions.size());
3899         for (const auto &r : m_params.regions)
3900             regions.push_back(r.imageBlit);
3901     }
3902     else
3903     {
3904         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
3905         regions2KHR.reserve(m_params.regions.size());
3906         for (const auto &r : m_params.regions)
3907             regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3908     }
3909 
3910     // generate source image
3911     if (isCompressedFormat(srcImageParams.format))
3912     {
3913         // for compressed images srcImageParams.fillMode is not used - we are using random data
3914         tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3915         m_sourceCompressedTexture =
3916             CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3917         uploadCompressedImage(m_source.get(), srcImageParams);
3918     }
3919     else
3920     {
3921         // non-compressed image is filled with selected fillMode
3922         const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3923         m_sourceTextureLevel =
3924             de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3925         generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3926         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3927     }
3928 
3929     // generate destination image
3930     if (isCompressedFormat(dstImageParams.format))
3931     {
3932         // compressed images are filled with random data
3933         tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3934         m_destinationCompressedTexture =
3935             CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3936         uploadCompressedImage(m_destination.get(), dstImageParams);
3937     }
3938     else
3939     {
3940         // non-compressed image is filled with white background
3941         const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3942         m_destinationTextureLevel =
3943             de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3944         generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3945         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3946     }
3947 
3948     generateExpectedResult();
3949 
3950     // Barriers for copying images to buffer
3951     const VkImageMemoryBarrier imageBarriers[]{
3952         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3953          DE_NULL,                                // const void* pNext;
3954          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
3955          VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
3956          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
3957          srcImageParams.operationLayout,         // VkImageLayout newLayout;
3958          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
3959          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
3960          m_source.get(),                         // VkImage image;
3961          {
3962              // VkImageSubresourceRange subresourceRange;
3963              getAspectFlags(srcImageParams.format), //   VkImageAspectFlags aspectMask;
3964              0u,                                    //   uint32_t baseMipLevel;
3965              1u,                                    //   uint32_t mipLevels;
3966              0u,                                    //   uint32_t baseArraySlice;
3967              getArraySize(m_params.src.image)       //   uint32_t arraySize;
3968          }},
3969         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3970          DE_NULL,                                // const void* pNext;
3971          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
3972          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
3973          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
3974          dstImageParams.operationLayout,         // VkImageLayout newLayout;
3975          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
3976          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
3977          m_destination.get(),                    // VkImage image;
3978          {
3979              // VkImageSubresourceRange subresourceRange;
3980              getAspectFlags(dstImageParams.format), //   VkImageAspectFlags aspectMask;
3981              0u,                                    //   uint32_t baseMipLevel;
3982              1u,                                    //   uint32_t mipLevels;
3983              0u,                                    //   uint32_t baseArraySlice;
3984              getArraySize(m_params.dst.image)       //   uint32_t arraySize;
3985          }}};
3986 
3987     beginCommandBuffer(vk, *m_universalCmdBuffer);
3988     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3989                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
3990                           (const VkBufferMemoryBarrier *)DE_NULL, 2, imageBarriers);
3991 
3992     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
3993     {
3994         vk.cmdBlitImage(*m_universalCmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(),
3995                         dstImageParams.operationLayout, (uint32_t)m_params.regions.size(), &regions[0],
3996                         m_params.filter);
3997     }
3998     else
3999     {
4000         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
4001         const VkBlitImageInfo2KHR blitImageInfo2KHR{
4002             VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4003             DE_NULL,                                 // const void* pNext;
4004             m_source.get(),                          // VkImage srcImage;
4005             srcImageParams.operationLayout,          // VkImageLayout srcImageLayout;
4006             m_destination.get(),                     // VkImage dstImage;
4007             dstImageParams.operationLayout,          // VkImageLayout dstImageLayout;
4008             (uint32_t)m_params.regions.size(),       // uint32_t regionCount;
4009             &regions2KHR[0],                         // const VkImageBlit2KHR* pRegions;
4010             m_params.filter,                         // VkFilter filter;
4011         };
4012         vk.cmdBlitImage2(*m_universalCmdBuffer, &blitImageInfo2KHR);
4013     }
4014 
4015     endCommandBuffer(vk, *m_universalCmdBuffer);
4016     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
4017     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
4018 
4019     de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, dstImageParams);
4020     tcu::PixelBufferAccess resultAccess        = resultLevel->getAccess();
4021 
4022     // if blit was done to a compressed format we need to decompress it to be able to verify it
4023     if (m_destinationCompressedTexture)
4024     {
4025         uint8_t *const compressedDataSrc(static_cast<uint8_t *>(resultAccess.getDataPtr()));
4026         const tcu::CompressedTexFormat dstCompressedFormat(mapVkCompressedFormat(dstImageParams.format));
4027         tcu::TextureLevel decompressedLevel(getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
4028         tcu::PixelBufferAccess decompressedAccess(decompressedLevel.getAccess());
4029 
4030         tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
4031 
4032         return checkTestResult(decompressedAccess);
4033     }
4034 
4035     return checkTestResult(resultAccess);
4036 }
4037 
calculateFloatConversionError(int srcBits)4038 static float calculateFloatConversionError(int srcBits)
4039 {
4040     if (srcBits > 0)
4041     {
4042         const int clampedBits   = de::clamp<int>(srcBits, 0, 32);
4043         const float srcMaxValue = de::max((float)(1ULL << clampedBits) - 1.0f, 1.0f);
4044         const float error       = 1.0f / srcMaxValue;
4045 
4046         return de::clamp<float>(error, 0.0f, 1.0f);
4047     }
4048     else
4049         return 1.0f;
4050 }
4051 
getFormatThreshold(const tcu::TextureFormat & format)4052 tcu::Vec4 getFormatThreshold(const tcu::TextureFormat &format)
4053 {
4054     tcu::Vec4 threshold(0.01f);
4055 
4056     switch (format.type)
4057     {
4058     case tcu::TextureFormat::HALF_FLOAT:
4059         threshold = tcu::Vec4(0.005f);
4060         break;
4061 
4062     case tcu::TextureFormat::FLOAT:
4063     case tcu::TextureFormat::FLOAT64:
4064         threshold = tcu::Vec4(0.001f);
4065         break;
4066 
4067     case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
4068         threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
4069         break;
4070 
4071     case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
4072         threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
4073         break;
4074 
4075     case tcu::TextureFormat::UNORM_INT_1010102_REV:
4076         threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
4077         break;
4078 
4079     case tcu::TextureFormat::UNORM_INT8:
4080         threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
4081         break;
4082 
4083     default:
4084         const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
4085         threshold = tcu::Vec4(calculateFloatConversionError(bits.x()), calculateFloatConversionError(bits.y()),
4086                               calculateFloatConversionError(bits.z()), calculateFloatConversionError(bits.w()));
4087     }
4088 
4089     // Return value matching the channel order specified by the format
4090     if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
4091         return threshold.swizzle(2, 1, 0, 3);
4092     else
4093         return threshold;
4094 }
4095 
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)4096 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat &format)
4097 {
4098     bool isSigned(false);
4099     tcu::IVec4 bitDepth(0);
4100 
4101     switch (format)
4102     {
4103     case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
4104         bitDepth = {7, 0, 0, 0};
4105         isSigned = true;
4106         break;
4107 
4108     case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
4109         bitDepth = {8, 0, 0, 0};
4110         break;
4111 
4112     case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
4113         bitDepth = {7, 7, 0, 0};
4114         isSigned = true;
4115         break;
4116 
4117     case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
4118         bitDepth = {8, 8, 0, 0};
4119         break;
4120 
4121     case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
4122     case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
4123     case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
4124         bitDepth = {8, 8, 8, 0};
4125         break;
4126 
4127     case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
4128     case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
4129         bitDepth = {8, 8, 8, 1};
4130         break;
4131 
4132     case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
4133     case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
4134     case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
4135     case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
4136     case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
4137     case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
4138     case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
4139     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
4140     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
4141     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
4142     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
4143     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
4144     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
4145     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
4146     case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
4147     case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
4148     case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
4149     case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
4150     case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
4151     case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
4152     case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
4153     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
4154     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
4155     case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
4156     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
4157     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
4158     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
4159     case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
4160     case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
4161     case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
4162         bitDepth = {8, 8, 8, 8};
4163         break;
4164 
4165     case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
4166     case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
4167     case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
4168     case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
4169     case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
4170     case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
4171         bitDepth = {5, 6, 5, 0};
4172         break;
4173 
4174     case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
4175     case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
4176     case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
4177     case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
4178         bitDepth = {5, 5, 5, 1};
4179         break;
4180 
4181     case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
4182         bitDepth = {7, 0, 0, 0};
4183         isSigned = true;
4184         break;
4185 
4186     case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
4187         bitDepth = {8, 0, 0, 0};
4188         break;
4189 
4190     case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
4191         bitDepth = {7, 7, 0, 0};
4192         isSigned = true;
4193         break;
4194 
4195     case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
4196         bitDepth = {8, 8, 0, 0};
4197         break;
4198 
4199     case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
4200         return tcu::Vec4(0.01f);
4201     case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
4202         return tcu::Vec4(0.005f);
4203 
4204     default:
4205         DE_ASSERT(false);
4206     }
4207 
4208     const float range = isSigned ? 1.0f - (-1.0f) : 1.0f - 0.0f;
4209     tcu::Vec4 v;
4210     for (int i = 0; i < 4; ++i)
4211     {
4212         if (bitDepth[i] == 0)
4213             v[i] = 1.0f;
4214         else
4215             v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
4216     }
4217     return v;
4218 }
4219 
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)4220 bool BlittingImages::checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4221                                                    const tcu::ConstPixelBufferAccess &clampedExpected,
4222                                                    const tcu::ConstPixelBufferAccess &unclampedExpected,
4223                                                    const tcu::TextureFormat &srcFormat)
4224 {
4225     tcu::TestLog &log(m_context.getTestContext().getLog());
4226     const tcu::TextureFormat dstFormat             = result.getFormat();
4227     const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
4228     const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
4229     bool isOk                                      = false;
4230 
4231     log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
4232 
4233     // if either of srcImage or dstImage stores values as a signed/unsigned integer,
4234     // the other must also store values a signed/unsigned integer
4235     // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4236     // despite the fact that both formats are sampled as floats
4237     bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4238                               dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4239     bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4240                               srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4241     if (dstImageIsIntClass != srcImageIsIntClass)
4242     {
4243         log << tcu::TestLog::EndSection;
4244         return false;
4245     }
4246 
4247     if (isFloatFormat(dstFormat))
4248     {
4249         const bool srcIsSRGB       = tcu::isSRGB(srcFormat);
4250         const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
4251         const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
4252         const tcu::Vec4 threshold =
4253             (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
4254 
4255         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold,
4256                                           tcu::COMPARE_LOG_RESULT);
4257         log << tcu::TestLog::EndSection;
4258 
4259         if (!isOk)
4260         {
4261             log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4262             isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold,
4263                                               tcu::COMPARE_LOG_RESULT);
4264             log << tcu::TestLog::EndSection;
4265         }
4266     }
4267     else
4268     {
4269         tcu::UVec4 threshold;
4270         // Calculate threshold depending on channel width of destination format.
4271         const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
4272         const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
4273         for (uint32_t i = 0; i < 4; ++i)
4274         {
4275             DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
4276             DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
4277             uint64_t threshold64 =
4278                 1 + de::max(((UINT64_C(1) << dstBitDepth[i]) - 1) /
4279                                 de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)),
4280                             UINT64_C(1));
4281             DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
4282             threshold[i] = static_cast<uint32_t>(threshold64);
4283         }
4284 
4285         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold,
4286                                         tcu::COMPARE_LOG_RESULT);
4287         log << tcu::TestLog::EndSection;
4288 
4289         if (!isOk)
4290         {
4291             log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4292             isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold,
4293                                             tcu::COMPARE_LOG_RESULT);
4294             log << tcu::TestLog::EndSection;
4295         }
4296     }
4297 
4298     return isOk;
4299 }
4300 
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)4301 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4302                                                              const tcu::ConstPixelBufferAccess &clampedReference,
4303                                                              const tcu::ConstPixelBufferAccess &unclampedReference,
4304                                                              const tcu::CompressedTexFormat format)
4305 {
4306     tcu::TestLog &log                  = m_context.getTestContext().getLog();
4307     const tcu::TextureFormat dstFormat = result.getFormat();
4308 
4309     // there are rare cases wher one or few pixels have slightly bigger error
4310     // in one of channels this accepted error allows those casses to pass
4311     const tcu::Vec4 acceptedError(0.06f);
4312 
4313     const tcu::Vec4 srcMaxDiff = getCompressedFormatThreshold(format);
4314     const tcu::Vec4 dstMaxDiff =
4315         m_destinationCompressedTexture ?
4316             getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4317             getFormatThreshold(dstFormat);
4318     const tcu::Vec4 threshold =
4319         (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
4320 
4321     bool filteredResultVerification(false);
4322     tcu::Vec4 filteredResultMinValue(-6e6);
4323     tcu::Vec4 filteredResultMaxValue(6e6);
4324     tcu::TextureLevel filteredResult;
4325     tcu::TextureLevel filteredClampedReference;
4326     tcu::TextureLevel filteredUnclampedReference;
4327 
4328     if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4329          (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
4330     {
4331         if ((dstFormat.type == tcu::TextureFormat::FLOAT) || (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
4332         {
4333             // for compressed formats we are using random data and for bc6h formats
4334             // this will give us also large color values; when we are bliting to
4335             // a format that accepts large values we can end up with large diferences
4336             // betwean filtered result and reference; to avoid that we need to remove
4337             // values that are to big from verification
4338             filteredResultVerification = true;
4339             filteredResultMinValue     = tcu::Vec4(-10.0f);
4340             filteredResultMaxValue     = tcu::Vec4(10.0f);
4341         }
4342         else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4343         {
4344             // we need to clamp some formats to <0;1> range as it has
4345             // small precision for big numbers compared to reference
4346             filteredResultVerification = true;
4347             filteredResultMinValue     = tcu::Vec4(0.0f);
4348             filteredResultMaxValue     = tcu::Vec4(1.0f);
4349         }
4350         // else don't use filtered verification
4351     }
4352 
4353     if (filteredResultVerification)
4354     {
4355         filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4356         tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
4357 
4358         filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4359         tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
4360 
4361         filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
4362         tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
4363 
4364         for (int32_t z = 0; z < result.getDepth(); z++)
4365             for (int32_t y = 0; y < result.getHeight(); y++)
4366                 for (int32_t x = 0; x < result.getWidth(); x++)
4367                 {
4368                     tcu::Vec4 resultTexel             = result.getPixel(x, y, z);
4369                     tcu::Vec4 clampedReferenceTexel   = clampedReference.getPixel(x, y, z);
4370                     tcu::Vec4 unclampedReferenceTexel = unclampedReference.getPixel(x, y, z);
4371 
4372                     resultTexel = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
4373                     clampedReferenceTexel =
4374                         tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
4375                     unclampedReferenceTexel =
4376                         tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
4377 
4378                     filteredResultAcccess.setPixel(resultTexel, x, y, z);
4379                     filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
4380                     filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
4381                 }
4382     }
4383 
4384     const tcu::ConstPixelBufferAccess clampedRef =
4385         filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
4386     const tcu::ConstPixelBufferAccess res = filteredResultVerification ? filteredResult.getAccess() : result;
4387 
4388     log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
4389     bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold,
4390                                            tcu::COMPARE_LOG_RESULT);
4391     log << tcu::TestLog::EndSection;
4392 
4393     if (!isOk)
4394     {
4395         const tcu::ConstPixelBufferAccess unclampedRef =
4396             filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
4397 
4398         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
4399         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold,
4400                                           tcu::COMPARE_LOG_RESULT);
4401         log << tcu::TestLog::EndSection;
4402     }
4403 
4404     return isOk;
4405 }
4406 
4407 //! Utility to encapsulate coordinate computation and loops.
4408 struct CompareEachPixelInEachRegion
4409 {
4410 protected:
getUsedZRangevkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4411     void getUsedZRange(int32_t range[2], const ImageParms &imgParams, const VkImageSubresourceLayers &layers,
4412                        const VkOffset3D offsets[2]) const
4413     {
4414         if (imgParams.imageType == VK_IMAGE_TYPE_3D)
4415         {
4416             range[0] = offsets[0].z;
4417             range[1] = offsets[1].z;
4418         }
4419         else if (imgParams.imageType == VK_IMAGE_TYPE_2D)
4420         {
4421             range[0] = static_cast<int32_t>(layers.baseArrayLayer);
4422             range[1] =
4423                 static_cast<int32_t>(layers.baseArrayLayer + ((layers.layerCount == VK_REMAINING_ARRAY_LAYERS) ?
4424                                                                   (getArraySize(imgParams) - layers.baseArrayLayer) :
4425                                                                   layers.layerCount));
4426         }
4427         else
4428         {
4429             range[0] = 0;
4430             range[1] = 1;
4431         }
4432     }
4433 
4434 public:
~CompareEachPixelInEachRegionvkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4435     virtual ~CompareEachPixelInEachRegion(void)
4436     {
4437     }
4438     virtual bool compare(const void *pUserData, const int x, const int y, const int z,
4439                          const tcu::Vec3 &srcNormCoord) const = 0;
4440 
forEachvkt::api::__anonbd1d8d730111::CompareEachPixelInEachRegion4441     bool forEach(const void *pUserData, const TestParams &params, const int sourceWidth, const int sourceHeight,
4442                  const int sourceDepth, const tcu::PixelBufferAccess &errorMask) const
4443     {
4444         bool compareOk = true;
4445 
4446         for (std::vector<CopyRegion>::const_iterator regionIter = params.regions.begin();
4447              regionIter != params.regions.end(); ++regionIter)
4448         {
4449             const VkImageBlit &blit = regionIter->imageBlit;
4450 
4451             int32_t srcZ[2];
4452             int32_t dstZ[2];
4453 
4454             getUsedZRange(srcZ, params.src.image, blit.srcSubresource, blit.srcOffsets);
4455             getUsedZRange(dstZ, params.dst.image, blit.dstSubresource, blit.dstOffsets);
4456 
4457             const int xStart   = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
4458             const int yStart   = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
4459             const int zStart   = deMin32(dstZ[0], dstZ[1]);
4460             const int xEnd     = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
4461             const int yEnd     = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
4462             const int zEnd     = deMax32(dstZ[0], dstZ[1]);
4463             const float xScale = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) /
4464                                  static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
4465             const float yScale = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) /
4466                                  static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
4467             const float zScale  = static_cast<float>(srcZ[1] - srcZ[0]) / static_cast<float>(dstZ[1] - dstZ[0]);
4468             const float srcInvW = 1.0f / static_cast<float>(sourceWidth);
4469             const float srcInvH = 1.0f / static_cast<float>(sourceHeight);
4470             const float srcInvD = 1.0f / static_cast<float>(sourceDepth);
4471 
4472             for (int z = zStart; z < zEnd; z++)
4473                 for (int y = yStart; y < yEnd; y++)
4474                     for (int x = xStart; x < xEnd; x++)
4475                     {
4476                         const tcu::Vec3 srcNormCoord(
4477                             (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) +
4478                              static_cast<float>(blit.srcOffsets[0].x)) *
4479                                 srcInvW,
4480                             (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) +
4481                              static_cast<float>(blit.srcOffsets[0].y)) *
4482                                 srcInvH,
4483                             (zScale * (static_cast<float>(z - dstZ[0]) + 0.5f) + static_cast<float>(srcZ[0])) *
4484                                 srcInvD);
4485 
4486                         if (!compare(pUserData, x, y, z, srcNormCoord))
4487                         {
4488                             errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
4489                             compareOk = false;
4490                         }
4491                     }
4492         }
4493         return compareOk;
4494     }
4495 };
4496 
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)4497 tcu::Vec4 getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat &format)
4498 {
4499     const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4500     const tcu::IVec4 bitDepth                   = tcu::getTextureFormatBitDepth(format);
4501 
4502     if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
4503     {
4504         return getFormatThreshold(format);
4505     }
4506     else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
4507              channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
4508     {
4509         const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
4510         const float range   = isSigned ? 1.0f - (-1.0f) : 1.0f - 0.0f;
4511 
4512         tcu::Vec4 v;
4513         for (int i = 0; i < 4; ++i)
4514         {
4515             if (bitDepth[i] == 0)
4516                 v[i] = 1.0f;
4517             else
4518                 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
4519         }
4520         return v;
4521     }
4522     else
4523     {
4524         DE_ASSERT(0);
4525         return tcu::Vec4();
4526     }
4527 }
4528 
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::Vec4 & sourceThreshold,const tcu::Vec4 & resultThreshold,const tcu::PixelBufferAccess & errorMask,const TestParams & params)4529 bool floatNearestBlitCompare(const tcu::ConstPixelBufferAccess &source, const tcu::ConstPixelBufferAccess &result,
4530                              const tcu::Vec4 &sourceThreshold, const tcu::Vec4 &resultThreshold,
4531                              const tcu::PixelBufferAccess &errorMask, const TestParams &params)
4532 {
4533     const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4534                                tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE,
4535                                0, tcu::Vec4(0.0f), true);
4536     const tcu::IVec4 dstBitDepth(tcu::getTextureFormatBitDepth(result.getFormat()));
4537     tcu::LookupPrecision precision;
4538 
4539     precision.colorMask      = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
4540     precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
4541 
4542     const struct Capture
4543     {
4544         const tcu::ConstPixelBufferAccess &source;
4545         const tcu::ConstPixelBufferAccess &result;
4546         const tcu::Sampler &sampler;
4547         const tcu::LookupPrecision &precision;
4548         const TestParams &params;
4549         const bool isSRGB;
4550     } capture = {source, result, sampler, precision, params, tcu::isSRGB(result.getFormat())};
4551 
4552     const struct Loop : CompareEachPixelInEachRegion
4553     {
4554         Loop(void)
4555         {
4556         }
4557 
4558         bool compare(const void *pUserData, const int x, const int y, const int z, const tcu::Vec3 &srcNormCoord) const
4559         {
4560             const Capture &c                                  = *static_cast<const Capture *>(pUserData);
4561             const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
4562             tcu::Vec4 dstColor                                = c.result.getPixel(x, y, z);
4563 
4564             // TexLookupVerifier performs a conversion to linear space, so we have to as well
4565             if (c.isSRGB)
4566                 dstColor = tcu::sRGBToLinear(dstColor);
4567 
4568             return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord,
4569                                                    dstColor);
4570         }
4571     } loop;
4572 
4573     return loop.forEach(&capture, params, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
4574 }
4575 
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const TestParams & params)4576 bool intNearestBlitCompare(const tcu::ConstPixelBufferAccess &source, const tcu::ConstPixelBufferAccess &result,
4577                            const tcu::PixelBufferAccess &errorMask, const TestParams &params)
4578 {
4579     const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4580                                tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0.0f, true, tcu::Sampler::COMPAREMODE_NONE,
4581                                0, tcu::Vec4(0.0f), true);
4582     tcu::IntLookupPrecision precision;
4583 
4584     {
4585         const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat());
4586         const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat());
4587 
4588         for (uint32_t i = 0; i < 4; ++i)
4589         {
4590             precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
4591             precision.colorMask[i]      = dstBitDepth[i] != 0;
4592         }
4593     }
4594 
4595     // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
4596     // does the conversion on the fly without wasting memory, but this approach is more straightforward.
4597     tcu::TextureLevel convertedSourceTexture(result.getFormat(), source.getWidth(), source.getHeight(),
4598                                              source.getDepth());
4599     const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess();
4600 
4601     for (int z = 0; z < source.getDepth(); ++z)
4602         for (int y = 0; y < source.getHeight(); ++y)
4603             for (int x = 0; x < source.getWidth(); ++x)
4604                 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y,
4605                                          z); // will be clamped to max. representable value
4606 
4607     const struct Capture
4608     {
4609         const tcu::ConstPixelBufferAccess &source;
4610         const tcu::ConstPixelBufferAccess &result;
4611         const tcu::Sampler &sampler;
4612         const tcu::IntLookupPrecision &precision;
4613     } capture = {convertedSource, result, sampler, precision};
4614 
4615     const struct Loop : CompareEachPixelInEachRegion
4616     {
4617         Loop(void)
4618         {
4619         }
4620 
4621         bool compare(const void *pUserData, const int x, const int y, const int z, const tcu::Vec3 &srcNormCoord) const
4622         {
4623             const Capture &c                                  = *static_cast<const Capture *>(pUserData);
4624             const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
4625             const tcu::IVec4 dstColor                         = c.result.getPixelInt(x, y, z);
4626 
4627             return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord,
4628                                                    dstColor);
4629         }
4630     } loop;
4631 
4632     return loop.forEach(&capture, params, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
4633 }
4634 
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)4635 bool BlittingImages::checkNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4636                                                 const tcu::ConstPixelBufferAccess &source)
4637 {
4638     tcu::TestLog &log(m_context.getTestContext().getLog());
4639     const tcu::TextureFormat dstFormat             = result.getFormat();
4640     const tcu::TextureFormat srcFormat             = source.getFormat();
4641     const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
4642     const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
4643 
4644     tcu::TextureLevel errorMaskStorage(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8),
4645                                        result.getWidth(), result.getHeight(), result.getDepth());
4646     tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
4647     tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
4648     tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
4649     bool ok = false;
4650 
4651     tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4652 
4653     // if either of srcImage or dstImage stores values as a signed/unsigned integer,
4654     // the other must also store values a signed/unsigned integer
4655     // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4656     // despite the fact that both formats are sampled as floats
4657     bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4658                               dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4659     bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4660                               srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4661     if (dstImageIsIntClass != srcImageIsIntClass)
4662         return false;
4663 
4664     if (dstImageIsIntClass)
4665     {
4666         ok = intNearestBlitCompare(source, result, errorMask, m_params);
4667     }
4668     else
4669     {
4670         const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
4671         const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4672         ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params);
4673     }
4674 
4675     if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4676         tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4677 
4678     if (!ok)
4679     {
4680         log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4681             << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4682             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
4683     }
4684     else
4685     {
4686         log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4687             << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << tcu::TestLog::EndImageSet;
4688     }
4689 
4690     return ok;
4691 }
4692 
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4693 bool BlittingImages::checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess &result,
4694                                                           const tcu::ConstPixelBufferAccess &source,
4695                                                           const tcu::CompressedTexFormat format)
4696 {
4697     tcu::TestLog &log(m_context.getTestContext().getLog());
4698     tcu::TextureFormat errorMaskFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4699     tcu::TextureLevel errorMaskStorage(errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4700     tcu::PixelBufferAccess errorMask(errorMaskStorage.getAccess());
4701     tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
4702     tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
4703     const tcu::TextureFormat &resultFormat(result.getFormat());
4704     VkFormat nativeResultFormat(mapTextureFormat(resultFormat));
4705 
4706     // there are rare cases wher one or few pixels have slightly bigger error
4707     // in one of channels this accepted error allows those casses to pass
4708     const tcu::Vec4 acceptedError(0.04f);
4709     const tcu::Vec4 srcMaxDiff(acceptedError + getCompressedFormatThreshold(format));
4710     const tcu::Vec4 dstMaxDiff(
4711         acceptedError +
4712         (m_destinationCompressedTexture ?
4713              getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4714              getFloatOrFixedPointFormatThreshold(resultFormat)));
4715 
4716     tcu::TextureLevel clampedSourceLevel;
4717     bool clampSource(false);
4718     tcu::Vec4 clampSourceMinValue(-1.0f);
4719     tcu::Vec4 clampSourceMaxValue(1.0f);
4720     tcu::TextureLevel clampedResultLevel;
4721     bool clampResult(false);
4722 
4723     tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4724 
4725     if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4726         tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4727 
4728     log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4729         << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4730 
4731     // for compressed formats source buffer access is not actual compressed format
4732     // but equivalent uncompressed format that is some cases needs additional
4733     // modifications so that sampling it will produce valid reference
4734     if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4735         (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4736     {
4737         if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4738         {
4739             // for compressed formats we are using random data and for some formats it
4740             // can be outside of <-1;1> range - for cases where result is not a float
4741             // format we need to clamp source to <-1;1> range as this will be done on
4742             // the device but not in software sampler in framework
4743             clampSource = true;
4744             // for this format we also need to clamp the result as precision of
4745             // this format is smaller then precision of calculations in framework;
4746             // the biger color valus are the bigger errors can be
4747             clampResult = true;
4748 
4749             if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4750                 clampSourceMinValue = tcu::Vec4(0.0f);
4751         }
4752         else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4753                  (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4754         {
4755             // clamp source for all non float formats
4756             clampSource = true;
4757         }
4758     }
4759 
4760     if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4761     {
4762         // when tested compressed format is signed but the result format
4763         // is unsigned we need to clamp source to <0; x> so that proper
4764         // reference is calculated
4765         if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4766             (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4767             (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4768             (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4769             (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4770         {
4771             clampSource         = true;
4772             clampSourceMinValue = tcu::Vec4(0.0f);
4773         }
4774     }
4775 
4776     if (clampSource || clampResult)
4777     {
4778         if (clampSource)
4779         {
4780             clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4781             tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4782 
4783             for (int32_t z = 0; z < source.getDepth(); z++)
4784                 for (int32_t y = 0; y < source.getHeight(); y++)
4785                     for (int32_t x = 0; x < source.getWidth(); x++)
4786                     {
4787                         tcu::Vec4 texel = source.getPixel(x, y, z);
4788                         texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4789                         clampedSourceAcccess.setPixel(texel, x, y, z);
4790                     }
4791         }
4792 
4793         if (clampResult)
4794         {
4795             clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4796             tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4797 
4798             for (int32_t z = 0; z < result.getDepth(); z++)
4799                 for (int32_t y = 0; y < result.getHeight(); y++)
4800                     for (int32_t x = 0; x < result.getWidth(); x++)
4801                     {
4802                         tcu::Vec4 texel = result.getPixel(x, y, z);
4803                         texel           = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4804                         clampedResultAcccess.setPixel(texel, x, y, z);
4805                     }
4806         }
4807     }
4808 
4809     const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4810     const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4811 
4812     if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params))
4813     {
4814         log << tcu::TestLog::EndImageSet;
4815         return true;
4816     }
4817 
4818     log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
4819     return false;
4820 }
4821 
checkTestResult(tcu::ConstPixelBufferAccess result)4822 tcu::TestStatus BlittingImages::checkTestResult(tcu::ConstPixelBufferAccess result)
4823 {
4824     DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR ||
4825               m_params.filter == VK_FILTER_CUBIC_EXT);
4826     const std::string failMessage("Result image is incorrect");
4827 
4828     if (m_params.filter != VK_FILTER_NEAREST)
4829     {
4830         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4831         {
4832             if (tcu::hasDepthComponent(result.getFormat().order))
4833             {
4834                 const tcu::Sampler::DepthStencilMode mode     = tcu::Sampler::MODE_DEPTH;
4835                 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4836                 const tcu::ConstPixelBufferAccess clampedExpected =
4837                     tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4838                 const tcu::ConstPixelBufferAccess unclampedExpected =
4839                     tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4840                 const tcu::TextureFormat sourceFormat =
4841                     tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4842 
4843                 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4844                     return tcu::TestStatus::fail(failMessage);
4845             }
4846 
4847             if (tcu::hasStencilComponent(result.getFormat().order))
4848             {
4849                 const tcu::Sampler::DepthStencilMode mode       = tcu::Sampler::MODE_STENCIL;
4850                 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4851                 const tcu::ConstPixelBufferAccess clampedExpected =
4852                     tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4853                 const tcu::ConstPixelBufferAccess unclampedExpected =
4854                     tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4855                 const tcu::TextureFormat sourceFormat =
4856                     tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4857 
4858                 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4859                     return tcu::TestStatus::fail(failMessage);
4860             }
4861         }
4862         else if (m_sourceCompressedTexture)
4863         {
4864             const tcu::CompressedTexture &compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4865             if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(),
4866                                                          m_unclampedExpectedTextureLevel->getAccess(),
4867                                                          compressedLevel.getFormat()))
4868                 return tcu::TestStatus::fail(failMessage);
4869         }
4870         else
4871         {
4872             const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4873             if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(),
4874                                                m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4875                 return tcu::TestStatus::fail(failMessage);
4876         }
4877     }
4878     else // NEAREST filtering
4879     {
4880         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4881         {
4882             if (tcu::hasDepthComponent(result.getFormat().order))
4883             {
4884                 const tcu::Sampler::DepthStencilMode mode     = tcu::Sampler::MODE_DEPTH;
4885                 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4886                 const tcu::ConstPixelBufferAccess depthSource =
4887                     tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4888 
4889                 if (!checkNearestFilteredResult(depthResult, depthSource))
4890                     return tcu::TestStatus::fail(failMessage);
4891             }
4892 
4893             if (tcu::hasStencilComponent(result.getFormat().order))
4894             {
4895                 const tcu::Sampler::DepthStencilMode mode       = tcu::Sampler::MODE_STENCIL;
4896                 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4897                 const tcu::ConstPixelBufferAccess stencilSource =
4898                     tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4899 
4900                 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4901                     return tcu::TestStatus::fail(failMessage);
4902             }
4903         }
4904         else if (m_sourceCompressedTexture)
4905         {
4906             const tcu::CompressedTexture &compressedLevel   = m_sourceCompressedTexture->getCompressedTexture();
4907             const tcu::PixelBufferAccess &decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4908 
4909             if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4910                 return tcu::TestStatus::fail(failMessage);
4911         }
4912         else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4913             return tcu::TestStatus::fail(failMessage);
4914     }
4915 
4916     return tcu::TestStatus::pass("Pass");
4917 }
4918 
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4919 tcu::Vec4 linearToSRGBIfNeeded(const tcu::TextureFormat &format, const tcu::Vec4 &color)
4920 {
4921     return isSRGB(format) ? linearToSRGB(color) : color;
4922 }
4923 
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4924 void scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
4925                              const VkOffset3D regionOffset, const VkOffset3D regionExtent,
4926                              tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4927 {
4928     DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4929 
4930     tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, filter,
4931                          filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4932 
4933     float sX = (float)regionExtent.x / (float)dst.getWidth();
4934     float sY = (float)regionExtent.y / (float)dst.getHeight();
4935     float sZ = (float)regionExtent.z / (float)dst.getDepth();
4936 
4937     for (int z = 0; z < dst.getDepth(); z++)
4938         for (int y = 0; y < dst.getHeight(); y++)
4939             for (int x = 0; x < dst.getWidth(); x++)
4940             {
4941                 float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ?
4942                                  (float)regionExtent.x + (float)regionOffset.x - ((float)x + 0.5f) * sX :
4943                                  (float)regionOffset.x + ((float)x + 0.5f) * sX;
4944                 float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ?
4945                                  (float)regionExtent.y + (float)regionOffset.y - ((float)y + 0.5f) * sY :
4946                                  (float)regionOffset.y + ((float)y + 0.5f) * sY;
4947                 float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ?
4948                                  (float)regionExtent.z + (float)regionOffset.z - ((float)z + 0.5f) * sZ :
4949                                  (float)regionOffset.z + ((float)z + 0.5f) * sZ;
4950                 if (dst.getDepth() > 1)
4951                     dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)),
4952                                  x, y, z);
4953                 else
4954                     dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x,
4955                                  y);
4956             }
4957 }
4958 
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4959 void blit(const tcu::PixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
4960           const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4961 {
4962     DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4963 
4964     tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, filter,
4965                          filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4966 
4967     const float sX = (float)src.getWidth() / (float)dst.getWidth();
4968     const float sY = (float)src.getHeight() / (float)dst.getHeight();
4969     const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4970 
4971     const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4972     const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4973     const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4974 
4975     const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4976     const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4977     const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4978 
4979     for (int z = 0; z < dst.getDepth(); ++z)
4980         for (int y = 0; y < dst.getHeight(); ++y)
4981             for (int x = 0; x < dst.getWidth(); ++x)
4982             {
4983                 dst.setPixel(
4984                     linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX,
4985                                                                        ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)),
4986                     x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
4987             }
4988 }
4989 
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4990 void flipCoordinates(CopyRegion &region, const MirrorMode mirrorMode)
4991 {
4992     const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4993     const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4994     const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4995     const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4996 
4997     if (mirrorMode != 0u)
4998     {
4999         //sourceRegion
5000         region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
5001         region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
5002         region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
5003 
5004         region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
5005         region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
5006         region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
5007 
5008         //destinationRegion
5009         region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
5010         region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
5011         region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
5012 
5013         region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
5014         region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
5015         region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
5016     }
5017 }
5018 
5019 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)5020 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
5021 {
5022     MirrorMode mode = 0u;
5023 
5024     if (from.x > to.x)
5025         mode |= MIRROR_MODE_X;
5026 
5027     if (from.y > to.y)
5028         mode |= MIRROR_MODE_Y;
5029 
5030     if (from.z > to.z)
5031         mode |= MIRROR_MODE_Z;
5032 
5033     return mode;
5034 }
5035 
5036 // Mirror the axes that are mirrored either in the source or destination, but not both.
getMirrorMode(const VkOffset3D s1,const VkOffset3D s2,const VkOffset3D d1,const VkOffset3D d2)5037 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
5038 {
5039     static const MirrorModeBits kBits[] = {MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z};
5040 
5041     const MirrorMode source      = getMirrorMode(s1, s2);
5042     const MirrorMode destination = getMirrorMode(d1, d2);
5043 
5044     MirrorMode mode = 0u;
5045 
5046     for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
5047     {
5048         const MirrorModeBits bit = kBits[i];
5049         if ((source & bit) != (destination & bit))
5050             mode |= bit;
5051     }
5052 
5053     return mode;
5054 }
5055 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)5056 void BlittingImages::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
5057                                               CopyRegion region, uint32_t mipLevel)
5058 {
5059     DE_UNREF(mipLevel);
5060 
5061     const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], region.imageBlit.srcOffsets[1],
5062                                                 region.imageBlit.dstOffsets[0], region.imageBlit.dstOffsets[1]);
5063 
5064     flipCoordinates(region, mirrorMode);
5065 
5066     const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
5067     const VkOffset3D srcExtent = {
5068         region.imageBlit.srcOffsets[1].x - srcOffset.x,
5069         region.imageBlit.srcOffsets[1].y - srcOffset.y,
5070         region.imageBlit.srcOffsets[1].z - srcOffset.z,
5071     };
5072     const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
5073     const VkOffset3D dstExtent = {
5074         region.imageBlit.dstOffsets[1].x - dstOffset.x,
5075         region.imageBlit.dstOffsets[1].y - dstOffset.y,
5076         region.imageBlit.dstOffsets[1].z - dstOffset.z,
5077     };
5078 
5079     tcu::Sampler::FilterMode filter;
5080     switch (m_params.filter)
5081     {
5082     case VK_FILTER_LINEAR:
5083         filter = tcu::Sampler::LINEAR;
5084         break;
5085     case VK_FILTER_CUBIC_EXT:
5086         filter = tcu::Sampler::CUBIC;
5087         break;
5088     case VK_FILTER_NEAREST:
5089     default:
5090         filter = tcu::Sampler::NEAREST;
5091         break;
5092     }
5093 
5094     if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5095     {
5096         DE_ASSERT(src.getFormat() == dst.getFormat());
5097 
5098         // Scale depth.
5099         if (tcu::hasDepthComponent(src.getFormat().order))
5100         {
5101             const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
5102                 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z),
5103                 tcu::Sampler::MODE_DEPTH);
5104             const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
5105                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5106                 tcu::Sampler::MODE_DEPTH);
5107             tcu::scale(dstSubRegion, srcSubRegion, filter);
5108 
5109             if (filter != tcu::Sampler::NEAREST)
5110             {
5111                 const tcu::ConstPixelBufferAccess depthSrc =
5112                     getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5113                 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
5114                     tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y,
5115                                       dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5116                     tcu::Sampler::MODE_DEPTH);
5117                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
5118             }
5119         }
5120 
5121         // Scale stencil.
5122         if (tcu::hasStencilComponent(src.getFormat().order))
5123         {
5124             const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
5125                 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z),
5126                 tcu::Sampler::MODE_STENCIL);
5127             const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
5128                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5129                 tcu::Sampler::MODE_STENCIL);
5130             blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5131 
5132             if (filter != tcu::Sampler::NEAREST)
5133             {
5134                 const tcu::ConstPixelBufferAccess stencilSrc =
5135                     getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5136                 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
5137                     tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y,
5138                                       dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z),
5139                     tcu::Sampler::MODE_STENCIL);
5140                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
5141             }
5142         }
5143     }
5144     else
5145     {
5146         const tcu::ConstPixelBufferAccess srcSubRegion =
5147             tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
5148         const tcu::PixelBufferAccess dstSubRegion =
5149             tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
5150         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5151 
5152         if (filter != tcu::Sampler::NEAREST)
5153         {
5154             const tcu::PixelBufferAccess unclampedSubRegion =
5155                 tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z,
5156                                   dstExtent.x, dstExtent.y, dstExtent.z);
5157             scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
5158         }
5159     }
5160 }
5161 
generateExpectedResult(void)5162 void BlittingImages::generateExpectedResult(void)
5163 {
5164     const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ?
5165                                                 m_sourceCompressedTexture->getDecompressedAccess() :
5166                                                 m_sourceTextureLevel->getAccess();
5167     const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ?
5168                                                 m_destinationCompressedTexture->getDecompressedAccess() :
5169                                                 m_destinationTextureLevel->getAccess();
5170 
5171     m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(
5172         new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
5173     tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
5174 
5175     if (m_params.filter != VK_FILTER_NEAREST)
5176     {
5177         m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(
5178             new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
5179         tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
5180     }
5181 
5182     for (uint32_t i = 0; i < m_params.regions.size(); i++)
5183     {
5184         CopyRegion region = m_params.regions[i];
5185         copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
5186     }
5187 }
5188 
uploadCompressedImage(const VkImage & image,const ImageParms & parms)5189 void BlittingImages::uploadCompressedImage(const VkImage &image, const ImageParms &parms)
5190 {
5191     DE_ASSERT(m_sourceCompressedTexture);
5192 
5193     const InstanceInterface &vki        = m_context.getInstanceInterface();
5194     const DeviceInterface &vk           = m_context.getDeviceInterface();
5195     const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
5196     const VkDevice vkDevice             = m_device;
5197     Allocator &memAlloc                 = *m_allocator;
5198     Move<VkBuffer> buffer;
5199     const uint32_t bufferSize = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
5200     de::MovePtr<Allocation> bufferAlloc;
5201     const uint32_t arraySize = getArraySize(parms);
5202     const VkExtent3D imageExtent{
5203         parms.extent.width,
5204         (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
5205         (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
5206     };
5207 
5208     // Create source buffer
5209     {
5210         const VkBufferCreateInfo bufferParams{
5211             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
5212             DE_NULL,                              // const void* pNext;
5213             0u,                                   // VkBufferCreateFlags flags;
5214             bufferSize,                           // VkDeviceSize size;
5215             VK_BUFFER_USAGE_TRANSFER_SRC_BIT,     // VkBufferUsageFlags usage;
5216             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
5217             0u,                                   // uint32_t queueFamilyIndexCount;
5218             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
5219         };
5220 
5221         buffer      = createBuffer(vk, vkDevice, &bufferParams);
5222         bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc,
5223                                      m_params.allocationKind);
5224         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
5225     }
5226 
5227     // Barriers for copying buffer to image
5228     const VkBufferMemoryBarrier preBufferBarrier{
5229         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
5230         DE_NULL,                                 // const void* pNext;
5231         VK_ACCESS_HOST_WRITE_BIT,                // VkAccessFlags srcAccessMask;
5232         VK_ACCESS_TRANSFER_READ_BIT,             // VkAccessFlags dstAccessMask;
5233         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t srcQueueFamilyIndex;
5234         VK_QUEUE_FAMILY_IGNORED,                 // uint32_t dstQueueFamilyIndex;
5235         *buffer,                                 // VkBuffer buffer;
5236         0u,                                      // VkDeviceSize offset;
5237         bufferSize                               // VkDeviceSize size;
5238     };
5239 
5240     const VkImageMemoryBarrier preImageBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5241                                                DE_NULL,                                // const void* pNext;
5242                                                0u,                                     // VkAccessFlags srcAccessMask;
5243                                                VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
5244                                                VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout oldLayout;
5245                                                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
5246                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5247                                                VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5248                                                image,                                  // VkImage image;
5249                                                {
5250                                                    // VkImageSubresourceRange subresourceRange;
5251                                                    VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5252                                                    0u,                        // uint32_t baseMipLevel;
5253                                                    1u,                        // uint32_t mipLevels;
5254                                                    0u,                        // uint32_t baseArraySlice;
5255                                                    arraySize,                 // uint32_t arraySize;
5256                                                }};
5257 
5258     const VkImageMemoryBarrier postImageBarrier{VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5259                                                 DE_NULL,                                // const void* pNext;
5260                                                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
5261                                                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
5262                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
5263                                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
5264                                                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5265                                                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5266                                                 image,                                  // VkImage image;
5267                                                 {
5268                                                     // VkImageSubresourceRange subresourceRange;
5269                                                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5270                                                     0u,                        // uint32_t baseMipLevel;
5271                                                     1u,                        // uint32_t mipLevels;
5272                                                     0u,                        // uint32_t baseArraySlice;
5273                                                     arraySize,                 // uint32_t arraySize;
5274                                                 }};
5275 
5276     const VkExtent3D copyExtent{imageExtent.width, imageExtent.height, imageExtent.depth};
5277 
5278     VkBufferImageCopy copyRegion{
5279         0u,                // VkDeviceSize bufferOffset;
5280         copyExtent.width,  // uint32_t bufferRowLength;
5281         copyExtent.height, // uint32_t bufferImageHeight;
5282         {
5283             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
5284             0u,                        // uint32_t mipLevel;
5285             0u,                        // uint32_t baseArrayLayer;
5286             arraySize,                 // uint32_t layerCount;
5287         },                             // VkImageSubresourceLayers imageSubresource;
5288         {0, 0, 0},                     // VkOffset3D imageOffset;
5289         copyExtent                     // VkExtent3D imageExtent;
5290     };
5291 
5292     // Write buffer data
5293     deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
5294     flushAlloc(vk, vkDevice, *bufferAlloc);
5295 
5296     // Copy buffer to image
5297     beginCommandBuffer(vk, *m_universalCmdBuffer);
5298     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5299                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &preBufferBarrier, 1,
5300                           &preImageBarrier);
5301     vk.cmdCopyBufferToImage(*m_universalCmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u,
5302                             &copyRegion);
5303     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5304                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5305                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5306     endCommandBuffer(vk, *m_universalCmdBuffer);
5307 
5308     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
5309     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
5310 }
5311 
5312 class BlitImageTestCase : public vkt::TestCase
5313 {
5314 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)5315     BlitImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
5316         : vkt::TestCase(testCtx, name)
5317         , m_params(params)
5318     {
5319     }
5320 
createInstance(Context & context) const5321     virtual TestInstance *createInstance(Context &context) const
5322     {
5323         return new BlittingImages(context, m_params);
5324     }
5325 
checkSupport(Context & context) const5326     virtual void checkSupport(Context &context) const
5327     {
5328 
5329 #ifndef CTS_USES_VULKANSC
5330         if (m_params.src.image.format == VK_FORMAT_A8_UNORM_KHR ||
5331             m_params.dst.image.format == VK_FORMAT_A8_UNORM_KHR ||
5332             m_params.src.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR ||
5333             m_params.dst.image.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
5334             context.requireDeviceFunctionality("VK_KHR_maintenance5");
5335 #endif // CTS_USES_VULKANSC
5336 
5337         VkImageFormatProperties properties;
5338         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
5339                 context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
5340                 m_params.src.image.tiling, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
5341                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5342         {
5343             TCU_THROW(NotSupportedError, "Source format not supported");
5344         }
5345         if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
5346                 context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
5347                 m_params.dst.image.tiling, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
5348                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5349         {
5350             TCU_THROW(NotSupportedError, "Destination format not supported");
5351         }
5352 
5353         checkExtensionSupport(context, m_params.extensionFlags);
5354 
5355         VkFormatProperties srcFormatProperties;
5356         context.getInstanceInterface().getPhysicalDeviceFormatProperties(
5357             context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
5358         VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ?
5359                                                      srcFormatProperties.linearTilingFeatures :
5360                                                      srcFormatProperties.optimalTilingFeatures;
5361         if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5362         {
5363             TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5364         }
5365 
5366         VkFormatProperties dstFormatProperties;
5367         context.getInstanceInterface().getPhysicalDeviceFormatProperties(
5368             context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
5369         VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ?
5370                                                      dstFormatProperties.linearTilingFeatures :
5371                                                      dstFormatProperties.optimalTilingFeatures;
5372         if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5373         {
5374             TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5375         }
5376 
5377         if (m_params.filter == VK_FILTER_LINEAR &&
5378             !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5379         {
5380             TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5381         }
5382 
5383         if (m_params.filter == VK_FILTER_CUBIC_EXT)
5384         {
5385             context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5386 
5387             if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5388             {
5389                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5390             }
5391         }
5392 
5393         checkExtensionSupport(context, m_params.extensionFlags);
5394     }
5395 
5396 private:
5397     TestParams m_params;
5398 };
5399 
5400 class BlittingMipmaps : public CopiesAndBlittingTestInstance
5401 {
5402 public:
5403     BlittingMipmaps(Context &context, TestParams params);
5404     virtual tcu::TestStatus iterate(void);
5405 
5406 protected:
5407     virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
5408     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
5409                                           CopyRegion region, uint32_t mipLevel = 0u);
5410     virtual void generateExpectedResult(void);
5411 
5412 private:
5413     bool checkNonNearestFilteredResult(void);
5414     bool checkNearestFilteredResult(void);
5415 
5416     Move<VkImage> m_source;
5417     de::MovePtr<Allocation> m_sourceImageAlloc;
5418     Move<VkImage> m_destination;
5419     de::MovePtr<Allocation> m_destinationImageAlloc;
5420     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
5421     Move<VkSemaphore> m_sparseSemaphore;
5422 
5423     de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16];
5424 };
5425 
BlittingMipmaps(Context & context,TestParams params)5426 BlittingMipmaps::BlittingMipmaps(Context &context, TestParams params) : CopiesAndBlittingTestInstance(context, params)
5427 {
5428     const InstanceInterface &vki        = context.getInstanceInterface();
5429     const DeviceInterface &vk           = context.getDeviceInterface();
5430     const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
5431     const VkDevice vkDevice             = m_device;
5432     Allocator &memAlloc                 = context.getDefaultAllocator();
5433 
5434     // Create source image
5435     {
5436         VkImageCreateInfo sourceImageParams = {
5437             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
5438             DE_NULL,                                                           // const void* pNext;
5439             getCreateFlags(m_params.src.image),                                // VkImageCreateFlags flags;
5440             m_params.src.image.imageType,                                      // VkImageType imageType;
5441             m_params.src.image.format,                                         // VkFormat format;
5442             getExtent3D(m_params.src.image),                                   // VkExtent3D extent;
5443             1u,                                                                // uint32_t mipLevels;
5444             getArraySize(m_params.src.image),                                  // uint32_t arraySize;
5445             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
5446             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
5447             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5448             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
5449             0u,                                                                // uint32_t queueFamilyIndexCount;
5450             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
5451             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
5452         };
5453 
5454 #ifndef CTS_USES_VULKANSC
5455         if (!params.useSparseBinding)
5456         {
5457 #endif
5458             m_source           = createImage(vk, m_device, &sourceImageParams);
5459             m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_source, MemoryRequirement::Any,
5460                                                *m_allocator, m_params.allocationKind, 0u);
5461             VK_CHECK(vk.bindImageMemory(m_device, *m_source, m_sourceImageAlloc->getMemory(),
5462                                         m_sourceImageAlloc->getOffset()));
5463 #ifndef CTS_USES_VULKANSC
5464         }
5465         else
5466         {
5467             sourceImageParams.flags |=
5468                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
5469             vk::VkImageFormatProperties imageFormatProperties;
5470             if (vki.getPhysicalDeviceImageFormatProperties(vkPhysDevice, sourceImageParams.format,
5471                                                            sourceImageParams.imageType, sourceImageParams.tiling,
5472                                                            sourceImageParams.usage, sourceImageParams.flags,
5473                                                            &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
5474             {
5475                 TCU_THROW(NotSupportedError, "Image format not supported");
5476             }
5477             m_source = createImage(
5478                 vk, m_device,
5479                 &sourceImageParams); //de::MovePtr<SparseImage>(new SparseImage(vk, vk, vkPhysDevice, vki, sourceImageParams, m_queue, *m_allocator, mapVkFormat(sourceImageParams.format)));
5480             m_sparseSemaphore = createSemaphore(vk, m_device);
5481             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, sourceImageParams, m_sparseSemaphore.get(),
5482                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
5483                                        mapVkFormat(sourceImageParams.format), m_source.get());
5484         }
5485 #endif
5486     }
5487 
5488     // Create destination image
5489     {
5490         const VkImageCreateInfo destinationImageParams = {
5491             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
5492             DE_NULL,                                                           // const void* pNext;
5493             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
5494             m_params.dst.image.imageType,                                      // VkImageType imageType;
5495             m_params.dst.image.format,                                         // VkFormat format;
5496             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
5497             m_params.mipLevels,                                                // uint32_t mipLevels;
5498             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
5499             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
5500             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
5501             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5502             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
5503             0u,                                                                // uint32_t queueFamilyIndexCount;
5504             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
5505             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
5506         };
5507 
5508         m_destination           = createImage(vk, vkDevice, &destinationImageParams);
5509         m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any,
5510                                                 memAlloc, m_params.allocationKind, 0u);
5511         VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(),
5512                                     m_destinationImageAlloc->getOffset()));
5513     }
5514 }
5515 
iterate(void)5516 tcu::TestStatus BlittingMipmaps::iterate(void)
5517 {
5518     const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
5519     const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
5520     m_sourceTextureLevel                  = de::MovePtr<tcu::TextureLevel>(
5521         new tcu::TextureLevel(srcTcuFormat, m_params.src.image.extent.width, m_params.src.image.extent.height,
5522                                                m_params.src.image.extent.depth));
5523     generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
5524                    m_params.src.image.extent.depth, m_params.src.image.fillMode);
5525     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
5526         new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
5527                               (int)m_params.dst.image.extent.depth));
5528     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
5529                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
5530     generateExpectedResult();
5531 
5532     uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
5533 
5534     uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
5535 
5536     const DeviceInterface &vk = m_context.getDeviceInterface();
5537     const VkDevice vkDevice   = m_device;
5538 
5539     std::vector<VkImageBlit> regions;
5540     std::vector<VkImageBlit2KHR> regions2KHR;
5541     for (uint32_t i = 0; i < m_params.regions.size(); i++)
5542     {
5543         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5544         {
5545             regions.push_back(m_params.regions[i].imageBlit);
5546         }
5547         else
5548         {
5549             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5550             regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
5551         }
5552     }
5553 
5554     // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
5555     if (!m_params.singleCommand)
5556         uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
5557 
5558     beginCommandBuffer(vk, *m_universalCmdBuffer);
5559 
5560     // Blit all mip levels with a single blit command
5561     if (m_params.singleCommand)
5562     {
5563         {
5564             // Source image layout
5565             const VkImageMemoryBarrier srcImageBarrier = {
5566                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5567                 DE_NULL,                                // const void* pNext;
5568                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
5569                 VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
5570                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
5571                 m_params.src.image.operationLayout,     // VkImageLayout newLayout;
5572                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5573                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5574                 m_source.get(),                         // VkImage image;
5575                 {
5576                     // VkImageSubresourceRange subresourceRange;
5577                     getAspectFlags(srcTcuFormat),    // VkImageAspectFlags   aspectMask;
5578                     0u,                              // uint32_t baseMipLevel;
5579                     1u,                              // uint32_t mipLevels;
5580                     0u,                              // uint32_t baseArraySlice;
5581                     getArraySize(m_params.src.image) // uint32_t arraySize;
5582                 }};
5583 
5584             // Destination image layout
5585             const VkImageMemoryBarrier dstImageBarrier = {
5586                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5587                 DE_NULL,                                // const void* pNext;
5588                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
5589                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
5590                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
5591                 m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
5592                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5593                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5594                 m_destination.get(),                    // VkImage image;
5595                 {
5596                     // VkImageSubresourceRange subresourceRange;
5597                     getAspectFlags(dstTcuFormat),    // VkImageAspectFlags   aspectMask;
5598                     0u,                              // uint32_t baseMipLevel;
5599                     m_params.mipLevels,              // uint32_t mipLevels;
5600                     0u,                              // uint32_t baseArraySlice;
5601                     getArraySize(m_params.dst.image) // uint32_t arraySize;
5602                 }};
5603 
5604             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5605                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5606                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &srcImageBarrier);
5607             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5608                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5609                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &dstImageBarrier);
5610 
5611             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5612             {
5613                 vk.cmdBlitImage(*m_universalCmdBuffer, m_source.get(), m_params.src.image.operationLayout,
5614                                 m_destination.get(), m_params.dst.image.operationLayout,
5615                                 (uint32_t)m_params.regions.size(), &regions[0], m_params.filter);
5616             }
5617             else
5618             {
5619                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5620                 const VkBlitImageInfo2KHR BlitImageInfo2KHR = {
5621                     VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
5622                     DE_NULL,                                 // const void* pNext;
5623                     m_source.get(),                          // VkImage srcImage;
5624                     m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
5625                     m_destination.get(),                     // VkImage dstImage;
5626                     m_params.dst.image.operationLayout,      // VkImageLayout dstImageLayout;
5627                     (uint32_t)m_params.regions.size(),       // uint32_t regionCount;
5628                     &regions2KHR[0],                         // const VkImageBlit2KHR* pRegions;
5629                     m_params.filter                          // VkFilter filter;
5630                 };
5631                 vk.cmdBlitImage2(*m_universalCmdBuffer, &BlitImageInfo2KHR);
5632             }
5633         }
5634     }
5635     // Blit mip levels with multiple blit commands
5636     else
5637     {
5638         // Prepare all mip levels for reading
5639         {
5640             for (uint32_t barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
5641             {
5642                 VkImageMemoryBarrier preImageBarrier = {
5643                     VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5644                     DE_NULL,                                // const void* pNext;
5645                     VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
5646                     VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
5647                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
5648                     m_params.src.image.operationLayout,     // VkImageLayout newLayout;
5649                     VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5650                     VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5651                     m_destination.get(),                    // VkImage image;
5652                     {
5653                         // VkImageSubresourceRange subresourceRange;
5654                         getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
5655                         0u,                              // uint32_t baseMipLevel;
5656                         VK_REMAINING_MIP_LEVELS,         // uint32_t mipLevels;
5657                         0u,                              // uint32_t baseArraySlice;
5658                         getArraySize(m_params.src.image) // uint32_t arraySize;
5659                     }};
5660 
5661                 if (getArraySize(m_params.src.image) == 1)
5662                 {
5663                     DE_ASSERT(barrierno < m_params.mipLevels);
5664                     preImageBarrier.subresourceRange.baseMipLevel = barrierno;
5665                     preImageBarrier.subresourceRange.levelCount =
5666                         (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
5667                 }
5668                 else
5669                 {
5670                     preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
5671                     preImageBarrier.subresourceRange.layerCount =
5672                         (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
5673                 }
5674                 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
5675                                       VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
5676                                       (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
5677                                       &preImageBarrier);
5678             }
5679         }
5680 
5681         for (uint32_t regionNdx = 0u; regionNdx < (uint32_t)m_params.regions.size(); regionNdx++)
5682         {
5683             const uint32_t mipLevel = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
5684 
5685             // Prepare single mip level for writing
5686             const VkImageMemoryBarrier preImageBarrier = {
5687                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5688                 DE_NULL,                                // const void* pNext;
5689                 VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags srcAccessMask;
5690                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
5691                 m_params.src.image.operationLayout,     // VkImageLayout oldLayout;
5692                 m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
5693                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5694                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5695                 m_destination.get(),                    // VkImage image;
5696                 {
5697                     // VkImageSubresourceRange subresourceRange;
5698                     getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
5699                     mipLevel,                        // uint32_t baseMipLevel;
5700                     1u,                              // uint32_t mipLevels;
5701                     0u,                              // uint32_t baseArraySlice;
5702                     getArraySize(m_params.dst.image) // uint32_t arraySize;
5703                 }};
5704 
5705             // Prepare single mip level for reading
5706             const VkImageMemoryBarrier postImageBarrier = {
5707                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5708                 DE_NULL,                                // const void* pNext;
5709                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
5710                 VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
5711                 m_params.dst.image.operationLayout,     // VkImageLayout oldLayout;
5712                 m_params.src.image.operationLayout,     // VkImageLayout newLayout;
5713                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5714                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5715                 m_destination.get(),                    // VkImage image;
5716                 {
5717                     // VkImageSubresourceRange subresourceRange;
5718                     getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
5719                     mipLevel,                        // uint32_t baseMipLevel;
5720                     1u,                              // uint32_t mipLevels;
5721                     0u,                              // uint32_t baseArraySlice;
5722                     getArraySize(m_params.src.image) // uint32_t arraySize;
5723                 }};
5724 
5725             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5726                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5727                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &preImageBarrier);
5728 
5729             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
5730             {
5731                 vk.cmdBlitImage(*m_universalCmdBuffer, m_destination.get(), m_params.src.image.operationLayout,
5732                                 m_destination.get(), m_params.dst.image.operationLayout, 1u, &regions[regionNdx],
5733                                 m_params.filter);
5734             }
5735             else
5736             {
5737                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
5738                 const VkBlitImageInfo2KHR BlitImageInfo2KHR = {
5739                     VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
5740                     DE_NULL,                                 // const void* pNext;
5741                     m_destination.get(),                     // VkImage srcImage;
5742                     m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
5743                     m_destination.get(),                     // VkImage dstImage;
5744                     m_params.dst.image.operationLayout,      // VkImageLayout dstImageLayout;
5745                     1u,                                      // uint32_t regionCount;
5746                     &regions2KHR[regionNdx],                 // const VkImageBlit2KHR* pRegions;
5747                     m_params.filter                          // VkFilter filter;
5748                 };
5749                 vk.cmdBlitImage2(*m_universalCmdBuffer, &BlitImageInfo2KHR);
5750             }
5751 
5752             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5753                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5754                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5755         }
5756 
5757         // Prepare all mip levels for writing
5758         {
5759             const VkImageMemoryBarrier postImageBarrier = {
5760                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5761                 DE_NULL,                                // const void* pNext;
5762                 VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags srcAccessMask;
5763                 VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
5764                 m_params.src.image.operationLayout,     // VkImageLayout oldLayout;
5765                 m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
5766                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
5767                 VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
5768                 m_destination.get(),                    // VkImage image;
5769                 {
5770                     // VkImageSubresourceRange subresourceRange;
5771                     getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
5772                     0u,                              // uint32_t baseMipLevel;
5773                     VK_REMAINING_MIP_LEVELS,         // uint32_t mipLevels;
5774                     0u,                              // uint32_t baseArraySlice;
5775                     getArraySize(m_params.dst.image) // uint32_t arraySize;
5776                 }};
5777 
5778             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
5779                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
5780                                   (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
5781         }
5782     }
5783 
5784     endCommandBuffer(vk, *m_universalCmdBuffer);
5785     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
5786     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
5787 
5788     return checkTestResult();
5789 }
5790 
checkNonNearestFilteredResult(void)5791 bool BlittingMipmaps::checkNonNearestFilteredResult(void)
5792 {
5793     tcu::TestLog &log(m_context.getTestContext().getLog());
5794     bool allLevelsOk = true;
5795 
5796     for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5797     {
5798         // Update reference results with previous results that have been verified.
5799         // This needs to be done such that accumulated errors don't exceed the fixed threshold.
5800         for (uint32_t i = 0; i < m_params.regions.size(); i++)
5801         {
5802             const CopyRegion region    = m_params.regions[i];
5803             const uint32_t srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5804             const uint32_t dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5805             de::MovePtr<tcu::TextureLevel> prevResultLevel;
5806             tcu::ConstPixelBufferAccess src;
5807             if (srcMipLevel < mipLevelNdx)
5808             {
5809                 // Generate expected result from rendered result that was previously verified
5810                 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
5811                 src             = prevResultLevel->getAccess();
5812             }
5813             else
5814             {
5815                 // Previous reference mipmaps might have changed, so recompute expected result
5816                 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5817             }
5818             copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5819         }
5820 
5821         de::MovePtr<tcu::TextureLevel> resultLevel      = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5822         const tcu::ConstPixelBufferAccess &resultAccess = resultLevel->getAccess();
5823 
5824         const tcu::Sampler::DepthStencilMode mode =
5825             tcu::hasDepthComponent(resultAccess.getFormat().order)   ? tcu::Sampler::MODE_DEPTH :
5826             tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5827                                                                        tcu::Sampler::MODE_LAST;
5828         const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5829                                                        getEffectiveDepthStencilAccess(resultAccess, mode) :
5830                                                    tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5831                                                        getEffectiveDepthStencilAccess(resultAccess, mode) :
5832                                                        resultAccess;
5833         const tcu::ConstPixelBufferAccess clampedLevel =
5834             tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5835                 getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5836             tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5837                 getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5838                 m_expectedTextureLevel[mipLevelNdx]->getAccess();
5839         const tcu::ConstPixelBufferAccess unclampedLevel =
5840             tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5841                 getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5842             tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5843                 getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5844                 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5845         const tcu::TextureFormat srcFormat =
5846             tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5847                 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5848             tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5849                 tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5850                 mapVkFormat(m_params.src.image.format);
5851 
5852         const tcu::TextureFormat dstFormat = result.getFormat();
5853         bool singleLevelOk                 = false;
5854         std::vector<CopyRegion> mipLevelRegions;
5855 
5856         for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5857             if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5858                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5859 
5860         log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5861 
5862         if (isFloatFormat(dstFormat))
5863         {
5864             const bool srcIsSRGB       = tcu::isSRGB(srcFormat);
5865             const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5866             const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
5867             const tcu::Vec4 threshold =
5868                 (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
5869 
5870             singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result,
5871                                                        threshold, tcu::COMPARE_LOG_RESULT);
5872             log << tcu::TestLog::EndSection;
5873 
5874             if (!singleLevelOk)
5875             {
5876                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5877                 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result,
5878                                                            threshold, tcu::COMPARE_LOG_RESULT);
5879                 log << tcu::TestLog::EndSection;
5880             }
5881         }
5882         else
5883         {
5884             tcu::UVec4 threshold;
5885             // Calculate threshold depending on channel width of destination format.
5886             const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
5887             const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5888             for (uint32_t i = 0; i < 4; ++i)
5889             {
5890                 DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5891                 DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5892                 uint64_t threshold64 =
5893                     1 + de::max(((UINT64_C(1) << dstBitDepth[i]) - 1) /
5894                                     de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)),
5895                                 UINT64_C(1));
5896                 DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
5897                 threshold[i] = static_cast<uint32_t>(threshold64);
5898             }
5899 
5900             singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result,
5901                                                      threshold, tcu::COMPARE_LOG_RESULT);
5902             log << tcu::TestLog::EndSection;
5903 
5904             if (!singleLevelOk)
5905             {
5906                 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5907                 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result,
5908                                                          threshold, tcu::COMPARE_LOG_RESULT);
5909                 log << tcu::TestLog::EndSection;
5910             }
5911         }
5912         allLevelsOk &= singleLevelOk;
5913     }
5914 
5915     return allLevelsOk;
5916 }
5917 
checkNearestFilteredResult(void)5918 bool BlittingMipmaps::checkNearestFilteredResult(void)
5919 {
5920     bool allLevelsOk = true;
5921     tcu::TestLog &log(m_context.getTestContext().getLog());
5922 
5923     for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5924     {
5925         de::MovePtr<tcu::TextureLevel> resultLevel      = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5926         const tcu::ConstPixelBufferAccess &resultAccess = resultLevel->getAccess();
5927 
5928         const tcu::Sampler::DepthStencilMode mode =
5929             tcu::hasDepthComponent(resultAccess.getFormat().order)   ? tcu::Sampler::MODE_DEPTH :
5930             tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5931                                                                        tcu::Sampler::MODE_LAST;
5932         const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5933                                                        getEffectiveDepthStencilAccess(resultAccess, mode) :
5934                                                    tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5935                                                        getEffectiveDepthStencilAccess(resultAccess, mode) :
5936                                                        resultAccess;
5937         const tcu::ConstPixelBufferAccess source =
5938             (m_params.singleCommand || mipLevelNdx == 0) ? //  Read from source image
5939                 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5940                 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5941                 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5942                 tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5943                 m_sourceTextureLevel->getAccess()
5944                 //  Read from destination image
5945                 :
5946                 tcu::hasDepthComponent(resultAccess.getFormat().order) ?
5947                 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5948                 tcu::hasStencilComponent(resultAccess.getFormat().order) ?
5949                 tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5950                 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5951         const tcu::TextureFormat dstFormat             = result.getFormat();
5952         const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
5953         bool singleLevelOk                             = false;
5954         std::vector<CopyRegion> mipLevelRegions;
5955 
5956         for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5957             if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5958                 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5959 
5960         // Use the calculated regions instead of the original ones.
5961         TestParams newParams = m_params;
5962         newParams.regions    = mipLevelRegions;
5963 
5964         tcu::TextureLevel errorMaskStorage(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8),
5965                                            result.getWidth(), result.getHeight(), result.getDepth());
5966         tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
5967         tcu::Vec4 pixelBias(0.0f, 0.0f, 0.0f, 0.0f);
5968         tcu::Vec4 pixelScale(1.0f, 1.0f, 1.0f, 1.0f);
5969 
5970         tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5971 
5972         if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5973             dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5974         {
5975             singleLevelOk = intNearestBlitCompare(source, result, errorMask, newParams);
5976         }
5977         else
5978         {
5979             const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5980             const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5981 
5982             singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, newParams);
5983         }
5984 
5985         if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5986             tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5987 
5988         if (!singleLevelOk)
5989         {
5990             log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5991                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5992                 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5993                 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask) << tcu::TestLog::EndImageSet;
5994         }
5995         else
5996         {
5997             log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5998                 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias) << tcu::TestLog::EndImageSet;
5999         }
6000 
6001         allLevelsOk &= singleLevelOk;
6002     }
6003 
6004     return allLevelsOk;
6005 }
6006 
checkTestResult(tcu::ConstPixelBufferAccess result)6007 tcu::TestStatus BlittingMipmaps::checkTestResult(tcu::ConstPixelBufferAccess result)
6008 {
6009     DE_UNREF(result);
6010     DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR ||
6011               m_params.filter == VK_FILTER_CUBIC_EXT);
6012     const std::string failMessage("Result image is incorrect");
6013 
6014     if (m_params.filter != VK_FILTER_NEAREST)
6015     {
6016         if (!checkNonNearestFilteredResult())
6017             return tcu::TestStatus::fail(failMessage);
6018     }
6019     else // NEAREST filtering
6020     {
6021         if (!checkNearestFilteredResult())
6022             return tcu::TestStatus::fail(failMessage);
6023     }
6024 
6025     return tcu::TestStatus::pass("Pass");
6026 }
6027 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)6028 void BlittingMipmaps::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
6029                                                CopyRegion region, uint32_t mipLevel)
6030 {
6031     DE_ASSERT(src.getDepth() == dst.getDepth());
6032 
6033     const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0], region.imageBlit.srcOffsets[1],
6034                                                 region.imageBlit.dstOffsets[0], region.imageBlit.dstOffsets[1]);
6035 
6036     flipCoordinates(region, mirrorMode);
6037 
6038     const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
6039     const VkOffset3D srcExtent = {region.imageBlit.srcOffsets[1].x - srcOffset.x,
6040                                   region.imageBlit.srcOffsets[1].y - srcOffset.y,
6041                                   region.imageBlit.srcOffsets[1].z - srcOffset.z};
6042     const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
6043     const VkOffset3D dstExtent = {region.imageBlit.dstOffsets[1].x - dstOffset.x,
6044                                   region.imageBlit.dstOffsets[1].y - dstOffset.y,
6045                                   region.imageBlit.dstOffsets[1].z - dstOffset.z};
6046 
6047     tcu::Sampler::FilterMode filter;
6048     switch (m_params.filter)
6049     {
6050     case VK_FILTER_LINEAR:
6051         filter = tcu::Sampler::LINEAR;
6052         break;
6053     case VK_FILTER_CUBIC_EXT:
6054         filter = tcu::Sampler::CUBIC;
6055         break;
6056     case VK_FILTER_NEAREST:
6057     default:
6058         filter = tcu::Sampler::NEAREST;
6059         break;
6060     }
6061 
6062     if (tcu::isCombinedDepthStencilType(src.getFormat().type))
6063     {
6064         DE_ASSERT(src.getFormat() == dst.getFormat());
6065         // Scale depth.
6066         if (tcu::hasDepthComponent(src.getFormat().order))
6067         {
6068             const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
6069                 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
6070             const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
6071                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
6072             tcu::scale(dstSubRegion, srcSubRegion, filter);
6073 
6074             if (filter != tcu::Sampler::NEAREST)
6075             {
6076                 const tcu::ConstPixelBufferAccess depthSrc =
6077                     getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
6078                 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
6079                     tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y,
6080                                       dstExtent.x, dstExtent.y),
6081                     tcu::Sampler::MODE_DEPTH);
6082                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
6083             }
6084         }
6085 
6086         // Scale stencil.
6087         if (tcu::hasStencilComponent(src.getFormat().order))
6088         {
6089             const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(
6090                 tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
6091             const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(
6092                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
6093             blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
6094 
6095             if (filter != tcu::Sampler::NEAREST)
6096             {
6097                 const tcu::ConstPixelBufferAccess stencilSrc =
6098                     getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
6099                 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(
6100                     tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y,
6101                                       dstExtent.x, dstExtent.y),
6102                     tcu::Sampler::MODE_STENCIL);
6103                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
6104             }
6105         }
6106     }
6107     else
6108     {
6109         for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
6110         {
6111             const tcu::ConstPixelBufferAccess srcSubRegion =
6112                 tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
6113             const tcu::PixelBufferAccess dstSubRegion =
6114                 tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
6115             blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
6116 
6117             if (filter != tcu::Sampler::NEAREST)
6118             {
6119                 const tcu::PixelBufferAccess unclampedSubRegion =
6120                     tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y,
6121                                       layerNdx, dstExtent.x, dstExtent.y, 1);
6122                 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
6123             }
6124         }
6125     }
6126 }
6127 
generateExpectedResult(void)6128 void BlittingMipmaps::generateExpectedResult(void)
6129 {
6130     const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
6131     const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
6132 
6133     for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
6134         m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(
6135             dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
6136 
6137     tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
6138 
6139     if (m_params.filter != VK_FILTER_NEAREST)
6140     {
6141         for (uint32_t mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
6142             m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(
6143                 dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
6144 
6145         tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
6146     }
6147 
6148     for (uint32_t i = 0; i < m_params.regions.size(); i++)
6149     {
6150         CopyRegion region = m_params.regions[i];
6151         copyRegionToTextureLevel(
6152             m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(),
6153             m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region,
6154             m_params.regions[i].imageBlit.dstSubresource.mipLevel);
6155     }
6156 }
6157 
6158 class BlitMipmapTestCase : public vkt::TestCase
6159 {
6160 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params)6161     BlitMipmapTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params)
6162         : vkt::TestCase(testCtx, name)
6163         , m_params(params)
6164     {
6165     }
6166 
createInstance(Context & context) const6167     virtual TestInstance *createInstance(Context &context) const
6168     {
6169         return new BlittingMipmaps(context, m_params);
6170     }
6171 
checkSupport(Context & context) const6172     virtual void checkSupport(Context &context) const
6173     {
6174         const InstanceInterface &vki        = context.getInstanceInterface();
6175         const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
6176         {
6177             VkImageFormatProperties properties;
6178             if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
6179                     context.getPhysicalDevice(), m_params.src.image.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
6180                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
6181             {
6182                 TCU_THROW(NotSupportedError, "Format not supported");
6183             }
6184             else if ((m_params.src.image.extent.width > properties.maxExtent.width) ||
6185                      (m_params.src.image.extent.height > properties.maxExtent.height) ||
6186                      (m_params.src.image.extent.depth > properties.maxArrayLayers))
6187             {
6188                 TCU_THROW(NotSupportedError, "Image size not supported");
6189             }
6190         }
6191 
6192         {
6193             VkImageFormatProperties properties;
6194             if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
6195                     context.getPhysicalDevice(), m_params.dst.image.format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
6196                     VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
6197             {
6198                 TCU_THROW(NotSupportedError, "Format not supported");
6199             }
6200             else if ((m_params.dst.image.extent.width > properties.maxExtent.width) ||
6201                      (m_params.dst.image.extent.height > properties.maxExtent.height) ||
6202                      (m_params.dst.image.extent.depth > properties.maxArrayLayers))
6203             {
6204                 TCU_THROW(NotSupportedError, "Image size not supported");
6205             }
6206             else if (m_params.mipLevels > properties.maxMipLevels)
6207             {
6208                 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
6209             }
6210 
6211             checkExtensionSupport(context, m_params.extensionFlags);
6212         }
6213 
6214         const VkFormatProperties srcFormatProperties =
6215             getPhysicalDeviceFormatProperties(vki, vkPhysDevice, m_params.src.image.format);
6216         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
6217         {
6218             TCU_THROW(NotSupportedError, "Format feature blit source not supported");
6219         }
6220 
6221         const VkFormatProperties dstFormatProperties =
6222             getPhysicalDeviceFormatProperties(vki, vkPhysDevice, m_params.dst.image.format);
6223         if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
6224         {
6225             TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
6226         }
6227 
6228         if (m_params.filter == VK_FILTER_LINEAR &&
6229             !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
6230             TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
6231 
6232         if (m_params.filter == VK_FILTER_CUBIC_EXT)
6233         {
6234             context.requireDeviceFunctionality("VK_EXT_filter_cubic");
6235 
6236             if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
6237             {
6238                 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
6239             }
6240         }
6241     }
6242 
6243 private:
6244     TestParams m_params;
6245 };
6246 
6247 // Resolve image to image.
6248 
6249 enum ResolveImageToImageOptions
6250 {
6251     NO_OPTIONAL_OPERATION = 0,
6252     COPY_MS_IMAGE_TO_MS_IMAGE,
6253     COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
6254     COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
6255     COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
6256     COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
6257     COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
6258     COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER
6259 };
6260 
6261 class ResolveImageToImage : public CopiesAndBlittingTestInstance
6262 {
6263 public:
6264     ResolveImageToImage(Context &context, TestParams params, ResolveImageToImageOptions options);
6265     virtual tcu::TestStatus iterate(void);
6266 
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)6267     static inline bool shouldVerifyIntermediateResults(ResolveImageToImageOptions option)
6268     {
6269         return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE ||
6270                option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE ||
6271                option == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6272     }
6273 
6274 protected:
6275     virtual tcu::TestStatus checkTestResult(tcu::ConstPixelBufferAccess result);
6276     void copyMSImageToMSImage(uint32_t copyArraySize);
6277     tcu::TestStatus checkIntermediateCopy(void);
6278 
6279 private:
6280     de::MovePtr<vk::Allocator> m_alternativeAllocator;
6281     Move<VkImage> m_multisampledImage;
6282     de::MovePtr<Allocation> m_multisampledImageAlloc;
6283 
6284     Move<VkImage> m_destination;
6285     de::MovePtr<Allocation> m_destinationImageAlloc;
6286     std::vector<de::SharedPtr<Allocation>> m_sparseAllocations;
6287     Move<VkSemaphore> m_sparseSemaphore;
6288 
6289     Move<VkImage> m_multisampledCopyImage;
6290     de::MovePtr<Allocation> m_multisampledCopyImageAlloc;
6291     Move<VkImage> m_multisampledCopyNoCabImage;
6292     de::MovePtr<Allocation> m_multisampledCopyImageNoCabAlloc;
6293 
6294     const TestParams m_params;
6295     const ResolveImageToImageOptions m_options;
6296 
6297     virtual void copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
6298                                           CopyRegion region, uint32_t mipLevel = 0u);
6299 };
6300 
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)6301 ResolveImageToImage::ResolveImageToImage(Context &context, TestParams params, const ResolveImageToImageOptions options)
6302     : CopiesAndBlittingTestInstance(context, params)
6303     , m_params(params)
6304     , m_options(options)
6305 {
6306     const InstanceInterface &vki = m_context.getInstanceInterface();
6307     const DeviceInterface &vk    = m_context.getDeviceInterface();
6308 
6309     VkQueue queue                               = VK_NULL_HANDLE;
6310     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
6311     VkCommandPool commandPool                   = VK_NULL_HANDLE;
6312     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
6313 
6314     Allocator &memAlloc                           = *m_allocator;
6315     const VkPhysicalDevice vkPhysDevice           = m_context.getPhysicalDevice();
6316     const VkDevice vkDevice                       = m_device;
6317     const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
6318                                                      VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
6319     Move<VkRenderPass> renderPass;
6320 
6321     Move<VkShaderModule> vertexShaderModule =
6322         createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
6323     Move<VkShaderModule> fragmentShaderModule =
6324         createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
6325     std::vector<tcu::Vec4> vertices;
6326 
6327     Move<VkBuffer> vertexBuffer;
6328     de::MovePtr<Allocation> vertexBufferAlloc;
6329 
6330     Move<VkPipelineLayout> pipelineLayout;
6331     Move<VkPipeline> graphicsPipeline;
6332 
6333     const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
6334 
6335     // Create color image.
6336     {
6337         VkImageCreateInfo colorImageParams = {
6338             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6339             DE_NULL,                             // const void* pNext;
6340             getCreateFlags(m_params.src.image),  // VkImageCreateFlags flags;
6341             m_params.src.image.imageType,        // VkImageType imageType;
6342             m_params.src.image.format,           // VkFormat format;
6343             getExtent3D(m_params.src.image),     // VkExtent3D extent;
6344             1u,                                  // uint32_t mipLevels;
6345             getArraySize(m_params.src.image),    // uint32_t arrayLayers;
6346             rasterizationSamples,                // VkSampleCountFlagBits samples;
6347             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
6348             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT  // VkImageUsageFlags usage;
6349                 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
6350                 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
6351             VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6352             0u,                        // uint32_t queueFamilyIndexCount;
6353             (const uint32_t *)DE_NULL, // const uint32_t* pQueueFamilyIndices;
6354             VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6355         };
6356 
6357         m_multisampledImage      = createImage(vk, vkDevice, &colorImageParams);
6358         VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
6359 
6360         // Allocate and bind color image memory.
6361         uint32_t offset          = m_params.imageOffset ? static_cast<uint32_t>(req.alignment) : 0u;
6362         m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage,
6363                                                  MemoryRequirement::Any, memAlloc, m_params.allocationKind, offset);
6364 
6365         VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
6366 
6367         switch (m_options)
6368         {
6369         case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6370         case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6371         case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6372         case COPY_MS_IMAGE_TO_MS_IMAGE:
6373         {
6374             colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
6375                                      VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6376             m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
6377             // Allocate and bind color image memory.
6378             m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6379                                                          MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6380             VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6381                                         m_multisampledCopyImageAlloc->getOffset()));
6382             break;
6383         }
6384         case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6385         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6386         {
6387             colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
6388                                      VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6389             colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
6390             m_multisampledCopyImage      = createImage(vk, vkDevice, &colorImageParams);
6391             // Allocate and bind color image memory.
6392             m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6393                                                          MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6394             VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6395                                         m_multisampledCopyImageAlloc->getOffset()));
6396             break;
6397         }
6398         case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6399         {
6400             colorImageParams.usage =
6401                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
6402             colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
6403             m_multisampledCopyImage      = createImage(vk, vkDevice, &colorImageParams);
6404             m_multisampledCopyNoCabImage = createImage(vk, vkDevice, &colorImageParams);
6405             // Allocate and bind color image memory.
6406             m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage,
6407                                                          MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
6408             VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(),
6409                                         m_multisampledCopyImageAlloc->getOffset()));
6410             m_multisampledCopyImageNoCabAlloc =
6411                 allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any,
6412                               memAlloc, m_params.allocationKind, 0u);
6413             VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage,
6414                                         m_multisampledCopyImageNoCabAlloc->getMemory(),
6415                                         m_multisampledCopyImageNoCabAlloc->getOffset()));
6416             break;
6417         }
6418 
6419         default:
6420             break;
6421         }
6422     }
6423 
6424     // Create destination image.
6425     {
6426         VkImageCreateInfo destinationImageParams = {
6427             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                               // VkStructureType sType;
6428             DE_NULL,                                                           // const void* pNext;
6429             getCreateFlags(m_params.dst.image),                                // VkImageCreateFlags flags;
6430             m_params.dst.image.imageType,                                      // VkImageType imageType;
6431             m_params.dst.image.format,                                         // VkFormat format;
6432             getExtent3D(m_params.dst.image),                                   // VkExtent3D extent;
6433             1u,                                                                // uint32_t mipLevels;
6434             getArraySize(m_params.dst.image),                                  // uint32_t arraySize;
6435             VK_SAMPLE_COUNT_1_BIT,                                             // uint32_t samples;
6436             VK_IMAGE_TILING_OPTIMAL,                                           // VkImageTiling tiling;
6437             VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
6438             VK_SHARING_MODE_EXCLUSIVE,                                         // VkSharingMode sharingMode;
6439             0u,                                                                // uint32_t queueFamilyIndexCount;
6440             (const uint32_t *)DE_NULL,                                         // const uint32_t* pQueueFamilyIndices;
6441             VK_IMAGE_LAYOUT_UNDEFINED,                                         // VkImageLayout initialLayout;
6442         };
6443 
6444 #ifndef CTS_USES_VULKANSC
6445         if (!params.useSparseBinding)
6446         {
6447 #endif
6448             m_destination           = createImage(vk, m_device, &destinationImageParams);
6449             m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, m_device, *m_destination,
6450                                                     MemoryRequirement::Any, *m_allocator, m_params.allocationKind, 0u);
6451             VK_CHECK(vk.bindImageMemory(m_device, *m_destination, m_destinationImageAlloc->getMemory(),
6452                                         m_destinationImageAlloc->getOffset()));
6453 #ifndef CTS_USES_VULKANSC
6454         }
6455         else
6456         {
6457             destinationImageParams.flags |=
6458                 (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
6459             vk::VkImageFormatProperties imageFormatProperties;
6460             if (vki.getPhysicalDeviceImageFormatProperties(
6461                     vkPhysDevice, destinationImageParams.format, destinationImageParams.imageType,
6462                     destinationImageParams.tiling, destinationImageParams.usage, destinationImageParams.flags,
6463                     &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
6464             {
6465                 TCU_THROW(NotSupportedError, "Image format not supported");
6466             }
6467             m_destination     = createImage(vk, m_device, &destinationImageParams);
6468             m_sparseSemaphore = createSemaphore(vk, m_device);
6469             allocateAndBindSparseImage(vk, m_device, vkPhysDevice, vki, destinationImageParams, m_sparseSemaphore.get(),
6470                                        context.getSparseQueue(), *m_allocator, m_sparseAllocations,
6471                                        mapVkFormat(destinationImageParams.format), m_destination.get());
6472         }
6473 #endif
6474     }
6475 
6476     // Barriers for image clearing.
6477     std::vector<VkImageMemoryBarrier> srcImageBarriers;
6478 
6479     const VkImageMemoryBarrier m_multisampledImageBarrier = {
6480         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6481         DE_NULL,                                // const void* pNext;
6482         0u,                                     // VkAccessFlags srcAccessMask;
6483         VK_ACCESS_MEMORY_WRITE_BIT,             // VkAccessFlags dstAccessMask;
6484         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout oldLayout;
6485         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
6486         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
6487         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
6488         m_multisampledImage.get(),              // VkImage image;
6489         {
6490             // VkImageSubresourceRange subresourceRange;
6491             VK_IMAGE_ASPECT_COLOR_BIT,       // VkImageAspectFlags aspectMask;
6492             0u,                              // uint32_t baseMipLevel;
6493             1u,                              // uint32_t mipLevels;
6494             0u,                              // uint32_t baseArraySlice;
6495             getArraySize(m_params.src.image) // uint32_t arraySize;
6496         }};
6497     const VkImageMemoryBarrier m_multisampledCopyImageBarrier = {
6498         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6499         DE_NULL,                                // const void* pNext;
6500         0u,                                     // VkAccessFlags srcAccessMask;
6501         VK_ACCESS_MEMORY_WRITE_BIT,             // VkAccessFlags dstAccessMask;
6502         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout oldLayout;
6503         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
6504         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
6505         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
6506         m_multisampledCopyImage.get(),          // VkImage image;
6507         {
6508             // VkImageSubresourceRange subresourceRange;
6509             VK_IMAGE_ASPECT_COLOR_BIT,       // VkImageAspectFlags aspectMask;
6510             0u,                              // uint32_t baseMipLevel;
6511             1u,                              // uint32_t mipLevels;
6512             0u,                              // uint32_t baseArraySlice;
6513             getArraySize(m_params.dst.image) // uint32_t arraySize;
6514         }};
6515     const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier = {
6516         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6517         DE_NULL,                                // const void* pNext;
6518         0u,                                     // VkAccessFlags srcAccessMask;
6519         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,   // VkAccessFlags dstAccessMask;
6520         VK_IMAGE_LAYOUT_UNDEFINED,              // VkImageLayout oldLayout;
6521         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout newLayout;
6522         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
6523         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
6524         m_multisampledCopyNoCabImage.get(),     // VkImage image;
6525         {
6526             // VkImageSubresourceRange subresourceRange;
6527             VK_IMAGE_ASPECT_COLOR_BIT,       // VkImageAspectFlags aspectMask;
6528             0u,                              // uint32_t baseMipLevel;
6529             1u,                              // uint32_t mipLevels;
6530             0u,                              // uint32_t baseArraySlice;
6531             getArraySize(m_params.dst.image) // uint32_t arraySize;
6532         }};
6533 
6534     // Only use one barrier if no options have been given.
6535     if (m_options != DE_NULL)
6536     {
6537         srcImageBarriers.push_back(m_multisampledImageBarrier);
6538         srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
6539         // Add the third barrier if option is as below.
6540         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6541             srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
6542     }
6543     else
6544     {
6545         srcImageBarriers.push_back(m_multisampledImageBarrier);
6546     }
6547 
6548     // Create render pass.
6549     {
6550         const VkAttachmentDescription attachmentDescription = {
6551             0u,                                   // VkAttachmentDescriptionFlags flags;
6552             m_params.src.image.format,            // VkFormat format;
6553             rasterizationSamples,                 // VkSampleCountFlagBits samples;
6554             VK_ATTACHMENT_LOAD_OP_CLEAR,          // VkAttachmentLoadOp loadOp;
6555             VK_ATTACHMENT_STORE_OP_STORE,         // VkAttachmentStoreOp storeOp;
6556             VK_ATTACHMENT_LOAD_OP_DONT_CARE,      // VkAttachmentLoadOp stencilLoadOp;
6557             VK_ATTACHMENT_STORE_OP_DONT_CARE,     // VkAttachmentStoreOp stencilStoreOp;
6558             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
6559             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL  // VkImageLayout finalLayout;
6560         };
6561 
6562         const VkAttachmentReference colorAttachmentReference = {
6563             0u,                                      // uint32_t attachment;
6564             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
6565         };
6566 
6567         const VkSubpassDescription subpassDescription = {
6568             0u,                              // VkSubpassDescriptionFlags flags;
6569             VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
6570             0u,                              // uint32_t inputAttachmentCount;
6571             DE_NULL,                         // const VkAttachmentReference* pInputAttachments;
6572             1u,                              // uint32_t colorAttachmentCount;
6573             &colorAttachmentReference,       // const VkAttachmentReference* pColorAttachments;
6574             DE_NULL,                         // const VkAttachmentReference* pResolveAttachments;
6575             DE_NULL,                         // const VkAttachmentReference* pDepthStencilAttachment;
6576             0u,                              // uint32_t preserveAttachmentCount;
6577             DE_NULL                          // const VkAttachmentReference* pPreserveAttachments;
6578         };
6579 
6580         // Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
6581         const VkSubpassDependency subpassDependency = {
6582             VK_SUBPASS_EXTERNAL,                           //uint32_t srcSubpass;
6583             0u,                                            //uint32_t dstSubpass;
6584             VK_PIPELINE_STAGE_TRANSFER_BIT,                //VkPipelineStageFlags srcStageMask;
6585             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags dstStageMask;
6586             VK_ACCESS_TRANSFER_WRITE_BIT,                  //VkAccessFlags srcAccessMask;
6587             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          //VkAccessFlags dstAccessMask;
6588             0u                                             //VkDependencyFlags dependencyFlags;
6589         };
6590 
6591         const bool useSubpassDependency =
6592             m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
6593         const VkRenderPassCreateInfo renderPassParams = {
6594             VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
6595             DE_NULL,                                   // const void* pNext;
6596             0u,                                        // VkRenderPassCreateFlags flags;
6597             1u,                                        // uint32_t attachmentCount;
6598             &attachmentDescription,                    // const VkAttachmentDescription* pAttachments;
6599             1u,                                        // uint32_t subpassCount;
6600             &subpassDescription,                       // const VkSubpassDescription* pSubpasses;
6601             useSubpassDependency ? 1u : 0u,            // uint32_t dependencyCount;
6602             &subpassDependency                         // const VkSubpassDependency* pDependencies;
6603         };
6604 
6605         renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
6606     }
6607 
6608     // Create pipeline layout
6609     {
6610         const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
6611             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6612             DE_NULL,                                       // const void* pNext;
6613             0u,                                            // VkPipelineLayoutCreateFlags flags;
6614             0u,                                            // uint32_t setLayoutCount;
6615             DE_NULL,                                       // const VkDescriptorSetLayout* pSetLayouts;
6616             0u,                                            // uint32_t pushConstantRangeCount;
6617             DE_NULL                                        // const VkPushConstantRange* pPushConstantRanges;
6618         };
6619 
6620         pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
6621     }
6622 
6623     // Create upper half triangle.
6624     {
6625         const tcu::Vec4 a(-1.0, -1.0, 0.0, 1.0);
6626         const tcu::Vec4 b(1.0, -1.0, 0.0, 1.0);
6627         const tcu::Vec4 c(1.0, 1.0, 0.0, 1.0);
6628         // Add triangle.
6629         vertices.push_back(a);
6630         vertices.push_back(c);
6631         vertices.push_back(b);
6632     }
6633 
6634     // Create vertex buffer.
6635     {
6636         const VkDeviceSize vertexDataSize           = vertices.size() * sizeof(tcu::Vec4);
6637         const VkBufferCreateInfo vertexBufferParams = {
6638             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
6639             DE_NULL,                              // const void* pNext;
6640             0u,                                   // VkBufferCreateFlags flags;
6641             vertexDataSize,                       // VkDeviceSize size;
6642             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
6643             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
6644             0u,                                   // uint32_t queueFamilyIndexCount;
6645             (const uint32_t *)DE_NULL,            // const uint32_t* pQueueFamilyIndices;
6646         };
6647 
6648         vertexBuffer      = createBuffer(vk, vkDevice, &vertexBufferParams);
6649         vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer,
6650                                            MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6651         VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(),
6652                                      vertexBufferAlloc->getOffset()));
6653 
6654         // Load vertices into vertex buffer.
6655         deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6656         flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6657     }
6658 
6659     {
6660         Move<VkFramebuffer> framebuffer;
6661         Move<VkImageView> sourceAttachmentView;
6662 
6663         uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6664 
6665         // Create color attachment view.
6666         {
6667             const VkImageViewCreateInfo colorAttachmentViewParams = {
6668                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType sType;
6669                 DE_NULL,                                                // const void* pNext;
6670                 0u,                                                     // VkImageViewCreateFlags flags;
6671                 *m_multisampledImage,                                   // VkImage image;
6672                 VK_IMAGE_VIEW_TYPE_2D,                                  // VkImageViewType viewType;
6673                 m_params.src.image.format,                              // VkFormat format;
6674                 componentMappingRGBA,                                   // VkComponentMapping components;
6675                 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u} // VkImageSubresourceRange subresourceRange;
6676             };
6677             sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
6678         }
6679 
6680         // Create framebuffer
6681         {
6682             const VkFramebufferCreateInfo framebufferParams = {
6683                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
6684                 DE_NULL,                                   // const void* pNext;
6685                 0u,                                        // VkFramebufferCreateFlags flags;
6686                 *renderPass,                               // VkRenderPass renderPass;
6687                 1u,                                        // uint32_t attachmentCount;
6688                 &sourceAttachmentView.get(),               // const VkImageView* pAttachments;
6689                 m_params.src.image.extent.width,           // uint32_t width;
6690                 m_params.src.image.extent.height,          // uint32_t height;
6691                 1u                                         // uint32_t layers;
6692             };
6693 
6694             framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6695         }
6696 
6697         // Create pipeline
6698         {
6699             const std::vector<VkViewport> viewports(1, makeViewport(m_params.src.image.extent));
6700             const std::vector<VkRect2D> scissors(1, makeRect2D(m_params.src.image.extent));
6701 
6702             const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
6703                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6704                 DE_NULL,                                                  // const void* pNext;
6705                 0u,                   // VkPipelineMultisampleStateCreateFlags flags;
6706                 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
6707                 VK_FALSE,             // VkBool32 sampleShadingEnable;
6708                 0.0f,                 // float minSampleShading;
6709                 DE_NULL,              // const VkSampleMask* pSampleMask;
6710                 VK_FALSE,             // VkBool32 alphaToCoverageEnable;
6711                 VK_FALSE              // VkBool32 alphaToOneEnable;
6712             };
6713 
6714             graphicsPipeline = makeGraphicsPipeline(
6715                 vk,                    // const DeviceInterface&                        vk
6716                 vkDevice,              // const VkDevice                                device
6717                 *pipelineLayout,       // const VkPipelineLayout                        pipelineLayout
6718                 *vertexShaderModule,   // const VkShaderModule                          vertexShaderModule
6719                 DE_NULL,               // const VkShaderModule                          tessellationControlModule
6720                 DE_NULL,               // const VkShaderModule                          tessellationEvalModule
6721                 DE_NULL,               // const VkShaderModule                          geometryShaderModule
6722                 *fragmentShaderModule, // const VkShaderModule                          fragmentShaderModule
6723                 *renderPass,           // const VkRenderPass                            renderPass
6724                 viewports,             // const std::vector<VkViewport>&                viewports
6725                 scissors,              // const std::vector<VkRect2D>&                  scissors
6726                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                     topology
6727                 0u,                                  // const uint32_t                                subpass
6728                 0u,                                  // const uint32_t                                patchControlPoints
6729                 DE_NULL,                  // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6730                 DE_NULL,                  // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6731                 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6732         }
6733 
6734         // Create command buffer
6735         {
6736             beginCommandBuffer(vk, *m_universalCmdBuffer, 0u);
6737 
6738             if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6739             {
6740                 // Change the image layouts.
6741                 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
6742                                       VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0,
6743                                       (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
6744                                       (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6745 
6746                 // Clear the 'm_multisampledImage'.
6747                 {
6748                     const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6749                     const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,
6750                                                                       m_params.src.image.extent.depth);
6751                     vk.cmdClearColorImage(*m_universalCmdBuffer, m_multisampledImage.get(),
6752                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6753                 }
6754 
6755                 // Clear the 'm_multisampledCopyImage' with different color.
6756                 {
6757                     const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6758                     const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,
6759                                                                       m_params.src.image.extent.depth);
6760                     vk.cmdClearColorImage(*m_universalCmdBuffer, m_multisampledCopyImage.get(),
6761                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6762                 }
6763             }
6764             else
6765             {
6766                 // Change the image layouts.
6767                 vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
6768                                       VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0,
6769                                       (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
6770                                       (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6771             }
6772 
6773             beginRenderPass(vk, *m_universalCmdBuffer, *renderPass, *framebuffer,
6774                             makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height),
6775                             tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
6776 
6777             const VkDeviceSize vertexBufferOffset = 0u;
6778 
6779             vk.cmdBindPipeline(*m_universalCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6780             vk.cmdBindVertexBuffers(*m_universalCmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6781             vk.cmdDraw(*m_universalCmdBuffer, (uint32_t)vertices.size(), 1, 0, 0);
6782 
6783             endRenderPass(vk, *m_universalCmdBuffer);
6784             endCommandBuffer(vk, *m_universalCmdBuffer);
6785         }
6786 
6787         // Queue submit.
6788         {
6789             submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
6790             m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
6791         }
6792     }
6793 }
6794 
iterate(void)6795 tcu::TestStatus ResolveImageToImage::iterate(void)
6796 {
6797     const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6798     const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
6799 
6800     // upload the destination image
6801     m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(
6802         new tcu::TextureLevel(dstTcuFormat, (int)m_params.dst.image.extent.width, (int)m_params.dst.image.extent.height,
6803                               (int)m_params.dst.image.extent.depth));
6804     generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width,
6805                    m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6806     uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6807 
6808     m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(
6809         new tcu::TextureLevel(srcTcuFormat, (int)m_params.src.image.extent.width, (int)m_params.src.image.extent.height,
6810                               (int)m_params.dst.image.extent.depth));
6811 
6812     generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height,
6813                    m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
6814     generateExpectedResult();
6815 
6816     VkImage sourceImage      = m_multisampledImage.get();
6817     uint32_t sourceArraySize = getArraySize(m_params.src.image);
6818 
6819     switch (m_options)
6820     {
6821     case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6822     case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6823         // Duplicate the multisampled image to a multisampled image array
6824         sourceArraySize = getArraySize(m_params.dst.image); // fall through
6825     case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6826     case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6827     case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6828     case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6829     case COPY_MS_IMAGE_TO_MS_IMAGE:
6830         copyMSImageToMSImage(sourceArraySize);
6831         sourceImage = m_multisampledCopyImage.get();
6832         break;
6833     default:
6834         break;
6835     }
6836 
6837     const DeviceInterface &vk = m_context.getDeviceInterface();
6838     const VkDevice vkDevice   = m_device;
6839 
6840     std::vector<VkImageResolve> imageResolves;
6841     std::vector<VkImageResolve2KHR> imageResolves2KHR;
6842     for (CopyRegion region : m_params.regions)
6843     {
6844         // If copying multiple regions, make sure that the same regions are
6845         // used for resolving as the ones used for copying.
6846         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6847         {
6848             VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6849                                         getExtent3D(m_params.src.image).height / 2,
6850                                         getExtent3D(m_params.src.image).depth};
6851 
6852             const VkImageResolve imageResolve = {
6853                 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6854                 region.imageResolve.dstOffset,      // VkOffset3D srcOffset;
6855                 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6856                 region.imageResolve.dstOffset,      // VkOffset3D dstOffset;
6857                 partialExtent,                      // VkExtent3D extent;
6858             };
6859 
6860             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6861             {
6862                 imageResolves.push_back(imageResolve);
6863             }
6864             else
6865             {
6866                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6867                 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6868             }
6869         }
6870         else
6871         {
6872             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6873             {
6874                 imageResolves.push_back(region.imageResolve);
6875             }
6876             else
6877             {
6878                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6879                 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6880             }
6881         }
6882     }
6883 
6884     const VkImageMemoryBarrier imageBarriers[] = {
6885         // source image
6886         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6887          DE_NULL,                                // const void* pNext;
6888          VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,   // VkAccessFlags srcAccessMask;
6889          VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
6890          m_options == NO_OPTIONAL_OPERATION ? m_params.dst.image.operationLayout :
6891                                               m_params.src.image.operationLayout, // VkImageLayout oldLayout;
6892          m_params.src.image.operationLayout,                                      // VkImageLayout newLayout;
6893          VK_QUEUE_FAMILY_IGNORED,                                                 // uint32_t srcQueueFamilyIndex;
6894          VK_QUEUE_FAMILY_IGNORED,                                                 // uint32_t dstQueueFamilyIndex;
6895          sourceImage,                                                             // VkImage image;
6896          {
6897              // VkImageSubresourceRange subresourceRange;
6898              getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6899              0u,                           // uint32_t baseMipLevel;
6900              1u,                           // uint32_t mipLevels;
6901              0u,                           // uint32_t baseArraySlice;
6902              sourceArraySize               // uint32_t arraySize;
6903          }},
6904         // destination image
6905         {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6906          DE_NULL,                                // const void* pNext;
6907          0u,                                     // VkAccessFlags srcAccessMask;
6908          VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
6909          VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
6910          m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
6911          VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
6912          VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
6913          m_destination.get(),                    // VkImage image;
6914          {
6915              // VkImageSubresourceRange subresourceRange;
6916              getAspectFlags(dstTcuFormat),    // VkImageAspectFlags aspectMask;
6917              0u,                              // uint32_t baseMipLevel;
6918              1u,                              // uint32_t mipLevels;
6919              0u,                              // uint32_t baseArraySlice;
6920              getArraySize(m_params.dst.image) // uint32_t arraySize;
6921          }},
6922     };
6923 
6924     const VkImageMemoryBarrier postImageBarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6925                                                    DE_NULL,                                // const void* pNext;
6926                                                    VK_ACCESS_TRANSFER_WRITE_BIT,       // VkAccessFlags srcAccessMask;
6927                                                    VK_ACCESS_HOST_READ_BIT,            // VkAccessFlags dstAccessMask;
6928                                                    m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6929                                                    m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6930                                                    VK_QUEUE_FAMILY_IGNORED,            // uint32_t srcQueueFamilyIndex;
6931                                                    VK_QUEUE_FAMILY_IGNORED,            // uint32_t dstQueueFamilyIndex;
6932                                                    m_destination.get(),                // VkImage image;
6933                                                    {
6934                                                        // VkImageSubresourceRange subresourceRange;
6935                                                        getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6936                                                        0u,                           // uint32_t baseMipLevel;
6937                                                        1u,                           // uint32_t mipLevels;
6938                                                        0u,                           // uint32_t baseArraySlice;
6939                                                        getArraySize(m_params.dst.image) // uint32_t arraySize;
6940                                                    }};
6941 
6942     beginCommandBuffer(vk, *m_universalCmdBuffer);
6943     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
6944                           VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
6945                           (const VkBufferMemoryBarrier *)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
6946 
6947     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
6948     {
6949         vk.cmdResolveImage(*m_universalCmdBuffer, sourceImage, m_params.src.image.operationLayout, m_destination.get(),
6950                            m_params.dst.image.operationLayout, (uint32_t)m_params.regions.size(), imageResolves.data());
6951     }
6952     else
6953     {
6954         DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
6955         const VkResolveImageInfo2KHR ResolveImageInfo2KHR = {
6956             VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR, // VkStructureType sType;
6957             DE_NULL,                                    // const void* pNext;
6958             sourceImage,                                // VkImage srcImage;
6959             m_params.src.image.operationLayout,         // VkImageLayout srcImageLayout;
6960             m_destination.get(),                        // VkImage dstImage;
6961             m_params.dst.image.operationLayout,         // VkImageLayout dstImageLayout;
6962             (uint32_t)m_params.regions.size(),          // uint32_t regionCount;
6963             imageResolves2KHR.data()                    // const  VkImageResolve2KHR* pRegions;
6964         };
6965         vk.cmdResolveImage2(*m_universalCmdBuffer, &ResolveImageInfo2KHR);
6966     }
6967 
6968     vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
6969                           (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
6970                           (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
6971     endCommandBuffer(vk, *m_universalCmdBuffer);
6972     submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
6973     m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
6974 
6975     de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
6976 
6977     if (shouldVerifyIntermediateResults(m_options))
6978     {
6979         // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6980         // resolving the image and giving every sample the same value.
6981         const auto intermediateResult = checkIntermediateCopy();
6982         if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6983             return intermediateResult;
6984     }
6985 
6986     return checkTestResult(resultTextureLevel->getAccess());
6987 }
6988 
checkTestResult(tcu::ConstPixelBufferAccess result)6989 tcu::TestStatus ResolveImageToImage::checkTestResult(tcu::ConstPixelBufferAccess result)
6990 {
6991     const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
6992     const float fuzzyThreshold                 = 0.01f;
6993 
6994     if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6995     {
6996         // Check that all the layers that have not been written to are solid white.
6997         tcu::Vec4 expectedColor(1.0f, 1.0f, 1.0f, 1.0f);
6998         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6999         {
7000             const tcu::ConstPixelBufferAccess resultSub =
7001                 getSubregion(result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
7002             if (resultSub.getPixel(0, 0) != expectedColor)
7003                 return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
7004         }
7005 
7006         // Check that the layer that has been copied to is the same as the layer that has been copied from.
7007         const tcu::ConstPixelBufferAccess expectedSub =
7008             getSubregion(expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
7009         const tcu::ConstPixelBufferAccess resultSub =
7010             getSubregion(result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
7011         if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub,
7012                                resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
7013             return tcu::TestStatus::fail("CopiesAndBlitting test");
7014     }
7015     else
7016     {
7017         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
7018         {
7019             const tcu::ConstPixelBufferAccess expectedSub =
7020                 getSubregion(expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
7021             const tcu::ConstPixelBufferAccess resultSub =
7022                 getSubregion(result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
7023             if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub,
7024                                    resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
7025                 return tcu::TestStatus::fail("CopiesAndBlitting test");
7026         }
7027     }
7028 
7029     return tcu::TestStatus::pass("CopiesAndBlitting test");
7030 }
7031 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,uint32_t mipLevel)7032 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst,
7033                                                    CopyRegion region, uint32_t mipLevel)
7034 {
7035     DE_UNREF(mipLevel);
7036 
7037     VkOffset3D srcOffset = region.imageResolve.srcOffset;
7038     srcOffset.z          = region.imageResolve.srcSubresource.baseArrayLayer;
7039     VkOffset3D dstOffset = region.imageResolve.dstOffset;
7040     dstOffset.z          = region.imageResolve.dstSubresource.baseArrayLayer;
7041     VkExtent3D extent    = region.imageResolve.extent;
7042     extent.depth         = (region.imageResolve.srcSubresource.layerCount == VK_REMAINING_ARRAY_LAYERS) ?
7043                                (src.getDepth() - region.imageResolve.srcSubresource.baseArrayLayer) :
7044                                region.imageResolve.srcSubresource.layerCount;
7045 
7046     const tcu::ConstPixelBufferAccess srcSubRegion =
7047         getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
7048     // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
7049     const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
7050     const tcu::PixelBufferAccess dstSubRegion = getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z,
7051                                                              extent.width, extent.height, extent.depth);
7052 
7053     tcu::copy(dstSubRegion, srcSubRegion);
7054 }
7055 
checkIntermediateCopy(void)7056 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy(void)
7057 {
7058     const auto &vkd          = m_context.getDeviceInterface();
7059     const auto device        = m_device;
7060     const auto queueIndex    = m_context.getUniversalQueueFamilyIndex();
7061     auto &alloc              = *m_allocator;
7062     const auto currentLayout = m_params.src.image.operationLayout;
7063     const auto numDstLayers  = getArraySize(m_params.dst.image);
7064     const auto numInputAttachments =
7065         m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
7066     constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
7067     const auto fbWidth     = m_params.src.image.extent.width;
7068     const auto fbHeight    = m_params.src.image.extent.height;
7069 
7070     // Push constants.
7071     const std::array<int, 3> pushConstantData = {{
7072         static_cast<int>(fbWidth),
7073         static_cast<int>(fbHeight),
7074         static_cast<int>(m_params.samples),
7075     }};
7076     const auto pushConstantSize =
7077         static_cast<uint32_t>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
7078 
7079     // Shader modules.
7080     const auto vertexModule       = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7081     const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
7082 
7083     // Descriptor sets.
7084     DescriptorPoolBuilder poolBuilder;
7085     poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
7086     poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7087     const auto descriptorPool =
7088         poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7089 
7090     DescriptorSetLayoutBuilder layoutBuilderBuffer;
7091     layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7092     const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7093 
7094     DescriptorSetLayoutBuilder layoutBuilderAttachments;
7095     for (uint32_t i = 0u; i < numInputAttachments; ++i)
7096         layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7097     const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7098 
7099     const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7100     const auto descriptorSetAttachments =
7101         makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7102 
7103     // Array with raw descriptor sets.
7104     const std::array<VkDescriptorSet, numSets> descriptorSets = {{
7105         descriptorSetBuffer.get(),
7106         descriptorSetAttachments.get(),
7107     }};
7108 
7109     // Pipeline layout.
7110     const std::array<VkDescriptorSetLayout, numSets> setLayouts = {{
7111         outputBufferSetLayout.get(),
7112         inputAttachmentsSetLayout.get(),
7113     }};
7114 
7115     const VkPushConstantRange pushConstantRange = {
7116         VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
7117         0u,                           // uint32_t offset;
7118         pushConstantSize,             // uint32_t size;
7119     };
7120 
7121     const VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
7122         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
7123         nullptr,                                       // const void* pNext;
7124         0u,                                            // VkPipelineLayoutCreateFlags flags;
7125         static_cast<uint32_t>(setLayouts.size()),      // uint32_t setLayoutCount;
7126         setLayouts.data(),                             // const VkDescriptorSetLayout* pSetLayouts;
7127         1u,                                            // uint32_t pushConstantRangeCount;
7128         &pushConstantRange,                            // const VkPushConstantRange* pPushConstantRanges;
7129     };
7130 
7131     const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
7132 
7133     // Render pass.
7134     const VkAttachmentDescription commonAttachmentDescription = {
7135         0u,                               // VkAttachmentDescriptionFlags flags;
7136         m_params.src.image.format,        // VkFormat format;
7137         m_params.samples,                 // VkSampleCountFlagBits samples;
7138         VK_ATTACHMENT_LOAD_OP_LOAD,       // VkAttachmentLoadOp loadOp;
7139         VK_ATTACHMENT_STORE_OP_STORE,     // VkAttachmentStoreOp storeOp;
7140         VK_ATTACHMENT_LOAD_OP_DONT_CARE,  // VkAttachmentLoadOp stencilLoadOp;
7141         VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
7142         currentLayout,                    // VkImageLayout initialLayout;
7143         currentLayout,                    // VkImageLayout finalLayout;
7144     };
7145     const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
7146 
7147     std::vector<VkAttachmentReference> inputAttachmentReferences;
7148     inputAttachmentReferences.reserve(numInputAttachments);
7149     for (uint32_t i = 0u; i < numInputAttachments; ++i)
7150     {
7151         const VkAttachmentReference reference = {i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
7152         inputAttachmentReferences.push_back(reference);
7153     }
7154 
7155     const VkSubpassDescription subpassDescription = {
7156         0u,                                                      // VkSubpassDescriptionFlags flags;
7157         VK_PIPELINE_BIND_POINT_GRAPHICS,                         // VkPipelineBindPoint pipelineBindPoint;
7158         static_cast<uint32_t>(inputAttachmentReferences.size()), // uint32_t inputAttachmentCount;
7159         inputAttachmentReferences.data(),                        // const VkAttachmentReference* pInputAttachments;
7160         0u,                                                      // uint32_t colorAttachmentCount;
7161         nullptr,                                                 // const VkAttachmentReference* pColorAttachments;
7162         nullptr,                                                 // const VkAttachmentReference* pResolveAttachments;
7163         nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
7164         0u,      // uint32_t preserveAttachmentCount;
7165         nullptr, // const uint32_t* pPreserveAttachments;
7166     };
7167 
7168     const VkRenderPassCreateInfo renderPassInfo = {
7169         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,            // VkStructureType sType;
7170         nullptr,                                              // const void* pNext;
7171         0u,                                                   // VkRenderPassCreateFlags flags;
7172         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
7173         attachmentDescriptions.data(),                        // const VkAttachmentDescription* pAttachments;
7174         1u,                                                   // uint32_t subpassCount;
7175         &subpassDescription,                                  // const VkSubpassDescription* pSubpasses;
7176         0u,                                                   // uint32_t dependencyCount;
7177         nullptr,                                              // const VkSubpassDependency* pDependencies;
7178     };
7179 
7180     const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
7181 
7182     // Framebuffer.
7183     std::vector<Move<VkImageView>> imageViews;
7184     std::vector<VkImageView> imageViewsRaw;
7185 
7186     if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7187     {
7188         imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7189                                            m_params.src.image.format,
7190                                            makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
7191         imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7192                                            m_params.src.image.format,
7193                                            makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
7194     }
7195     else
7196     {
7197         imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7198                                            m_params.src.image.format,
7199                                            makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
7200         for (uint32_t i = 0u; i < numDstLayers; ++i)
7201         {
7202             const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
7203             imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D,
7204                                                m_params.dst.image.format, subresourceRange));
7205         }
7206     }
7207 
7208     imageViewsRaw.reserve(imageViews.size());
7209     std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw),
7210                    [](const Move<VkImageView> &ptr) { return ptr.get(); });
7211 
7212     const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<uint32_t>(imageViewsRaw.size()),
7213                                              imageViewsRaw.data(), fbWidth, fbHeight);
7214 
7215     // Storage buffer.
7216     const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
7217     const auto bufferSize  = static_cast<VkDeviceSize>(bufferCount * sizeof(int32_t));
7218     BufferWithMemory buffer(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
7219                             MemoryRequirement::HostVisible);
7220     auto &bufferAlloc = buffer.getAllocation();
7221     void *bufferData  = bufferAlloc.getHostPtr();
7222 
7223     // Update descriptor sets.
7224     DescriptorSetUpdateBuilder updater;
7225 
7226     const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
7227     updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u),
7228                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
7229 
7230     std::vector<VkDescriptorImageInfo> imageInfos;
7231     imageInfos.reserve(imageViewsRaw.size());
7232     for (size_t i = 0; i < imageViewsRaw.size(); ++i)
7233         imageInfos.push_back(
7234             makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
7235 
7236     for (size_t i = 0; i < imageInfos.size(); ++i)
7237         updater.writeSingle(descriptorSetAttachments.get(),
7238                             DescriptorSetUpdateBuilder::Location::binding(static_cast<uint32_t>(i)),
7239                             VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
7240 
7241     updater.update(vkd, device);
7242 
7243     // Vertex buffer.
7244     std::vector<tcu::Vec4> fullScreenQuad;
7245     {
7246         // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
7247         const tcu::Vec4 topLeft(-1.0f, -1.0f, 0.0f, 1.0f);
7248         const tcu::Vec4 topRight(1.0f, -1.0f, 0.0f, 1.0f);
7249         const tcu::Vec4 bottomLeft(-1.0f, 1.0f, 0.0f, 1.0f);
7250         const tcu::Vec4 bottomRight(1.0f, 1.0f, 0.0f, 1.0f);
7251 
7252         fullScreenQuad.reserve(6u);
7253         fullScreenQuad.push_back(topLeft);
7254         fullScreenQuad.push_back(topRight);
7255         fullScreenQuad.push_back(bottomRight);
7256         fullScreenQuad.push_back(topLeft);
7257         fullScreenQuad.push_back(bottomRight);
7258         fullScreenQuad.push_back(bottomLeft);
7259     }
7260 
7261     const auto vertexBufferSize =
7262         static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
7263     const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
7264     const BufferWithMemory vertexBuffer(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
7265     const auto vertexBufferHandler        = vertexBuffer.get();
7266     auto &vertexBufferAlloc               = vertexBuffer.getAllocation();
7267     void *vertexBufferData                = vertexBufferAlloc.getHostPtr();
7268     const VkDeviceSize vertexBufferOffset = 0ull;
7269 
7270     deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
7271     flushAlloc(vkd, device, vertexBufferAlloc);
7272 
7273     // Graphics pipeline.
7274     const std::vector<VkViewport> viewports(1, makeViewport(m_params.src.image.extent));
7275     const std::vector<VkRect2D> scissors(1, makeRect2D(m_params.src.image.extent));
7276 
7277     const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
7278         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
7279         nullptr,                                                  // const void* pNext;
7280         0u,                                                       // VkPipelineMultisampleStateCreateFlags flags;
7281         VK_SAMPLE_COUNT_1_BIT,                                    // VkSampleCountFlagBits rasterizationSamples;
7282         VK_FALSE,                                                 // VkBool32 sampleShadingEnable;
7283         0.0f,                                                     // float minSampleShading;
7284         nullptr,                                                  // const VkSampleMask* pSampleMask;
7285         VK_FALSE,                                                 // VkBool32 alphaToCoverageEnable;
7286         VK_FALSE                                                  // VkBool32 alphaToOneEnable;
7287     };
7288 
7289     const auto graphicsPipeline = makeGraphicsPipeline(
7290         vkd,                                 // const DeviceInterface&                        vk
7291         device,                              // const VkDevice                                device
7292         pipelineLayout.get(),                // const VkPipelineLayout                        pipelineLayout
7293         vertexModule.get(),                  // const VkShaderModule                          vertexShaderModule
7294         DE_NULL,                             // const VkShaderModule                          tessellationControlModule
7295         DE_NULL,                             // const VkShaderModule                          tessellationEvalModule
7296         DE_NULL,                             // const VkShaderModule                          geometryShaderModule
7297         verificationModule.get(),            // const VkShaderModule                          fragmentShaderModule
7298         renderPass.get(),                    // const VkRenderPass                            renderPass
7299         viewports,                           // const std::vector<VkViewport>&                viewports
7300         scissors,                            // const std::vector<VkRect2D>&                  scissors
7301         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                     topology
7302         0u,                                  // const uint32_t                                subpass
7303         0u,                                  // const uint32_t                                patchControlPoints
7304         nullptr,                             // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
7305         nullptr,                  // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
7306         &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
7307 
7308     // Command buffer.
7309     const auto cmdPool      = makeCommandPool(vkd, device, queueIndex);
7310     const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7311     const auto cmdBuffer    = cmdBufferPtr.get();
7312 
7313     // Make sure multisample copy data is available to the fragment shader.
7314     const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
7315 
7316     // Make sure verification buffer data is available on the host.
7317     const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
7318 
7319     // Record and submit command buffer.
7320     beginCommandBuffer(vkd, cmdBuffer);
7321     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u,
7322                            &imagesBarrier, 0u, nullptr, 0u, nullptr);
7323     beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
7324     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
7325     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
7326     vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize,
7327                          pushConstantData.data());
7328     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u,
7329                               static_cast<uint32_t>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
7330     vkd.cmdDraw(cmdBuffer, static_cast<uint32_t>(fullScreenQuad.size()), 1u, 0u, 0u);
7331     endRenderPass(vkd, cmdBuffer);
7332     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u,
7333                            &bufferBarrier, 0u, nullptr, 0u, nullptr);
7334     endCommandBuffer(vkd, cmdBuffer);
7335     submitCommandsAndWait(vkd, device, m_universalQueue, cmdBuffer);
7336     m_context.resetCommandPoolForVKSC(device, *cmdPool);
7337 
7338     // Verify intermediate results.
7339     invalidateAlloc(vkd, device, bufferAlloc);
7340     std::vector<int32_t> outputFlags(bufferCount, 0);
7341     deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
7342 
7343     auto &log = m_context.getTestContext().getLog();
7344     log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
7345 
7346     const auto sampleCount = static_cast<uint32_t>(m_params.samples);
7347 
7348     for (uint32_t x = 0u; x < fbWidth; ++x)
7349         for (uint32_t y = 0u; y < fbHeight; ++y)
7350             for (uint32_t s = 0u; s < sampleCount; ++s)
7351             {
7352                 const auto index = (y * fbWidth + x) * sampleCount + s;
7353                 if (!outputFlags[index])
7354                 {
7355                     std::ostringstream msg;
7356                     msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
7357                     return tcu::TestStatus::fail(msg.str());
7358                 }
7359             }
7360 
7361     log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
7362     return tcu::TestStatus::pass("Pass");
7363 }
7364 
copyMSImageToMSImage(uint32_t copyArraySize)7365 void ResolveImageToImage::copyMSImageToMSImage(uint32_t copyArraySize)
7366 {
7367     const DeviceInterface &vk             = m_context.getDeviceInterface();
7368     const VkDevice vkDevice               = m_device;
7369     const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
7370     std::vector<VkImageCopy> imageCopies;
7371     std::vector<VkImageCopy2KHR> imageCopies2KHR;
7372 
7373     if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7374     {
7375         const VkImageSubresourceLayers sourceSubresourceLayers = {
7376             getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
7377             0u,                           // uint32_t mipLevel;
7378             2u,                           // uint32_t baseArrayLayer;
7379             1u                            // uint32_t layerCount;
7380         };
7381 
7382         const VkImageSubresourceLayers destinationSubresourceLayers = {
7383             getAspectFlags(srcTcuFormat), // VkImageAspectFlags    aspectMask;//getAspectFlags(dstTcuFormat)
7384             0u,                           // uint32_t mipLevel;
7385             4u,                           // uint32_t baseArrayLayer;
7386             1u                            // uint32_t layerCount;
7387         };
7388 
7389         const VkImageCopy imageCopy = {
7390             sourceSubresourceLayers,         // VkImageSubresourceLayers srcSubresource;
7391             {0, 0, 0},                       // VkOffset3D srcOffset;
7392             destinationSubresourceLayers,    // VkImageSubresourceLayers dstSubresource;
7393             {0, 0, 0},                       // VkOffset3D dstOffset;
7394             getExtent3D(m_params.src.image), // VkExtent3D extent;
7395         };
7396 
7397         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7398         {
7399             imageCopies.push_back(imageCopy);
7400         }
7401         else
7402         {
7403             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7404             imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7405         }
7406     }
7407     else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
7408     {
7409         VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
7410                                     getExtent3D(m_params.src.image).height / 2, getExtent3D(m_params.src.image).depth};
7411 
7412         for (CopyRegion region : m_params.regions)
7413         {
7414             const VkImageCopy imageCopy = {
7415                 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
7416                 region.imageResolve.srcOffset,      // VkOffset3D srcOffset;
7417                 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
7418                 region.imageResolve.dstOffset,      // VkOffset3D dstOffset;
7419                 partialExtent,                      // VkExtent3D extent;
7420             };
7421 
7422             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7423             {
7424                 imageCopies.push_back(imageCopy);
7425             }
7426             else
7427             {
7428                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7429                 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7430             }
7431         }
7432     }
7433     else
7434     {
7435         for (uint32_t layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
7436         {
7437             const VkImageSubresourceLayers sourceSubresourceLayers = {
7438                 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
7439                 0u,                           // uint32_t mipLevel;
7440                 0u,                           // uint32_t baseArrayLayer;
7441                 1u                            // uint32_t layerCount;
7442             };
7443 
7444             const VkImageSubresourceLayers destinationSubresourceLayers = {
7445                 getAspectFlags(srcTcuFormat), // VkImageAspectFlags    aspectMask;//getAspectFlags(dstTcuFormat)
7446                 0u,                           // uint32_t mipLevel;
7447                 layerNdx,                     // uint32_t baseArrayLayer;
7448                 1u                            // uint32_t layerCount;
7449             };
7450 
7451             const VkImageCopy imageCopy = {
7452                 sourceSubresourceLayers,         // VkImageSubresourceLayers srcSubresource;
7453                 {0, 0, 0},                       // VkOffset3D srcOffset;
7454                 destinationSubresourceLayers,    // VkImageSubresourceLayers dstSubresource;
7455                 {0, 0, 0},                       // VkOffset3D dstOffset;
7456                 getExtent3D(m_params.src.image), // VkExtent3D extent;
7457             };
7458 
7459             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7460             {
7461                 imageCopies.push_back(imageCopy);
7462             }
7463             else
7464             {
7465                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7466                 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
7467             }
7468         }
7469     }
7470 
7471     VkImageSubresourceRange subresourceRange = {
7472         getAspectFlags(srcTcuFormat), // VkImageAspectFlags    aspectMask
7473         0u,                           // uint32_t                baseMipLevel
7474         1u,                           // uint32_t                mipLevels
7475         0u,                           // uint32_t                baseArraySlice
7476         copyArraySize                 // uint32_t                arraySize
7477     };
7478 
7479     // m_multisampledImage
7480     const VkImageMemoryBarrier m_multisampledImageBarrier = {
7481         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7482         DE_NULL,                                // const void* pNext;
7483         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,   // VkAccessFlags srcAccessMask;
7484         VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
7485         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
7486         m_params.src.image.operationLayout,     // VkImageLayout newLayout;
7487         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
7488         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
7489         m_multisampledImage.get(),              // VkImage image;
7490         {
7491             // VkImageSubresourceRange subresourceRange;
7492             getAspectFlags(srcTcuFormat),    // VkImageAspectFlags aspectMask;
7493             0u,                              // uint32_t baseMipLevel;
7494             1u,                              // uint32_t mipLevels;
7495             0u,                              // uint32_t baseArraySlice;
7496             getArraySize(m_params.src.image) // uint32_t arraySize;
7497         }};
7498     // m_multisampledCopyImage
7499     VkImageMemoryBarrier m_multisampledCopyImageBarrier = {
7500         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7501         DE_NULL,                                // const void* pNext;
7502         0,                                      // VkAccessFlags srcAccessMask;
7503         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
7504         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
7505         m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
7506         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
7507         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
7508         m_multisampledCopyImage.get(),          // VkImage image;
7509         subresourceRange                        // VkImageSubresourceRange subresourceRange;
7510     };
7511 
7512     // m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
7513     const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier = {
7514         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7515         DE_NULL,                                // const void* pNext;
7516         0,                                      // VkAccessFlags srcAccessMask;
7517         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags dstAccessMask;
7518         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout oldLayout;
7519         m_params.dst.image.operationLayout,     // VkImageLayout newLayout;
7520         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
7521         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
7522         m_multisampledCopyNoCabImage.get(),     // VkImage image;
7523         subresourceRange                        // VkImageSubresourceRange subresourceRange;
7524     };
7525 
7526     // destination image
7527     const VkImageMemoryBarrier multisampledCopyImagePostBarrier = {
7528         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7529         DE_NULL,                                // const void* pNext;
7530         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
7531         VK_ACCESS_MEMORY_READ_BIT,              // VkAccessFlags dstAccessMask;
7532         m_params.dst.image.operationLayout,     // VkImageLayout oldLayout;
7533         m_params.src.image.operationLayout,     // VkImageLayout newLayout;
7534         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
7535         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
7536         m_multisampledCopyImage.get(),          // VkImage image;
7537         subresourceRange                        // VkImageSubresourceRange subresourceRange;
7538     };
7539 
7540     // destination image (no USAGE_COLOR_ATTACHMENT_BIT)
7541     const VkImageMemoryBarrier betweenCopyImageBarrier = {
7542         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
7543         DE_NULL,                                // const void* pNext;
7544         VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
7545         VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
7546         m_params.dst.image.operationLayout,     // VkImageLayout oldLayout;
7547         m_params.src.image.operationLayout,     // VkImageLayout newLayout;
7548         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
7549         VK_QUEUE_FAMILY_IGNORED,                // uint32_t dstQueueFamilyIndex;
7550         m_multisampledCopyNoCabImage.get(),     // VkImage image;
7551         subresourceRange                        // VkImageSubresourceRange subresourceRange;
7552     };
7553 
7554     uint32_t familyIndex                        = activeQueueFamilyIndex();
7555     VkQueue queue                               = VK_NULL_HANDLE;
7556     VkCommandBuffer commandBuffer               = VK_NULL_HANDLE;
7557     VkCommandPool commandPool                   = VK_NULL_HANDLE;
7558     std::tie(queue, commandBuffer, commandPool) = activeExecutionCtx();
7559 
7560     // Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
7561     if (m_params.queueSelection != QueueSelectionOptions::Universal)
7562     {
7563         // Release ownership from graphics queue.
7564         {
7565             std::vector<VkImageMemoryBarrier> barriers;
7566             barriers.reserve(2);
7567 
7568             // Barrier for m_multisampledImage
7569             VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
7570             releaseBarrier.dstAccessMask        = 0u; // dstAccessMask is ignored in ownership release operation.
7571             releaseBarrier.srcQueueFamilyIndex  = m_context.getUniversalQueueFamilyIndex();
7572             releaseBarrier.dstQueueFamilyIndex  = familyIndex;
7573             barriers.push_back(releaseBarrier);
7574 
7575             // Barrier for m_multisampledCopyImage
7576             releaseBarrier                     = m_multisampledCopyImageBarrier;
7577             releaseBarrier.dstAccessMask       = 0u; // dstAccessMask is ignored in ownership release operation.
7578             releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7579             releaseBarrier.dstQueueFamilyIndex = familyIndex;
7580             barriers.push_back(releaseBarrier);
7581 
7582             beginCommandBuffer(vk, *m_universalCmdBuffer);
7583             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7584                                   VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0,
7585                                   (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
7586                                   (uint32_t)barriers.size(), barriers.data());
7587             endCommandBuffer(vk, *m_universalCmdBuffer);
7588             submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
7589             m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
7590         }
7591 
7592         // Acquire ownership to compute / transfer queue.
7593         {
7594             std::vector<VkImageMemoryBarrier> barriers;
7595             barriers.reserve(2);
7596 
7597             // Barrier for m_multisampledImage
7598             VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
7599             acquireBarrier.srcAccessMask        = 0u; // srcAccessMask is ignored in ownership acquire operation.
7600             acquireBarrier.srcQueueFamilyIndex  = m_context.getUniversalQueueFamilyIndex();
7601             acquireBarrier.dstQueueFamilyIndex  = familyIndex;
7602             barriers.push_back(acquireBarrier);
7603 
7604             // Barrier for m_multisampledImage
7605             acquireBarrier                     = m_multisampledCopyImageBarrier;
7606             acquireBarrier.srcAccessMask       = 0u; // srcAccessMask is ignored in ownership acquire operation.
7607             acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7608             acquireBarrier.dstQueueFamilyIndex = familyIndex;
7609             barriers.push_back(acquireBarrier);
7610 
7611             beginCommandBuffer(vk, commandBuffer);
7612             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7613                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7614                                   (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7615             endCommandBuffer(vk, commandBuffer);
7616             submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7617             m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7618         }
7619 
7620         beginCommandBuffer(vk, commandBuffer);
7621     }
7622     else
7623     {
7624         // Universal queue
7625 
7626         std::vector<VkImageMemoryBarrier> imageBarriers;
7627 
7628         imageBarriers.push_back(m_multisampledImageBarrier);
7629         // Only use one barrier if no options have been given.
7630         if (m_options != NO_OPTIONAL_OPERATION)
7631         {
7632             imageBarriers.push_back(m_multisampledCopyImageBarrier);
7633             // Add the third barrier if option is as below.
7634             if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7635                 imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
7636         }
7637 
7638         beginCommandBuffer(vk, commandBuffer);
7639         vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
7640                               VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL,
7641                               0, (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)imageBarriers.size(),
7642                               imageBarriers.data());
7643     }
7644 
7645     if (!(m_params.extensionFlags & COPY_COMMANDS_2))
7646     {
7647         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7648         {
7649             vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout,
7650                             m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout,
7651                             (uint32_t)imageCopies.size(), imageCopies.data());
7652             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7653                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7654                                   (const VkBufferMemoryBarrier *)DE_NULL, 1u, &betweenCopyImageBarrier);
7655             vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout,
7656                             m_multisampledCopyImage.get(), m_params.dst.image.operationLayout,
7657                             (uint32_t)imageCopies.size(), imageCopies.data());
7658         }
7659         else
7660         {
7661             vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout,
7662                             m_multisampledCopyImage.get(), m_params.dst.image.operationLayout,
7663                             (uint32_t)imageCopies.size(), imageCopies.data());
7664         }
7665     }
7666     else
7667     {
7668         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7669         {
7670             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7671             const VkCopyImageInfo2KHR copyImageInfo2KHR = {
7672                 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7673                 DE_NULL,                                 // const void* pNext;
7674                 m_multisampledImage.get(),               // VkImage srcImage;
7675                 m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
7676                 m_multisampledCopyNoCabImage.get(),      // VkImage dstImage;
7677                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,    // VkImageLayout dstImageLayout;
7678                 (uint32_t)imageCopies2KHR.size(),        // uint32_t regionCount;
7679                 imageCopies2KHR.data()                   // const VkImageCopy2KHR* pRegions;
7680             };
7681             const VkCopyImageInfo2KHR copyImageInfo2KHRCopy = {
7682                 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,  // VkStructureType sType;
7683                 DE_NULL,                                  // const void* pNext;
7684                 m_multisampledCopyNoCabImage.get(),       // VkImage srcImage;
7685                 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
7686                 m_multisampledCopyImage.get(),            // VkImage dstImage;
7687                 m_params.dst.image.operationLayout,       // VkImageLayout dstImageLayout;
7688                 (uint32_t)imageCopies2KHR.size(),         // uint32_t regionCount;
7689                 imageCopies2KHR.data()                    // const VkImageCopy2KHR* pRegions;
7690             };
7691 
7692             vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7693             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7694                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7695                                   (const VkBufferMemoryBarrier *)DE_NULL, 1u, &betweenCopyImageBarrier);
7696             vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHRCopy);
7697         }
7698         else
7699         {
7700             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
7701             const VkCopyImageInfo2KHR copyImageInfo2KHR = {
7702                 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
7703                 DE_NULL,                                 // const void* pNext;
7704                 m_multisampledImage.get(),               // VkImage srcImage;
7705                 m_params.src.image.operationLayout,      // VkImageLayout srcImageLayout;
7706                 m_multisampledCopyImage.get(),           // VkImage dstImage;
7707                 m_params.dst.image.operationLayout,      // VkImageLayout dstImageLayout;
7708                 (uint32_t)imageCopies2KHR.size(),        // uint32_t regionCount;
7709                 imageCopies2KHR.data()                   // const VkImageCopy2KHR* pRegions;
7710             };
7711             vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7712         }
7713     }
7714 
7715     if (m_params.queueSelection != QueueSelectionOptions::Universal)
7716     {
7717         endCommandBuffer(vk, commandBuffer);
7718         submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7719         m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7720 
7721         VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7722             0u, 0u, m_params.src.image.operationLayout, m_params.src.image.operationLayout, m_multisampledImage.get(),
7723             m_multisampledImageBarrier.subresourceRange, familyIndex, m_context.getUniversalQueueFamilyIndex());
7724         // Release ownership from compute / transfer queue.
7725         {
7726             std::vector<VkImageMemoryBarrier> barriers;
7727             barriers.reserve(2);
7728 
7729             VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7730             releaseBarrier.dstAccessMask        = 0u; // dstAccessMask is ignored in ownership release operation.
7731             releaseBarrier.srcQueueFamilyIndex  = familyIndex;
7732             releaseBarrier.dstQueueFamilyIndex  = m_context.getUniversalQueueFamilyIndex();
7733             barriers.push_back(releaseBarrier);
7734 
7735             releaseBarrier               = srcImageBarrier;
7736             releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7737             releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7738             barriers.push_back(releaseBarrier);
7739 
7740             beginCommandBuffer(vk, commandBuffer);
7741             vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
7742                                   (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7743                                   (const VkBufferMemoryBarrier *)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7744             endCommandBuffer(vk, commandBuffer);
7745             submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7746             m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7747         }
7748 
7749         // Move ownership back to graphics queue.
7750         {
7751             std::vector<VkImageMemoryBarrier> barriers;
7752             barriers.reserve(2);
7753 
7754             VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7755             acquireBarrier.srcAccessMask        = 0u; // srcAccessMask is ignored in ownership acquire operation.
7756             acquireBarrier.srcQueueFamilyIndex  = familyIndex;
7757             acquireBarrier.dstQueueFamilyIndex  = m_context.getUniversalQueueFamilyIndex();
7758             barriers.push_back(acquireBarrier);
7759 
7760             acquireBarrier               = srcImageBarrier;
7761             acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7762             acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7763             barriers.push_back(acquireBarrier);
7764 
7765             beginCommandBuffer(vk, *m_universalCmdBuffer);
7766             vk.cmdPipelineBarrier(*m_universalCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
7767                                   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0,
7768                                   (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL,
7769                                   (uint32_t)barriers.size(), barriers.data());
7770             endCommandBuffer(vk, *m_universalCmdBuffer);
7771             submitCommandsAndWait(vk, vkDevice, m_universalQueue, *m_universalCmdBuffer);
7772             m_context.resetCommandPoolForVKSC(vkDevice, *m_universalCmdPool);
7773         }
7774     }
7775     else
7776     {
7777         vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
7778                               (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
7779                               (const VkBufferMemoryBarrier *)DE_NULL, 1u, &multisampledCopyImagePostBarrier);
7780         endCommandBuffer(vk, commandBuffer);
7781         submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7782         m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7783     }
7784 }
7785 
7786 class ResolveImageToImageTestCase : public vkt::TestCase
7787 {
7788 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7789     ResolveImageToImageTestCase(tcu::TestContext &testCtx, const std::string &name, const TestParams params,
7790                                 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION)
7791         : vkt::TestCase(testCtx, name)
7792         , m_params(params)
7793         , m_options(options)
7794     {
7795     }
7796 
7797     virtual void initPrograms(SourceCollections &programCollection) const;
7798 
createInstance(Context & context) const7799     virtual TestInstance *createInstance(Context &context) const
7800     {
7801         return new ResolveImageToImage(context, m_params, m_options);
7802     }
7803 
checkSupport(Context & context) const7804     virtual void checkSupport(Context &context) const
7805     {
7806         const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
7807 
7808         // Intermediate result check uses fragmentStoresAndAtomics.
7809         if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) &&
7810             !context.getDeviceFeatures().fragmentStoresAndAtomics)
7811         {
7812             TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7813         }
7814 
7815         if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7816             throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7817 
7818         VkImageFormatProperties properties;
7819         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
7820                  context.getPhysicalDevice(), m_params.src.image.format, m_params.src.image.imageType,
7821                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7822                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7823             (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
7824                  context.getPhysicalDevice(), m_params.dst.image.format, m_params.dst.image.imageType,
7825                  VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7826                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7827         {
7828             TCU_THROW(NotSupportedError, "Format not supported");
7829         }
7830 
7831         checkExtensionSupport(context, m_params.extensionFlags);
7832 
7833         // Find at least one queue family that supports compute queue but does NOT support graphics queue.
7834         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7835         {
7836             if (context.getComputeQueueFamilyIndex() == -1)
7837                 TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7838         }
7839 
7840         // Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7841         if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7842         {
7843             if (context.getTransferQueueFamilyIndex() == -1)
7844                 TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7845         }
7846     }
7847 
7848 private:
7849     TestParams m_params;
7850     const ResolveImageToImageOptions m_options;
7851 };
7852 
initPrograms(SourceCollections & programCollection) const7853 void ResolveImageToImageTestCase::initPrograms(SourceCollections &programCollection) const
7854 {
7855     programCollection.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
7856                                                                    "layout (location = 0) in highp vec4 a_position;\n"
7857                                                                    "void main()\n"
7858                                                                    "{\n"
7859                                                                    "    gl_Position = a_position;\n"
7860                                                                    "}\n");
7861 
7862     programCollection.glslSources.add("frag") << glu::FragmentSource("#version 310 es\n"
7863                                                                      "layout (location = 0) out highp vec4 o_color;\n"
7864                                                                      "void main()\n"
7865                                                                      "{\n"
7866                                                                      "    o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7867                                                                      "}\n");
7868 
7869     if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE ||
7870         m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION ||
7871         m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7872     {
7873         // The shader verifies all layers in the copied image are the same as the source image.
7874         // This needs an image view per layer in the copied image.
7875         // Set 0 contains the output buffer.
7876         // Set 1 contains the input attachments.
7877 
7878         std::ostringstream verificationShader;
7879 
7880         verificationShader
7881             << "#version 450\n"
7882             << "\n"
7883             << "layout (push_constant, std430) uniform PushConstants {\n"
7884             << "    int width;\n"
7885             << "    int height;\n"
7886             << "    int samples;\n"
7887             << "};\n"
7888             << "layout (set=0, binding=0) buffer VerificationResults {\n"
7889             << "    int verificationFlags[];\n"
7890             << "};\n"
7891             << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n";
7892 
7893         const auto dstLayers = getArraySize(m_params.dst.image);
7894 
7895         if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7896         {
7897             verificationShader
7898                 << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7899         }
7900         else
7901         {
7902             for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7903             {
7904                 const auto i = layerNdx + 1u;
7905                 verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i
7906                                    << ") uniform subpassInputMS attachment" << i << ";\n";
7907             }
7908         }
7909 
7910         // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7911         // created with a single sample.
7912         verificationShader << "\n"
7913                            << "void main() {\n"
7914                            << "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7915                            << "        vec4 orig = subpassLoad(attachment0, sampleID);\n";
7916 
7917         std::ostringstream testCondition;
7918         if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7919         {
7920             verificationShader << "        vec4 copy = subpassLoad(attachment1, sampleID);\n";
7921             testCondition << "orig == copy";
7922         }
7923         else
7924         {
7925             for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7926             {
7927                 const auto i = layerNdx + 1u;
7928                 verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7929             }
7930 
7931             for (uint32_t layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7932             {
7933                 const auto i = layerNdx + 1u;
7934                 testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7935             }
7936         }
7937 
7938         verificationShader << "\n"
7939                            << "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7940                            << "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7941                            << "\n"
7942                            << "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7943                            << "    }\n"
7944                            << "}\n";
7945 
7946         programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7947     }
7948 }
7949 
7950 class DepthStencilMSAA : public vkt::TestInstance
7951 {
7952 public:
7953     enum CopyOptions
7954     {
7955         COPY_WHOLE_IMAGE,
7956         COPY_ARRAY_TO_ARRAY,
7957         COPY_PARTIAL
7958     };
7959 
7960     struct TestParameters
7961     {
7962         AllocationKind allocationKind;
7963         uint32_t extensionFlags;
7964         CopyOptions copyOptions;
7965         VkSampleCountFlagBits samples;
7966         VkImageLayout srcImageLayout;
7967         VkImageLayout dstImageLayout;
7968         VkFormat imageFormat;
7969         VkImageAspectFlags copyAspect;
7970         bool imageOffset;
7971     };
7972 
7973     DepthStencilMSAA(Context &context, TestParameters testParameters);
7974     tcu::TestStatus iterate(void) override;
7975 
7976 protected:
7977     tcu::TestStatus checkCopyResults(VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits &aspectToVerify,
7978                                      VkImage srcImage, VkImage dstImage);
7979 
7980 private:
7981     // Returns image aspects used in the copy regions.
getUsedImageAspects()7982     VkImageAspectFlags getUsedImageAspects()
7983     {
7984         auto aspectFlags = (VkImageAspectFlags)0;
7985         for (const auto &region : m_regions)
7986         {
7987             aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7988         }
7989         return aspectFlags;
7990     }
7991 
7992     ImageParms m_srcImage;
7993     ImageParms m_dstImage;
7994     std::vector<CopyRegion> m_regions;
7995     const TestParameters m_params;
7996     const float m_clearValue = 0.0f;
7997 };
7998 
DepthStencilMSAA(Context & context,TestParameters testParameters)7999 DepthStencilMSAA::DepthStencilMSAA(Context &context, TestParameters testParameters)
8000     : vkt::TestInstance(context)
8001     , m_params(testParameters)
8002 {
8003     // params.src.image is the parameters used to create the copy source image
8004     m_srcImage.imageType       = VK_IMAGE_TYPE_2D;
8005     m_srcImage.format          = testParameters.imageFormat;
8006     m_srcImage.extent          = defaultExtent;
8007     m_srcImage.tiling          = VK_IMAGE_TILING_OPTIMAL;
8008     m_srcImage.operationLayout = testParameters.srcImageLayout;
8009     m_srcImage.createFlags     = 0u;
8010 
8011     // params.src.image is the parameters used to create the copy destination image
8012     m_dstImage.imageType       = VK_IMAGE_TYPE_2D;
8013     m_dstImage.format          = testParameters.imageFormat;
8014     m_dstImage.extent          = defaultExtent;
8015     m_dstImage.tiling          = VK_IMAGE_TILING_OPTIMAL;
8016     m_dstImage.operationLayout = testParameters.dstImageLayout;
8017     m_dstImage.createFlags     = 0u;
8018 
8019     const VkImageSubresourceLayers depthSubresourceLayers = {
8020         VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
8021         0u,                        // uint32_t mipLevel;
8022         0u,                        // uint32_t baseArrayLayer;
8023         1u                         // uint32_t layerCount;
8024     };
8025 
8026     const VkImageSubresourceLayers stencilSubresourceLayers = {
8027         VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
8028         0u,                          // uint32_t mipLevel;
8029         0u,                          // uint32_t baseArrayLayer;
8030         1u                           // uint32_t layerCount;
8031     };
8032 
8033     VkImageCopy depthCopy = {
8034         depthSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
8035         {0, 0, 0},              // VkOffset3D srcOffset;
8036         depthSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
8037         {0, 0, 0},              // VkOffset3D dstOffset;
8038         defaultExtent,          // VkExtent3D extent;
8039     };
8040 
8041     VkImageCopy stencilCopy = {
8042         stencilSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
8043         {0, 0, 0},                // VkOffset3D srcOffset;
8044         stencilSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
8045         {0, 0, 0},                // VkOffset3D dstOffset;
8046         defaultExtent,            // VkExtent3D extent;
8047     };
8048 
8049     if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8050     {
8051         m_srcImage.extent.depth                   = 5u;
8052         depthCopy.srcSubresource.baseArrayLayer   = 2u;
8053         depthCopy.dstSubresource.baseArrayLayer   = 3u;
8054         stencilCopy.srcSubresource.baseArrayLayer = 2u;
8055         stencilCopy.dstSubresource.baseArrayLayer = 3u;
8056     }
8057 
8058     CopyRegion depthCopyRegion;
8059     CopyRegion stencilCopyRegion;
8060     depthCopyRegion.imageCopy   = depthCopy;
8061     stencilCopyRegion.imageCopy = stencilCopy;
8062 
8063     std::vector<CopyRegion> depthRegions;
8064     std::vector<CopyRegion> stencilRegions;
8065 
8066     if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
8067     {
8068         if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8069         {
8070             depthCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
8071             // Copy region from bottom right to bottom left
8072             depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
8073             depthCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
8074             depthRegions.push_back(depthCopyRegion);
8075             // Copy region from top right to bottom right
8076             depthCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
8077             depthCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
8078             depthRegions.push_back(depthCopyRegion);
8079         }
8080         if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8081         {
8082             stencilCopyRegion.imageCopy.extent = {defaultHalfSize, defaultHalfSize, 1};
8083             // Copy region from bottom right to bottom left
8084             stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, defaultHalfSize, 0};
8085             stencilCopyRegion.imageCopy.dstOffset = {0, defaultHalfSize, 0};
8086             stencilRegions.push_back(stencilCopyRegion);
8087             // Copy region from top right to bottom right
8088             stencilCopyRegion.imageCopy.srcOffset = {defaultHalfSize, 0, 0};
8089             stencilCopyRegion.imageCopy.dstOffset = {defaultHalfSize, defaultHalfSize, 0};
8090             stencilRegions.push_back(stencilCopyRegion);
8091         }
8092     }
8093     else
8094     {
8095         // Copy the default region (full image)
8096         if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8097         {
8098             depthRegions.push_back(depthCopyRegion);
8099         }
8100         if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8101         {
8102             stencilRegions.push_back(stencilCopyRegion);
8103         }
8104     }
8105 
8106     if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8107     {
8108         m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
8109     }
8110 
8111     if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8112     {
8113         m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
8114     }
8115 }
8116 
iterate(void)8117 tcu::TestStatus DepthStencilMSAA::iterate(void)
8118 {
8119     const DeviceInterface &vk           = m_context.getDeviceInterface();
8120     const InstanceInterface &vki        = m_context.getInstanceInterface();
8121     const VkDevice vkDevice             = m_context.getDevice();
8122     const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
8123     const VkQueue queue                 = m_context.getUniversalQueue();
8124     const uint32_t queueFamilyIndex     = m_context.getUniversalQueueFamilyIndex();
8125     Allocator &memAlloc                 = m_context.getDefaultAllocator();
8126     Move<VkCommandPool> cmdPool =
8127         createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
8128     Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8129 
8130     const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_srcImage.format);
8131     const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_dstImage.format);
8132     VkImageAspectFlags aspectFlags        = getUsedImageAspects();
8133     uint32_t sourceArraySize              = getArraySize(m_srcImage);
8134 
8135     Move<VkImage> srcImage;
8136     de::MovePtr<Allocation> srcImageAlloc;
8137     Move<VkImage> dstImage;
8138     de::MovePtr<Allocation> dstImageAlloc;
8139 
8140     // 1. Create the images and draw a triangle to the source image.
8141     {
8142         const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
8143                                                          VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
8144         Move<VkShaderModule> vertexShaderModule =
8145             createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
8146         Move<VkShaderModule> fragmentShaderModule =
8147             createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
8148         std::vector<tcu::Vec4> vertices;
8149         Move<VkBuffer> vertexBuffer;
8150         de::MovePtr<Allocation> vertexBufferAlloc;
8151         Move<VkPipelineLayout> pipelineLayout;
8152         Move<VkPipeline> graphicsPipeline;
8153         Move<VkRenderPass> renderPass;
8154 
8155         // Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
8156         {
8157             VkImageCreateInfo multiSampledImageParams = {
8158                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        // VkStructureType sType;
8159                 DE_NULL,                                    // const void* pNext;
8160                 getCreateFlags(m_srcImage),                 // VkImageCreateFlags flags;
8161                 m_srcImage.imageType,                       // VkImageType imageType;
8162                 m_srcImage.format,                          // VkFormat format;
8163                 getExtent3D(m_srcImage),                    // VkExtent3D extent;
8164                 1u,                                         // uint32_t mipLevels;
8165                 getArraySize(m_srcImage),                   // uint32_t arrayLayers;
8166                 m_params.samples,                           // VkSampleCountFlagBits samples;
8167                 VK_IMAGE_TILING_OPTIMAL,                    // VkImageTiling tiling;
8168                 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT // VkImageUsageFlags usage;
8169                     | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL |
8170                     VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
8171                 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
8172                 1u,                        // uint32_t queueFamilyIndexCount;
8173                 &queueFamilyIndex,         // const uint32_t* pQueueFamilyIndices;
8174                 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
8175             };
8176 
8177             srcImage = createImage(vk, vkDevice, &multiSampledImageParams);
8178 
8179             VkMemoryRequirements req = getImageMemoryRequirements(vk, vkDevice, *srcImage);
8180             uint32_t offset          = m_params.imageOffset ? static_cast<uint32_t>(req.alignment) : 0;
8181 
8182             srcImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any,
8183                                           memAlloc, m_params.allocationKind, offset);
8184             VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(),
8185                                         srcImageAlloc->getOffset() + offset));
8186 
8187             dstImage      = createImage(vk, vkDevice, &multiSampledImageParams);
8188             dstImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any,
8189                                           memAlloc, m_params.allocationKind, 0u);
8190             VK_CHECK(
8191                 vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
8192         }
8193 
8194         // Create render pass.
8195         {
8196             const VkImageLayout initialLayout                   = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ?
8197                                                                       VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
8198                                                                       VK_IMAGE_LAYOUT_UNDEFINED;
8199             const VkAttachmentDescription attachmentDescription = {
8200                 0u,                                              // VkAttachmentDescriptionFlags        flags
8201                 m_srcImage.format,                               // VkFormat                            format
8202                 m_params.samples,                                // VkSampleCountFlagBits            samples
8203                 VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp                loadOp
8204                 VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp                storeOp
8205                 VK_ATTACHMENT_LOAD_OP_CLEAR,                     // VkAttachmentLoadOp                stencilLoadOp
8206                 VK_ATTACHMENT_STORE_OP_STORE,                    // VkAttachmentStoreOp                stencilStoreOp
8207                 initialLayout,                                   // VkImageLayout                    initialLayout
8208                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout                    finalLayout
8209             };
8210 
8211             const VkAttachmentReference attachmentReference = {
8212                 0u,                                              // uint32_t            attachment
8213                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout    layout
8214             };
8215 
8216             const VkSubpassDescription subpassDescription = {
8217                 0u,                              // VkSubpassDescriptionFlags    flags
8218                 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint            pipelineBindPoint
8219                 0u,                              // uint32_t                        inputAttachmentCount
8220                 DE_NULL,                         // const VkAttachmentReference*    pInputAttachments
8221                 0u,                              // uint32_t                        colorAttachmentCount
8222                 DE_NULL,                         // const VkAttachmentReference*    pColorAttachments
8223                 DE_NULL,                         // const VkAttachmentReference*    pResolveAttachments
8224                 &attachmentReference,            // const VkAttachmentReference*    pDepthStencilAttachment
8225                 0u,                              // uint32_t                        preserveAttachmentCount
8226                 DE_NULL                          // const VkAttachmentReference*    pPreserveAttachments
8227             };
8228 
8229             const VkRenderPassCreateInfo renderPassParams = {
8230                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
8231                 DE_NULL,                                   // const void* pNext;
8232                 0u,                                        // VkRenderPassCreateFlags flags;
8233                 1u,                                        // uint32_t attachmentCount;
8234                 &attachmentDescription,                    // const VkAttachmentDescription* pAttachments;
8235                 1u,                                        // uint32_t subpassCount;
8236                 &subpassDescription,                       // const VkSubpassDescription* pSubpasses;
8237                 0u,                                        // uint32_t dependencyCount;
8238                 DE_NULL                                    // const VkSubpassDependency* pDependencies;
8239             };
8240 
8241             renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
8242         }
8243 
8244         // Create pipeline layout
8245         {
8246             const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
8247                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8248                 DE_NULL,                                       // const void* pNext;
8249                 0u,                                            // VkPipelineLayoutCreateFlags flags;
8250                 0u,                                            // uint32_t setLayoutCount;
8251                 DE_NULL,                                       // const VkDescriptorSetLayout* pSetLayouts;
8252                 0u,                                            // uint32_t pushConstantRangeCount;
8253                 DE_NULL                                        // const VkPushConstantRange* pPushConstantRanges;
8254             };
8255 
8256             pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
8257         }
8258 
8259         // Create upper half triangle.
8260         {
8261             // Add triangle.
8262             vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
8263             vertices.emplace_back(1.0f, -1.0f, 0.0f, 1.0f);
8264             vertices.emplace_back(1.0f, 1.0f, 0.0f, 1.0f);
8265         }
8266 
8267         // Create vertex buffer.
8268         {
8269             const VkDeviceSize vertexDataSize           = vertices.size() * sizeof(tcu::Vec4);
8270             const VkBufferCreateInfo vertexBufferParams = {
8271                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
8272                 DE_NULL,                              // const void* pNext;
8273                 0u,                                   // VkBufferCreateFlags flags;
8274                 vertexDataSize,                       // VkDeviceSize size;
8275                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
8276                 VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
8277                 1u,                                   // uint32_t queueFamilyIndexCount;
8278                 &queueFamilyIndex                     // const uint32_t* pQueueFamilyIndices;
8279             };
8280 
8281             vertexBuffer      = createBuffer(vk, vkDevice, &vertexBufferParams);
8282             vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer,
8283                                                MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
8284             VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(),
8285                                          vertexBufferAlloc->getOffset()));
8286 
8287             // Load vertices into vertex buffer.
8288             deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
8289             flushAlloc(vk, vkDevice, *vertexBufferAlloc);
8290         }
8291 
8292         {
8293             Move<VkFramebuffer> framebuffer;
8294             Move<VkImageView> sourceAttachmentView;
8295 
8296             // Create depth/stencil attachment view.
8297             {
8298                 const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8299                 const VkImageViewCreateInfo depthStencilAttachmentViewParams = {
8300                     VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
8301                     DE_NULL,                                  // const void* pNext;
8302                     0u,                                       // VkImageViewCreateFlags flags;
8303                     *srcImage,                                // VkImage image;
8304                     VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType viewType;
8305                     m_srcImage.format,                        // VkFormat format;
8306                     componentMappingRGBA,                     // VkComponentMapping components;
8307                     {aspectFlags, 0u, 1u, arrayLayer, 1u}     // VkImageSubresourceRange subresourceRange;
8308                 };
8309                 sourceAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
8310             }
8311 
8312             // Create framebuffer
8313             {
8314                 const VkFramebufferCreateInfo framebufferParams = {
8315                     VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
8316                     DE_NULL,                                   // const void* pNext;
8317                     0u,                                        // VkFramebufferCreateFlags flags;
8318                     *renderPass,                               // VkRenderPass renderPass;
8319                     1u,                                        // uint32_t attachmentCount;
8320                     &sourceAttachmentView.get(),               // const VkImageView* pAttachments;
8321                     m_srcImage.extent.width,                   // uint32_t width;
8322                     m_srcImage.extent.height,                  // uint32_t height;
8323                     1u                                         // uint32_t layers;
8324                 };
8325 
8326                 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
8327             }
8328 
8329             // Create pipeline
8330             {
8331                 const std::vector<VkViewport> viewports(1, makeViewport(m_srcImage.extent));
8332                 const std::vector<VkRect2D> scissors(1, makeRect2D(m_srcImage.extent));
8333 
8334                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
8335                     VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8336                     DE_NULL,                                                  // const void* pNext;
8337                     0u,               // VkPipelineMultisampleStateCreateFlags flags;
8338                     m_params.samples, // VkSampleCountFlagBits rasterizationSamples;
8339                     VK_FALSE,         // VkBool32 sampleShadingEnable;
8340                     0.0f,             // float minSampleShading;
8341                     DE_NULL,          // const VkSampleMask* pSampleMask;
8342                     VK_FALSE,         // VkBool32 alphaToCoverageEnable;
8343                     VK_FALSE          // VkBool32 alphaToOneEnable;
8344                 };
8345 
8346                 const VkStencilOpState stencilOpState = {
8347                     VK_STENCIL_OP_KEEP,    // VkStencilOp    failOp
8348                     VK_STENCIL_OP_REPLACE, // VkStencilOp    passOp
8349                     VK_STENCIL_OP_KEEP,    // VkStencilOp    depthFailOp
8350                     VK_COMPARE_OP_ALWAYS,  // VkCompareOp    compareOp
8351                     0,                     // uint32_t        compareMask
8352                     0xFF,                  // uint32_t        writeMask
8353                     0xFF                   // uint32_t        reference
8354                 };
8355 
8356                 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfoDefault = {
8357                     VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                            sType
8358                     DE_NULL, // const void*                                pNext
8359                     0u,      // VkPipelineDepthStencilStateCreateFlags    flags
8360                     aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ?
8361                         VK_TRUE :
8362                         VK_FALSE, // VkBool32                                    depthTestEnable
8363                     aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ?
8364                         VK_TRUE :
8365                         VK_FALSE,         // VkBool32                                    depthWriteEnable
8366                     VK_COMPARE_OP_ALWAYS, // VkCompareOp                                depthCompareOp
8367                     VK_FALSE,             // VkBool32                                    depthBoundsTestEnable
8368                     aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ?
8369                         VK_TRUE :
8370                         VK_FALSE,   // VkBool32                                    stencilTestEnable
8371                     stencilOpState, // VkStencilOpState                            front
8372                     stencilOpState, // VkStencilOpState                            back
8373                     0.0f,           // float                                    minDepthBounds
8374                     1.0f,           // float                                    maxDepthBounds
8375                 };
8376 
8377                 graphicsPipeline = makeGraphicsPipeline(
8378                     vk,                  // const DeviceInterface&                            vk
8379                     vkDevice,            // const VkDevice                                    device
8380                     *pipelineLayout,     // const VkPipelineLayout                            pipelineLayout
8381                     *vertexShaderModule, // const VkShaderModule                                vertexShaderModule
8382                     DE_NULL, // const VkShaderModule                                tessellationControlModule
8383                     DE_NULL, // const VkShaderModule                                tessellationEvalModule
8384                     DE_NULL, // const VkShaderModule                                geometryShaderModule
8385                     *fragmentShaderModule, // const VkShaderModule                                fragmentShaderModule
8386                     *renderPass,           // const VkRenderPass                                renderPass
8387                     viewports,             // const std::vector<VkViewport>&                    viewports
8388                     scissors,              // const std::vector<VkRect2D>&                        scissors
8389                     VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                        topology
8390                     0u,                                  // const uint32_t                                    subpass
8391                     0u,      // const uint32_t                                    patchControlPoints
8392                     DE_NULL, // const VkPipelineVertexInputStateCreateInfo*        vertexInputStateCreateInfo
8393                     DE_NULL, // const VkPipelineRasterizationStateCreateInfo*    rasterizationStateCreateInfo
8394                     &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
8395                     &depthStencilStateCreateInfoDefault); // const VkPipelineDepthStencilStateCreateInfo*        depthStencilStateCreateInfo
8396             }
8397 
8398             // Create command buffer
8399             {
8400                 beginCommandBuffer(vk, *cmdBuffer, 0u);
8401 
8402                 const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
8403 
8404                 // Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
8405                 const VkClearValue copiedImageClearValue =
8406                     makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
8407                 const auto subResourceRange = makeImageSubresourceRange( // VkImageSubresourceRange    subresourceRange
8408                     (getAspectFlags(m_srcImage.format)),                 // VkImageAspectFlags        aspectMask
8409                     0u,                                                  // uint32_t                    baseMipLevel
8410                     1u,                                                  // uint32_t                    levelCount
8411                     0u,                                                  // uint32_t                    baseArrayLayer
8412                     getArraySize(m_srcImage));
8413 
8414                 const VkImageMemoryBarrier preClearBarrier =
8415                     makeImageMemoryBarrier(0u,                           // VkAccessFlags            srcAccessMask
8416                                            VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags            dstAccessMask
8417                                            VK_IMAGE_LAYOUT_UNDEFINED,    // VkImageLayout            oldLayout
8418                                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout            newLayout
8419                                            srcImage.get(),                       // VkImage                    image
8420                                            subResourceRange); // VkImageSubresourceRange    subresourceRange
8421                 std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
8422                 preClearBarriers[1].image = dstImage.get();
8423                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
8424                                       (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
8425                                       (const VkBufferMemoryBarrier *)DE_NULL, 2, preClearBarriers.data());
8426 
8427                 vk.cmdClearDepthStencilImage(
8428                     *cmdBuffer,                           // VkCommandBuffer                    commandBuffer
8429                     srcImage.get(),                       // VkImage                            image
8430                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout                    imageLayout
8431                     &srcImageClearValue.depthStencil,     // const VkClearDepthStencilValue*    pDepthStencil
8432                     1u,                                   // uint32_t                            rangeCount
8433                     &subResourceRange);                   // const VkImageSubresourceRange*    pRanges
8434 
8435                 vk.cmdClearDepthStencilImage(
8436                     *cmdBuffer,                           // VkCommandBuffer                    commandBuffer
8437                     dstImage.get(),                       // VkImage                            image
8438                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout                    imageLayout
8439                     &copiedImageClearValue.depthStencil,  // const VkClearDepthStencilValue*    pDepthStencil
8440                     1u,                                   // uint32_t                            rangeCount
8441                     &subResourceRange);                   // const VkImageSubresourceRange*    pRanges
8442 
8443                 // Post clear barrier
8444                 const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
8445                     VK_ACCESS_TRANSFER_WRITE_BIT,                     // VkAccessFlags            srcAccessMask
8446                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,     // VkAccessFlags            dstAccessMask
8447                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,             // VkImageLayout            oldLayout
8448                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout            newLayout
8449                     srcImage.get(),                                   // VkImage                    image
8450                     subResourceRange);                                // VkImageSubresourceRange    subresourceRange
8451 
8452                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
8453                                       VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, (VkDependencyFlags)0, 0,
8454                                       (const VkMemoryBarrier *)DE_NULL, 0, (const VkBufferMemoryBarrier *)DE_NULL, 1,
8455                                       &postClearBarrier);
8456 
8457                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer,
8458                                 makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u,
8459                                 &srcImageClearValue);
8460 
8461                 const VkDeviceSize vertexBufferOffset = 0u;
8462 
8463                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
8464                 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
8465                 vk.cmdDraw(*cmdBuffer, (uint32_t)vertices.size(), 1, 0, 0);
8466 
8467                 endRenderPass(vk, *cmdBuffer);
8468                 endCommandBuffer(vk, *cmdBuffer);
8469             }
8470 
8471             submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
8472             m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
8473         }
8474     }
8475 
8476     // 2. Record a command buffer that contains the copy operation(s).
8477     beginCommandBuffer(vk, *cmdBuffer);
8478     {
8479         // Change the image layouts and synchronize the memory access before copying
8480         {
8481             const VkImageMemoryBarrier imageBarriers[] = {
8482                 // srcImage
8483                 makeImageMemoryBarrier(
8484                     VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,     // VkAccessFlags            srcAccessMask
8485                     VK_ACCESS_TRANSFER_READ_BIT,                      // VkAccessFlags            dstAccessMask
8486                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout            oldLayout
8487                     m_srcImage.operationLayout,                       // VkImageLayout            newLayout
8488                     srcImage.get(),                                   // VkImage                    image
8489                     makeImageSubresourceRange(                        // VkImageSubresourceRange    subresourceRange
8490                         getAspectFlags(srcTcuFormat),                 // VkImageAspectFlags    aspectMask
8491                         0u,                                           // uint32_t                baseMipLevel
8492                         1u,                                           // uint32_t                levelCount
8493                         0u,                                           // uint32_t                baseArrayLayer
8494                         sourceArraySize                               // uint32_t                layerCount
8495                         )),
8496                 // dstImage
8497                 makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT,         // VkAccessFlags            srcAccessMask
8498                                        VK_ACCESS_TRANSFER_WRITE_BIT,         // VkAccessFlags            dstAccessMask
8499                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout            oldLayout
8500                                        m_dstImage.operationLayout,           // VkImageLayout            newLayout
8501                                        dstImage.get(),                       // VkImage                    image
8502                                        makeImageSubresourceRange(        // VkImageSubresourceRange    subresourceRange
8503                                            getAspectFlags(dstTcuFormat), // VkImageAspectFlags    aspectMask
8504                                            0u,                           // uint32_t                baseMipLevel
8505                                            1u,                           // uint32_t                levelCount
8506                                            0u,                           // uint32_t                baseArrayLayer
8507                                            sourceArraySize               // uint32_t                layerCount
8508                                            )),
8509             };
8510             vk.cmdPipelineBarrier(
8511                 *cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT,
8512                 VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
8513                 (const VkBufferMemoryBarrier *)DE_NULL, 2u, imageBarriers);
8514         }
8515 
8516         std::vector<VkImageCopy> imageCopies;
8517         std::vector<VkImageCopy2KHR> imageCopies2KHR;
8518         for (const auto &region : m_regions)
8519         {
8520             if (!(m_params.extensionFlags & COPY_COMMANDS_2))
8521             {
8522                 imageCopies.push_back(region.imageCopy);
8523             }
8524             else
8525             {
8526                 DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
8527                 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
8528             }
8529         }
8530 
8531         if (!(m_params.extensionFlags & COPY_COMMANDS_2))
8532         {
8533             vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(),
8534                             m_dstImage.operationLayout, (uint32_t)imageCopies.size(), imageCopies.data());
8535         }
8536         else
8537         {
8538             DE_ASSERT(m_params.extensionFlags & COPY_COMMANDS_2);
8539             const VkCopyImageInfo2KHR copyImageInfo2KHR = {
8540                 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
8541                 DE_NULL,                                 // const void* pNext;
8542                 srcImage.get(),                          // VkImage srcImage;
8543                 m_srcImage.operationLayout,              // VkImageLayout srcImageLayout;
8544                 dstImage.get(),                          // VkImage dstImage;
8545                 m_dstImage.operationLayout,              // VkImageLayout dstImageLayout;
8546                 (uint32_t)imageCopies2KHR.size(),        // uint32_t regionCount;
8547                 imageCopies2KHR.data()                   // const VkImageCopy2KHR* pRegions;
8548             };
8549 
8550             vk.cmdCopyImage2(*cmdBuffer, &copyImageInfo2KHR);
8551         }
8552     }
8553     endCommandBuffer(vk, *cmdBuffer);
8554     submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
8555     m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
8556 
8557     // Verify that all samples have been copied properly from all aspects.
8558     const auto usedImageAspects = getUsedImageAspects();
8559     if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
8560     {
8561         auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
8562         if (copyResult.getCode() != QP_TEST_RESULT_PASS)
8563             return copyResult;
8564     }
8565     if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
8566     {
8567         auto copyResult =
8568             checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
8569         if (copyResult.getCode() != QP_TEST_RESULT_PASS)
8570             return copyResult;
8571     }
8572     return tcu::TestStatus::pass("pass");
8573 }
8574 
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)8575 tcu::TestStatus DepthStencilMSAA::checkCopyResults(VkCommandBuffer cmdBuffer,
8576                                                    const VkImageAspectFlagBits &aspectToVerify, VkImage srcImage,
8577                                                    VkImage dstImage)
8578 {
8579     DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
8580 
8581     const auto &vkd                = m_context.getDeviceInterface();
8582     const auto device              = m_context.getDevice();
8583     const auto queue               = m_context.getUniversalQueue();
8584     auto &alloc                    = m_context.getDefaultAllocator();
8585     const auto layerCount          = getArraySize(m_srcImage);
8586     const auto numInputAttachments = layerCount + 1u; // +1 for the source image.
8587     const auto numOutputBuffers    = 2u;              // 1 for the reference and 1 for the copied values.
8588     const auto numSets             = 2u;              // 1 for the output buffers, 1 for the input attachments.
8589     const auto fbWidth             = m_srcImage.extent.width;
8590     const auto fbHeight            = m_srcImage.extent.height;
8591     const auto aspectFlags         = getUsedImageAspects();
8592 
8593     // Shader modules.
8594     const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
8595     const auto verificationModule =
8596         createShaderModule(vkd, device,
8597                            m_context.getBinaryCollection().get(
8598                                aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"),
8599                            0u);
8600 
8601     // Descriptor sets.
8602     DescriptorPoolBuilder poolBuilder;
8603     poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
8604     poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
8605     const auto descriptorPool =
8606         poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
8607 
8608     DescriptorSetLayoutBuilder layoutBuilderBuffer;
8609     layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
8610     layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
8611     const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
8612 
8613     DescriptorSetLayoutBuilder layoutBuilderAttachments;
8614     for (uint32_t i = 0u; i < numInputAttachments; ++i)
8615         layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
8616     const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
8617 
8618     const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
8619     const auto descriptorSetAttachments =
8620         makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
8621 
8622     // Array with raw descriptor sets.
8623     const std::array<VkDescriptorSet, numSets> descriptorSets = {{
8624         descriptorSetBuffer.get(),
8625         descriptorSetAttachments.get(),
8626     }};
8627 
8628     // Pipeline layout.
8629     const std::array<VkDescriptorSetLayout, numSets> setLayouts = {{
8630         outputBufferSetLayout.get(),
8631         inputAttachmentsSetLayout.get(),
8632     }};
8633 
8634     // Push constants.
8635     std::array<int, 3> pushConstantData = {{
8636         static_cast<int>(fbWidth),
8637         static_cast<int>(fbHeight),
8638         static_cast<int>(m_params.samples),
8639     }};
8640 
8641     const auto pushConstantSize =
8642         static_cast<uint32_t>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
8643 
8644     const VkPushConstantRange pushConstantRange = {
8645         VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
8646         0u,                           // uint32_t offset;
8647         pushConstantSize,             // uint32_t size;
8648     };
8649 
8650     const VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
8651         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
8652         nullptr,                                       // const void* pNext;
8653         0u,                                            // VkPipelineLayoutCreateFlags flags;
8654         static_cast<uint32_t>(setLayouts.size()),      // uint32_t setLayoutCount;
8655         setLayouts.data(),                             // const VkDescriptorSetLayout* pSetLayouts;
8656         1u,                                            // uint32_t pushConstantRangeCount;
8657         &pushConstantRange,                            // const VkPushConstantRange* pPushConstantRanges;
8658     };
8659 
8660     const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8661 
8662     // Render pass.
8663     const VkAttachmentDescription commonAttachmentDescription = {
8664         0u,                                   // VkAttachmentDescriptionFlags flags;
8665         m_srcImage.format,                    // VkFormat format;
8666         m_params.samples,                     // VkSampleCountFlagBits samples;
8667         VK_ATTACHMENT_LOAD_OP_LOAD,           // VkAttachmentLoadOp loadOp;
8668         VK_ATTACHMENT_STORE_OP_STORE,         // VkAttachmentStoreOp storeOp;
8669         VK_ATTACHMENT_LOAD_OP_DONT_CARE,      // VkAttachmentLoadOp stencilLoadOp;
8670         VK_ATTACHMENT_STORE_OP_DONT_CARE,     // VkAttachmentStoreOp stencilStoreOp;
8671         m_dstImage.operationLayout,           // VkImageLayout initialLayout;
8672         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout finalLayout;
8673     };
8674 
8675     std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8676     // Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8677     attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8678 
8679     std::vector<VkAttachmentReference> inputAttachmentReferences;
8680     inputAttachmentReferences.reserve(numInputAttachments);
8681     for (uint32_t i = 0u; i < numInputAttachments; ++i)
8682     {
8683         const VkAttachmentReference reference = {i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL};
8684         inputAttachmentReferences.push_back(reference);
8685     }
8686 
8687     const VkSubpassDescription subpassDescription = {
8688         0u,                                                      // VkSubpassDescriptionFlags flags;
8689         VK_PIPELINE_BIND_POINT_GRAPHICS,                         // VkPipelineBindPoint pipelineBindPoint;
8690         static_cast<uint32_t>(inputAttachmentReferences.size()), // uint32_t inputAttachmentCount;
8691         inputAttachmentReferences.data(),                        // const VkAttachmentReference* pInputAttachments;
8692         0u,                                                      // uint32_t colorAttachmentCount;
8693         nullptr,                                                 // const VkAttachmentReference* pColorAttachments;
8694         nullptr,                                                 // const VkAttachmentReference* pResolveAttachments;
8695         nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
8696         0u,      // uint32_t preserveAttachmentCount;
8697         nullptr, // const uint32_t* pPreserveAttachments;
8698     };
8699 
8700     const VkRenderPassCreateInfo renderPassInfo = {
8701         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,            // VkStructureType sType;
8702         nullptr,                                              // const void* pNext;
8703         0u,                                                   // VkRenderPassCreateFlags flags;
8704         static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount;
8705         attachmentDescriptions.data(),                        // const VkAttachmentDescription* pAttachments;
8706         1u,                                                   // uint32_t subpassCount;
8707         &subpassDescription,                                  // const VkSubpassDescription* pSubpasses;
8708         0u,                                                   // uint32_t dependencyCount;
8709         nullptr,                                              // const VkSubpassDependency* pDependencies;
8710     };
8711 
8712     const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
8713 
8714     // Framebuffer.
8715     std::vector<Move<VkImageView>> imageViews;
8716     std::vector<VkImageView> imageViewsRaw;
8717 
8718     const uint32_t srcArrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8719     imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format,
8720                                        makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8721     for (uint32_t i = 0u; i < layerCount; ++i)
8722     {
8723         const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8724         imageViews.push_back(
8725             makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8726     }
8727 
8728     imageViewsRaw.reserve(imageViews.size());
8729     std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw),
8730                    [](const Move<VkImageView> &ptr) { return ptr.get(); });
8731 
8732     const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<uint32_t>(imageViewsRaw.size()),
8733                                              imageViewsRaw.data(), fbWidth, fbHeight);
8734 
8735     // Create storage buffers for both original and copied multisampled depth/stencil images.
8736     const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8737     const auto bufferSize  = static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8738     BufferWithMemory bufferOriginal(vkd, device, alloc,
8739                                     makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
8740                                     MemoryRequirement::HostVisible);
8741     BufferWithMemory bufferCopied(vkd, device, alloc,
8742                                   makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
8743                                   MemoryRequirement::HostVisible);
8744     auto &bufferOriginalAlloc = bufferOriginal.getAllocation();
8745     auto &bufferCopiedAlloc   = bufferCopied.getAllocation();
8746 
8747     // Update descriptor sets.
8748     DescriptorSetUpdateBuilder updater;
8749 
8750     const auto bufferOriginalInfo = makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8751     const auto bufferCopiedInfo   = makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8752     updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u),
8753                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8754     updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u),
8755                         VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8756 
8757     std::vector<VkDescriptorImageInfo> imageInfos;
8758     imageInfos.reserve(imageViewsRaw.size());
8759     for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8760     {
8761         imageInfos.push_back(
8762             makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8763         updater.writeSingle(descriptorSetAttachments.get(),
8764                             DescriptorSetUpdateBuilder::Location::binding(static_cast<uint32_t>(i)),
8765                             VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8766     }
8767 
8768     updater.update(vkd, device);
8769 
8770     // Vertex buffer.
8771     std::vector<tcu::Vec4> fullScreenQuad;
8772     {
8773         // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8774         const tcu::Vec4 topLeft(-1.0f, -1.0f, 0.0f, 1.0f);
8775         const tcu::Vec4 topRight(1.0f, -1.0f, 0.0f, 1.0f);
8776         const tcu::Vec4 bottomLeft(-1.0f, 1.0f, 0.0f, 1.0f);
8777         const tcu::Vec4 bottomRight(1.0f, 1.0f, 0.0f, 1.0f);
8778 
8779         fullScreenQuad.reserve(6u);
8780         fullScreenQuad.push_back(topLeft);
8781         fullScreenQuad.push_back(topRight);
8782         fullScreenQuad.push_back(bottomRight);
8783         fullScreenQuad.push_back(topLeft);
8784         fullScreenQuad.push_back(bottomRight);
8785         fullScreenQuad.push_back(bottomLeft);
8786     }
8787 
8788     const auto vertexBufferSize =
8789         static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8790     const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8791     const BufferWithMemory vertexBuffer(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8792     const VkDeviceSize vertexBufferOffset = 0ull;
8793 
8794     deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8795     flushAlloc(vkd, device, vertexBuffer.getAllocation());
8796 
8797     // Graphics pipeline.
8798     const std::vector<VkViewport> viewports(1, makeViewport(m_srcImage.extent));
8799     const std::vector<VkRect2D> scissors(1, makeRect2D(m_srcImage.extent));
8800 
8801     const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
8802         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
8803         nullptr,                                                  // const void* pNext;
8804         0u,                                                       // VkPipelineMultisampleStateCreateFlags flags;
8805         VK_SAMPLE_COUNT_1_BIT,                                    // VkSampleCountFlagBits rasterizationSamples;
8806         VK_FALSE,                                                 // VkBool32 sampleShadingEnable;
8807         0.0f,                                                     // float minSampleShading;
8808         nullptr,                                                  // const VkSampleMask* pSampleMask;
8809         VK_FALSE,                                                 // VkBool32 alphaToCoverageEnable;
8810         VK_FALSE                                                  // VkBool32 alphaToOneEnable;
8811     };
8812 
8813     const auto graphicsPipeline = makeGraphicsPipeline(
8814         vkd,                      // const DeviceInterface&                            vk
8815         device,                   // const VkDevice                                    device
8816         pipelineLayout.get(),     // const VkPipelineLayout                            pipelineLayout
8817         vertexModule.get(),       // const VkShaderModule                                vertexShaderModule
8818         DE_NULL,                  // const VkShaderModule                                tessellationControlModule
8819         DE_NULL,                  // const VkShaderModule                                tessellationEvalModule
8820         DE_NULL,                  // const VkShaderModule                                geometryShaderModule
8821         verificationModule.get(), // const VkShaderModule                                fragmentShaderModule
8822         renderPass.get(),         // const VkRenderPass                                renderPass
8823         viewports,                // const std::vector<VkViewport>&                    viewports
8824         scissors,                 // const std::vector<VkRect2D>&                        scissors
8825         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                        topology
8826         0u,                                  // const uint32_t                                    subpass
8827         0u,                                  // const uint32_t                                    patchControlPoints
8828         nullptr,                  // const VkPipelineVertexInputStateCreateInfo*        vertexInputStateCreateInfo
8829         nullptr,                  // const VkPipelineRasterizationStateCreateInfo*    rasterizationStateCreateInfo
8830         &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
8831 
8832     // Make sure multisample copy data is available to the fragment shader.
8833     const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8834 
8835     // Record and submit command buffer.
8836     beginCommandBuffer(vkd, cmdBuffer);
8837     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u,
8838                            &imagesBarrier, 0u, nullptr, 0u, nullptr);
8839     beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8840     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8841     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8842 
8843     vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize,
8844                          pushConstantData.data());
8845     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u,
8846                               static_cast<uint32_t>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8847     vkd.cmdDraw(cmdBuffer, static_cast<uint32_t>(fullScreenQuad.size()), 1u, 0u, 0u);
8848 
8849     endRenderPass(vkd, cmdBuffer);
8850 
8851     // Make sure verification buffer data is available on the host.
8852     const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8853     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u,
8854                            &bufferBarrier, 0u, nullptr, 0u, nullptr);
8855     endCommandBuffer(vkd, cmdBuffer);
8856     submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8857 
8858     // Verify intermediate results.
8859     invalidateAlloc(vkd, device, bufferOriginalAlloc);
8860     invalidateAlloc(vkd, device, bufferCopiedAlloc);
8861     std::vector<float> outputOriginal(bufferCount, 0);
8862     std::vector<float> outputCopied(bufferCount, 0);
8863     deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8864     deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8865 
8866     auto &log = m_context.getTestContext().getLog();
8867     log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8868 
8869     const auto sampleCount = static_cast<uint32_t>(m_params.samples);
8870 
8871     // Verify copied region(s)
8872     for (const auto &region : m_regions)
8873     {
8874         for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8875             for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8876                 for (uint32_t s = 0u; s < sampleCount; ++s)
8877                 {
8878                     tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8879                     tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8880                     const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8881                     const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8882                     if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8883                     {
8884                         std::ostringstream msg;
8885                         msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample "
8886                             << s << ". "
8887                             << "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8888                         return tcu::TestStatus::fail(msg.str());
8889                     }
8890                 }
8891     }
8892 
8893     if (m_params.copyOptions == COPY_PARTIAL)
8894     {
8895         // In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8896         // Verify that the upper half of the image is left at it's clear value (0).
8897         for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8898             for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8899                 for (uint32_t s = 0u; s < sampleCount; ++s)
8900                 {
8901                     const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8902                     if (outputCopied[bufferIndex] != m_clearValue)
8903                     {
8904                         std::ostringstream msg;
8905                         msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample "
8906                             << s << ". "
8907                             << "result: " << outputCopied[bufferIndex] << " expected: 0.0";
8908                         return tcu::TestStatus::fail(msg.str());
8909                     }
8910                 }
8911     }
8912 
8913     log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8914     return tcu::TestStatus::pass("Pass");
8915 }
8916 
8917 class DepthStencilMSAATestCase : public vkt::TestCase
8918 {
8919 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const DepthStencilMSAA::TestParameters testParams)8920     DepthStencilMSAATestCase(tcu::TestContext &testCtx, const std::string &name,
8921                              const DepthStencilMSAA::TestParameters testParams)
8922         : vkt::TestCase(testCtx, name)
8923         , m_params(testParams)
8924     {
8925     }
8926 
8927     virtual void initPrograms(SourceCollections &programCollection) const;
8928 
createInstance(Context & context) const8929     virtual TestInstance *createInstance(Context &context) const
8930     {
8931         return new DepthStencilMSAA(context, m_params);
8932     }
8933 
checkSupport(Context & context) const8934     virtual void checkSupport(Context &context) const
8935     {
8936         checkExtensionSupport(context, m_params.extensionFlags);
8937 
8938         const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8939 
8940         if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8941             TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8942 
8943         if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) &&
8944             !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8945             TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8946 
8947         if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) &&
8948             !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8949             TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8950 
8951         VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
8952                                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8953 
8954         VkImageFormatProperties properties;
8955         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
8956                  context.getPhysicalDevice(), m_params.imageFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
8957                  usageFlags, 0, &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8958         {
8959             TCU_THROW(NotSupportedError, "Format not supported");
8960         }
8961     }
8962 
8963 private:
getArrayLayerCount() const8964     uint32_t getArrayLayerCount() const
8965     {
8966         return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8967     }
8968 
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8969     void createVerificationShader(std::ostringstream &shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8970     {
8971         DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8972         // The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8973         // CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8974         // and the rest should be filled with the clear value (0). This is also verified in this shader.
8975         // Array layer cases need an image view per layer in the copied image.
8976         // Set 0 contains the output buffers.
8977         // Set 1 contains the input attachments.
8978 
8979         std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8980 
8981         shaderCode << "#version 450\n"
8982                    << "\n"
8983                    << "layout (push_constant, std430) uniform PushConstants {\n"
8984                    << "    int width;\n"
8985                    << "    int height;\n"
8986                    << "    int samples;\n"
8987                    << "};\n"
8988                    << "layout (set=0, binding=0) buffer OriginalValues {\n"
8989                    << "    float outputOriginal[];\n"
8990                    << "};\n"
8991                    << "layout (set=0, binding=1) buffer CopiedValues {\n"
8992                    << "    float outputCopied[];\n"
8993                    << "};\n"
8994                    << "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix
8995                    << "subpassInputMS attachment0;\n";
8996 
8997         const auto layerCount = getArrayLayerCount();
8998         for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8999         {
9000             const auto i = layerNdx + 1u;
9001             shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform "
9002                        << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
9003         }
9004 
9005         // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
9006         // created with a single sample.
9007         shaderCode << "\n"
9008                    << "void main() {\n"
9009                    << "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
9010                    << "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
9011                    << "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
9012                    << "        " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
9013                    << "        outputOriginal[bufferPos] = orig.r;\n";
9014 
9015         for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
9016         {
9017             const auto i = layerNdx + 1u;
9018             shaderCode << "        " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i
9019                        << ", sampleID);\n";
9020         }
9021 
9022         std::ostringstream testCondition;
9023         std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
9024         shaderCode << "\n"
9025                    << "        outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
9026 
9027         if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
9028         {
9029             // In array layer copy tests the copied image should be in the layer 3 and other layers should be value of 0 or 0.0 depending on the format.
9030             // This verifies that all the samples in the other layers have proper values.
9031             shaderCode << "        bool equalEmptyLayers = ";
9032             for (uint32_t layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
9033             {
9034                 if (layerNdx == 3)
9035                     continue;
9036                 const auto i = layerNdx + 1u;
9037                 shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0")
9038                            << (layerNdx < 4u ? " && " : ";\n");
9039             }
9040             shaderCode << "        if (!equalEmptyLayers)\n"
9041                        << "            outputCopied[bufferPos]--; \n";
9042         }
9043 
9044         shaderCode << "    }\n"
9045                    << "}\n";
9046     }
9047 
9048     DepthStencilMSAA::TestParameters m_params;
9049 };
9050 
initPrograms(SourceCollections & programCollection) const9051 void DepthStencilMSAATestCase::initPrograms(SourceCollections &programCollection) const
9052 {
9053     programCollection.glslSources.add("vert") << glu::VertexSource("#version 310 es\n"
9054                                                                    "layout (location = 0) in highp vec4 a_position;\n"
9055                                                                    "void main()\n"
9056                                                                    "{\n"
9057                                                                    "    gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
9058                                                                    "}\n");
9059 
9060     programCollection.glslSources.add("frag") << glu::FragmentSource("#version 310 es\n"
9061                                                                      "void main()\n"
9062                                                                      "{}\n");
9063 
9064     // Create the verifying shader for the depth aspect if the depth is used.
9065     if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
9066     {
9067         std::ostringstream verificationShader;
9068         // All the depth formats are float types, so the input attachment prefix is not used.
9069         createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
9070         programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
9071     }
9072 
9073     // Create the verifying shader for the stencil aspect if the stencil is used.
9074     if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
9075     {
9076         std::ostringstream verificationShader;
9077         // All the stencil formats are uint types, so the input attachment prefix is "u".
9078         createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
9079         programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
9080     }
9081 }
9082 
9083 struct BufferOffsetParams
9084 {
9085     static constexpr uint32_t kMaxOffset = 8u;
9086 
9087     uint32_t srcOffset;
9088     uint32_t dstOffset;
9089 };
9090 
checkZerosAt(const std::vector<uint8_t> & bufferData,uint32_t from,uint32_t count)9091 void checkZerosAt(const std::vector<uint8_t> &bufferData, uint32_t from, uint32_t count)
9092 {
9093     constexpr uint8_t zero{0};
9094     for (uint32_t i = 0; i < count; ++i)
9095     {
9096         const auto &val = bufferData[from + i];
9097         if (val != zero)
9098         {
9099             std::ostringstream msg;
9100             msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
9101             TCU_FAIL(msg.str());
9102         }
9103     }
9104 }
9105 
bufferOffsetTest(Context & ctx,BufferOffsetParams params)9106 tcu::TestStatus bufferOffsetTest(Context &ctx, BufferOffsetParams params)
9107 {
9108     // 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.
9109     constexpr auto kMaxOffset  = BufferOffsetParams::kMaxOffset;
9110     constexpr auto kBlockSize  = kMaxOffset * 2u;
9111     constexpr auto kBufferSize = kMaxOffset * kBlockSize;
9112 
9113     DE_ASSERT(params.srcOffset < kMaxOffset);
9114     DE_ASSERT(params.dstOffset < kMaxOffset);
9115 
9116     const auto &vkd   = ctx.getDeviceInterface();
9117     const auto device = ctx.getDevice();
9118     auto &alloc       = ctx.getDefaultAllocator();
9119     const auto qIndex = ctx.getUniversalQueueFamilyIndex();
9120     const auto queue  = ctx.getUniversalQueue();
9121 
9122     const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
9123     const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
9124 
9125     BufferWithMemory srcBuffer(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
9126     BufferWithMemory dstBuffer(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
9127     auto &srcAlloc = srcBuffer.getAllocation();
9128     auto &dstAlloc = dstBuffer.getAllocation();
9129 
9130     // Zero-out destination buffer.
9131     deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
9132     flushAlloc(vkd, device, dstAlloc);
9133 
9134     // Fill source buffer with nonzero bytes.
9135     std::vector<uint8_t> srcData;
9136     srcData.reserve(kBufferSize);
9137     for (uint32_t i = 0; i < kBufferSize; ++i)
9138         srcData.push_back(static_cast<uint8_t>(100u + i));
9139     deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
9140     flushAlloc(vkd, device, srcAlloc);
9141 
9142     // Copy regions.
9143     std::vector<VkBufferCopy> copies;
9144     copies.reserve(kMaxOffset);
9145     for (uint32_t i = 0; i < kMaxOffset; ++i)
9146     {
9147         const auto blockStart = kBlockSize * i;
9148         const auto copySize   = i + 1u;
9149         const auto bufferCopy = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
9150         copies.push_back(bufferCopy);
9151     }
9152 
9153     const auto cmdPool      = makeCommandPool(vkd, device, qIndex);
9154     const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
9155     const auto cmdBuffer    = cmdBufferPtr.get();
9156 
9157     beginCommandBuffer(vkd, cmdBuffer);
9158     vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<uint32_t>(copies.size()), copies.data());
9159     const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
9160     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u,
9161                            nullptr, 0u, nullptr);
9162     endCommandBuffer(vkd, cmdBuffer);
9163     submitCommandsAndWait(vkd, device, queue, cmdBuffer);
9164     invalidateAlloc(vkd, device, dstAlloc);
9165 
9166     // Verify destination buffer data.
9167     std::vector<uint8_t> dstData(kBufferSize);
9168     deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
9169 
9170     for (uint32_t blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
9171     {
9172         const auto blockStart = kBlockSize * blockIdx;
9173         const auto copySize   = blockIdx + 1u;
9174 
9175         // Verify no data has been written before dstOffset.
9176         checkZerosAt(dstData, blockStart, params.dstOffset);
9177 
9178         // Verify copied block.
9179         for (uint32_t i = 0; i < copySize; ++i)
9180         {
9181             const auto &dstVal = dstData[blockStart + params.dstOffset + i];
9182             const auto &srcVal = srcData[blockStart + params.srcOffset + i];
9183             if (dstVal != srcVal)
9184             {
9185                 std::ostringstream msg;
9186                 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected "
9187                     << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
9188                 TCU_FAIL(msg.str());
9189             }
9190         }
9191 
9192         // Verify no data has been written after copy block.
9193         checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
9194     }
9195 
9196     return tcu::TestStatus::pass("Pass");
9197 }
9198 
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)9199 std::string getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)
9200 {
9201     return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
9202 }
9203 
getFormatCaseName(VkFormat format)9204 std::string getFormatCaseName(VkFormat format)
9205 {
9206     return de::toLower(de::toString(getFormatStr(format)).substr(10));
9207 }
9208 
getImageLayoutCaseName(VkImageLayout layout)9209 std::string getImageLayoutCaseName(VkImageLayout layout)
9210 {
9211     switch (layout)
9212     {
9213     case VK_IMAGE_LAYOUT_GENERAL:
9214         return "general";
9215     case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
9216     case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
9217         return "optimal";
9218     default:
9219         DE_ASSERT(false);
9220         return "";
9221     }
9222 }
9223 
9224 struct TestGroupParams
9225 {
9226     AllocationKind allocationKind;
9227     uint32_t extensionFlags;
9228     QueueSelectionOptions queueSelection;
9229     bool useSecondaryCmdBuffer;
9230     bool useSparseBinding;
9231 };
9232 
9233 using TestGroupParamsPtr = de::SharedPtr<TestGroupParams>;
9234 
addImageToImageSimpleTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)9235 void addImageToImageSimpleTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
9236 {
9237     tcu::TestContext &testCtx = group->getTestContext();
9238 
9239     {
9240         TestParams params;
9241         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9242         params.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
9243         params.src.image.extent          = defaultExtent;
9244         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9245         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9246         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9247         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
9248         params.dst.image.extent          = defaultExtent;
9249         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9250         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9251         params.allocationKind            = testGroupParams->allocationKind;
9252         params.extensionFlags            = testGroupParams->extensionFlags;
9253         params.queueSelection            = testGroupParams->queueSelection;
9254         params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9255         params.useSparseBinding          = testGroupParams->useSparseBinding;
9256 
9257         {
9258             const VkImageCopy testCopy = {
9259                 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9260                 {0, 0, 0},          // VkOffset3D srcOffset;
9261                 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9262                 {0, 0, 0},          // VkOffset3D dstOffset;
9263                 defaultExtent,      // VkExtent3D extent;
9264             };
9265 
9266             CopyRegion imageCopy;
9267             imageCopy.imageCopy = testCopy;
9268             params.regions.push_back(imageCopy);
9269         }
9270 
9271         group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", params));
9272     }
9273 
9274     {
9275         TestParams params;
9276         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9277         params.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
9278         params.src.image.extent          = defaultExtent;
9279         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9280         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9281         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9282         params.dst.image.format          = VK_FORMAT_R32_UINT;
9283         params.dst.image.extent          = defaultExtent;
9284         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9285         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9286         params.allocationKind            = testGroupParams->allocationKind;
9287         params.extensionFlags            = testGroupParams->extensionFlags;
9288         params.queueSelection            = testGroupParams->queueSelection;
9289         params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9290         params.useSparseBinding          = testGroupParams->useSparseBinding;
9291 
9292         {
9293             const VkImageCopy testCopy = {
9294                 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9295                 {0, 0, 0},          // VkOffset3D srcOffset;
9296                 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9297                 {0, 0, 0},          // VkOffset3D dstOffset;
9298                 defaultExtent,      // VkExtent3D extent;
9299             };
9300 
9301             CopyRegion imageCopy;
9302             imageCopy.imageCopy = testCopy;
9303             params.regions.push_back(imageCopy);
9304         }
9305 
9306         group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_format", params));
9307     }
9308 
9309     {
9310         TestParams params;
9311         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9312         params.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
9313         params.src.image.extent          = defaultExtent;
9314         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9315         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9316         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9317         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
9318         params.dst.image.extent          = defaultExtent;
9319         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9320         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9321         params.allocationKind            = testGroupParams->allocationKind;
9322         params.extensionFlags            = testGroupParams->extensionFlags;
9323         params.queueSelection            = testGroupParams->queueSelection;
9324         params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9325         params.useSparseBinding          = testGroupParams->useSparseBinding;
9326 
9327         {
9328             const VkImageCopy testCopy = {
9329                 defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
9330                 {0, 0, 0},                                           // VkOffset3D srcOffset;
9331                 defaultSourceLayer,                                  // VkImageSubresourceLayers dstSubresource;
9332                 {defaultQuarterSize, defaultQuarterSize / 2, 0},     // VkOffset3D dstOffset;
9333                 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9334             };
9335 
9336             CopyRegion imageCopy;
9337             imageCopy.imageCopy = testCopy;
9338             params.regions.push_back(imageCopy);
9339         }
9340 
9341         group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", params));
9342     }
9343 
9344     static const struct
9345     {
9346         std::string name;
9347         vk::VkFormat format1;
9348         vk::VkFormat format2;
9349     } formats[] = {{"diff_format", vk::VK_FORMAT_R32_UINT, vk::VK_FORMAT_R8G8B8A8_UNORM},
9350                    {"same_format", vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM}};
9351     static const struct
9352     {
9353         std::string name;
9354         vk::VkBool32 clear;
9355     } clears[] = {{"clear", VK_TRUE}, {"noclear", VK_FALSE}};
9356     static const struct
9357     {
9358         std::string name;
9359         VkExtent3D extent;
9360     } extents[] = {{"npot", {65u, 63u, 1u}}, {"pot", {64u, 64u, 1u}}};
9361 
9362     for (const auto &format : formats)
9363     {
9364         for (const auto &clear : clears)
9365         {
9366             if (testGroupParams->queueSelection == QueueSelectionOptions::TransferOnly)
9367                 continue;
9368 
9369             for (const auto &extent : extents)
9370             {
9371                 TestParams params;
9372                 params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9373                 params.src.image.format          = format.format1;
9374                 params.src.image.extent          = extent.extent;
9375                 params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9376                 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9377                 params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9378                 params.dst.image.format          = format.format2;
9379                 params.dst.image.extent          = extent.extent;
9380                 params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9381                 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9382                 params.allocationKind            = testGroupParams->allocationKind;
9383                 params.extensionFlags            = testGroupParams->extensionFlags;
9384                 params.queueSelection            = testGroupParams->queueSelection;
9385                 params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9386                 params.useSparseBinding          = testGroupParams->useSparseBinding;
9387                 params.clearDestinationWithRed   = clear.clear;
9388 
9389                 {
9390                     VkImageCopy testCopy = {
9391                         defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
9392                         {34, 34, 0},        // VkOffset3D srcOffset;
9393                         defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
9394                         {0, 0, 0},          // VkOffset3D dstOffset;
9395                         {31, 29, 1}         // VkExtent3D extent;
9396                     };
9397 
9398                     if (extent.name == "pot")
9399                     {
9400                         testCopy.srcOffset = {16, 16, 0};
9401                         testCopy.extent    = {32, 32, 1};
9402                     }
9403 
9404                     CopyRegion imageCopy;
9405                     imageCopy.imageCopy = testCopy;
9406                     params.regions.push_back(imageCopy);
9407                 }
9408 
9409                 // Example test case name: "partial_image_npot_diff_format_clear"
9410                 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
9411 
9412                 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, params));
9413             }
9414         }
9415     }
9416 
9417     {
9418         TestParams params;
9419         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9420         params.src.image.format          = VK_FORMAT_D32_SFLOAT;
9421         params.src.image.extent          = defaultExtent;
9422         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9423         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9424         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9425         params.dst.image.format          = VK_FORMAT_D32_SFLOAT;
9426         params.dst.image.extent          = defaultExtent;
9427         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9428         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9429         params.allocationKind            = testGroupParams->allocationKind;
9430         params.extensionFlags            = testGroupParams->extensionFlags;
9431         params.queueSelection            = testGroupParams->queueSelection;
9432         params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9433         params.useSparseBinding          = testGroupParams->useSparseBinding;
9434 
9435         {
9436             const VkImageSubresourceLayers sourceLayer = {
9437                 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
9438                 0u,                        // uint32_t mipLevel;
9439                 0u,                        // uint32_t baseArrayLayer;
9440                 1u                         // uint32_t layerCount;
9441             };
9442             const VkImageCopy testCopy = {
9443                 sourceLayer,                                         // VkImageSubresourceLayers srcSubresource;
9444                 {0, 0, 0},                                           // VkOffset3D srcOffset;
9445                 sourceLayer,                                         // VkImageSubresourceLayers dstSubresource;
9446                 {defaultQuarterSize, defaultQuarterSize / 2, 0},     // VkOffset3D dstOffset;
9447                 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9448             };
9449 
9450             CopyRegion imageCopy;
9451             imageCopy.imageCopy = testCopy;
9452             params.regions.push_back(imageCopy);
9453         }
9454 
9455         group->addChild(new CopyImageToImageTestCase(testCtx, "depth", params));
9456     }
9457 
9458     {
9459         TestParams params;
9460         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
9461         params.src.image.format          = VK_FORMAT_S8_UINT;
9462         params.src.image.extent          = defaultExtent;
9463         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9464         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9465         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
9466         params.dst.image.format          = VK_FORMAT_S8_UINT;
9467         params.dst.image.extent          = defaultExtent;
9468         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
9469         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9470         params.allocationKind            = testGroupParams->allocationKind;
9471         params.extensionFlags            = testGroupParams->extensionFlags;
9472         params.queueSelection            = testGroupParams->queueSelection;
9473         params.useSecondaryCmdBuffer     = testGroupParams->useSecondaryCmdBuffer;
9474         params.useSparseBinding          = testGroupParams->useSparseBinding;
9475 
9476         {
9477             const VkImageSubresourceLayers sourceLayer = {
9478                 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
9479                 0u,                          // uint32_t mipLevel;
9480                 0u,                          // uint32_t baseArrayLayer;
9481                 1u                           // uint32_t layerCount;
9482             };
9483             const VkImageCopy testCopy = {
9484                 sourceLayer,                                         // VkImageSubresourceLayers srcSubresource;
9485                 {0, 0, 0},                                           // VkOffset3D srcOffset;
9486                 sourceLayer,                                         // VkImageSubresourceLayers dstSubresource;
9487                 {defaultQuarterSize, defaultQuarterSize / 2, 0},     // VkOffset3D dstOffset;
9488                 {defaultQuarterSize / 2, defaultQuarterSize / 2, 1}, // VkExtent3D extent;
9489             };
9490 
9491             CopyRegion imageCopy;
9492             imageCopy.imageCopy = testCopy;
9493             params.regions.push_back(imageCopy);
9494         }
9495 
9496         group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", params));
9497     }
9498 }
9499 
9500 struct CopyColorTestParams
9501 {
9502     TestParams params;
9503     const VkFormat *compatibleFormats;
9504 };
9505 
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)9506 void addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup *group, TestParams params)
9507 {
9508     const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
9509     const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
9510 
9511     for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9512     {
9513         params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9514 
9515         for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9516         {
9517             params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9518 
9519             const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9520                                          getImageLayoutCaseName(params.dst.image.operationLayout);
9521             const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9522                                             " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9523             group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, params));
9524         }
9525     }
9526 }
9527 
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)9528 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams &testParams)
9529 {
9530     bool result = true;
9531 
9532     if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
9533     {
9534         DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
9535 
9536         result = de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
9537                  de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
9538     }
9539 
9540     return result;
9541 }
9542 
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)9543 void addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup *group, CopyColorTestParams testParams)
9544 {
9545     // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
9546     const VkFormat srcFormatOnly[2] = {testParams.params.src.image.format, VK_FORMAT_UNDEFINED};
9547     const VkFormat *formatList      = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
9548 
9549     for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
9550     {
9551         testParams.params.dst.image.format = formatList[dstFormatIndex];
9552 
9553         const VkFormat srcFormat = testParams.params.src.image.format;
9554         const VkFormat dstFormat = testParams.params.dst.image.format;
9555 
9556         if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
9557             continue;
9558 
9559         if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9560             continue;
9561 
9562         if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
9563             if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) ||
9564                 (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
9565                 continue;
9566 
9567         const std::string description = "Copy to destination format " + getFormatCaseName(dstFormat);
9568         addTestGroup(group, getFormatCaseName(dstFormat), addImageToImageAllFormatsColorSrcFormatDstFormatTests,
9569                      testParams.params);
9570     }
9571 }
9572 
9573 const VkFormat compatibleFormats8Bit[] = {VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R8_UNORM,   VK_FORMAT_R8_SNORM,
9574                                           VK_FORMAT_R8_USCALED,       VK_FORMAT_R8_SSCALED, VK_FORMAT_R8_UINT,
9575                                           VK_FORMAT_R8_SINT,          VK_FORMAT_R8_SRGB,
9576 
9577                                           VK_FORMAT_UNDEFINED};
9578 
9579 const VkFormat compatibleFormats8BitA[] = {
9580 #ifndef CTS_USES_VULKANSC
9581     VK_FORMAT_A8_UNORM_KHR,
9582 #endif // CTS_USES_VULKANSC
9583     VK_FORMAT_UNDEFINED};
9584 
9585 const VkFormat compatibleFormats16Bit[] = {VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9586                                            VK_FORMAT_B4G4R4A4_UNORM_PACK16,
9587                                            VK_FORMAT_R5G6B5_UNORM_PACK16,
9588                                            VK_FORMAT_B5G6R5_UNORM_PACK16,
9589                                            VK_FORMAT_R5G5B5A1_UNORM_PACK16,
9590                                            VK_FORMAT_B5G5R5A1_UNORM_PACK16,
9591                                            VK_FORMAT_A1R5G5B5_UNORM_PACK16,
9592 #ifndef CTS_USES_VULKANSC
9593                                            VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
9594 #endif // CTS_USES_VULKANSC
9595                                            VK_FORMAT_R8G8_UNORM,
9596                                            VK_FORMAT_R8G8_SNORM,
9597                                            VK_FORMAT_R8G8_USCALED,
9598                                            VK_FORMAT_R8G8_SSCALED,
9599                                            VK_FORMAT_R8G8_UINT,
9600                                            VK_FORMAT_R8G8_SINT,
9601                                            VK_FORMAT_R8G8_SRGB,
9602                                            VK_FORMAT_R16_UNORM,
9603                                            VK_FORMAT_R16_SNORM,
9604                                            VK_FORMAT_R16_USCALED,
9605                                            VK_FORMAT_R16_SSCALED,
9606                                            VK_FORMAT_R16_UINT,
9607                                            VK_FORMAT_R16_SINT,
9608                                            VK_FORMAT_R16_SFLOAT,
9609                                            VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
9610                                            VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
9611 
9612                                            VK_FORMAT_UNDEFINED};
9613 const VkFormat compatibleFormats24Bit[] = {VK_FORMAT_R8G8B8_UNORM,   VK_FORMAT_R8G8B8_SNORM,   VK_FORMAT_R8G8B8_USCALED,
9614                                            VK_FORMAT_R8G8B8_SSCALED, VK_FORMAT_R8G8B8_UINT,    VK_FORMAT_R8G8B8_SINT,
9615                                            VK_FORMAT_R8G8B8_SRGB,    VK_FORMAT_B8G8R8_UNORM,   VK_FORMAT_B8G8R8_SNORM,
9616                                            VK_FORMAT_B8G8R8_USCALED, VK_FORMAT_B8G8R8_SSCALED, VK_FORMAT_B8G8R8_UINT,
9617                                            VK_FORMAT_B8G8R8_SINT,    VK_FORMAT_B8G8R8_SRGB,
9618 
9619                                            VK_FORMAT_UNDEFINED};
9620 const VkFormat compatibleFormats32Bit[] = {VK_FORMAT_R8G8B8A8_UNORM,
9621                                            VK_FORMAT_R8G8B8A8_SNORM,
9622                                            VK_FORMAT_R8G8B8A8_USCALED,
9623                                            VK_FORMAT_R8G8B8A8_SSCALED,
9624                                            VK_FORMAT_R8G8B8A8_UINT,
9625                                            VK_FORMAT_R8G8B8A8_SINT,
9626                                            VK_FORMAT_R8G8B8A8_SRGB,
9627                                            VK_FORMAT_B8G8R8A8_UNORM,
9628                                            VK_FORMAT_B8G8R8A8_SNORM,
9629                                            VK_FORMAT_B8G8R8A8_USCALED,
9630                                            VK_FORMAT_B8G8R8A8_SSCALED,
9631                                            VK_FORMAT_B8G8R8A8_UINT,
9632                                            VK_FORMAT_B8G8R8A8_SINT,
9633                                            VK_FORMAT_B8G8R8A8_SRGB,
9634                                            VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9635                                            VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9636                                            VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9637                                            VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9638                                            VK_FORMAT_A8B8G8R8_UINT_PACK32,
9639                                            VK_FORMAT_A8B8G8R8_SINT_PACK32,
9640                                            VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9641                                            VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9642                                            VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9643                                            VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9644                                            VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9645                                            VK_FORMAT_A2R10G10B10_UINT_PACK32,
9646                                            VK_FORMAT_A2R10G10B10_SINT_PACK32,
9647                                            VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9648                                            VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9649                                            VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9650                                            VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9651                                            VK_FORMAT_A2B10G10R10_UINT_PACK32,
9652                                            VK_FORMAT_A2B10G10R10_SINT_PACK32,
9653                                            VK_FORMAT_R16G16_UNORM,
9654                                            VK_FORMAT_R16G16_SNORM,
9655                                            VK_FORMAT_R16G16_USCALED,
9656                                            VK_FORMAT_R16G16_SSCALED,
9657                                            VK_FORMAT_R16G16_UINT,
9658                                            VK_FORMAT_R16G16_SINT,
9659                                            VK_FORMAT_R16G16_SFLOAT,
9660                                            VK_FORMAT_R32_UINT,
9661                                            VK_FORMAT_R32_SINT,
9662                                            VK_FORMAT_R32_SFLOAT,
9663 
9664                                            VK_FORMAT_UNDEFINED};
9665 const VkFormat compatibleFormats48Bit[] = {
9666     VK_FORMAT_R16G16B16_UNORM, VK_FORMAT_R16G16B16_SNORM, VK_FORMAT_R16G16B16_USCALED, VK_FORMAT_R16G16B16_SSCALED,
9667     VK_FORMAT_R16G16B16_UINT,  VK_FORMAT_R16G16B16_SINT,  VK_FORMAT_R16G16B16_SFLOAT,
9668 
9669     VK_FORMAT_UNDEFINED};
9670 const VkFormat compatibleFormats64Bit[]  = {VK_FORMAT_R16G16B16A16_UNORM,
9671                                             VK_FORMAT_R16G16B16A16_SNORM,
9672                                             VK_FORMAT_R16G16B16A16_USCALED,
9673                                             VK_FORMAT_R16G16B16A16_SSCALED,
9674                                             VK_FORMAT_R16G16B16A16_UINT,
9675                                             VK_FORMAT_R16G16B16A16_SINT,
9676                                             VK_FORMAT_R16G16B16A16_SFLOAT,
9677                                             VK_FORMAT_R32G32_UINT,
9678                                             VK_FORMAT_R32G32_SINT,
9679                                             VK_FORMAT_R32G32_SFLOAT,
9680                                             VK_FORMAT_R64_UINT,
9681                                             VK_FORMAT_R64_SINT,
9682                                             VK_FORMAT_R64_SFLOAT,
9683 
9684                                             VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9685                                             VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9686                                             VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9687                                             VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9688                                             VK_FORMAT_BC4_UNORM_BLOCK,
9689                                             VK_FORMAT_BC4_SNORM_BLOCK,
9690 
9691                                             VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9692                                             VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9693                                             VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9694                                             VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9695 
9696                                             VK_FORMAT_EAC_R11_UNORM_BLOCK,
9697                                             VK_FORMAT_EAC_R11_SNORM_BLOCK,
9698 
9699                                             VK_FORMAT_UNDEFINED};
9700 const VkFormat compatibleFormats96Bit[]  = {VK_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_SINT,
9701                                             VK_FORMAT_R32G32B32_SFLOAT,
9702 
9703                                             VK_FORMAT_UNDEFINED};
9704 const VkFormat compatibleFormats128Bit[] = {VK_FORMAT_R32G32B32A32_UINT,
9705                                             VK_FORMAT_R32G32B32A32_SINT,
9706                                             VK_FORMAT_R32G32B32A32_SFLOAT,
9707                                             VK_FORMAT_R64G64_UINT,
9708                                             VK_FORMAT_R64G64_SINT,
9709                                             VK_FORMAT_R64G64_SFLOAT,
9710 
9711                                             VK_FORMAT_BC2_UNORM_BLOCK,
9712                                             VK_FORMAT_BC2_SRGB_BLOCK,
9713                                             VK_FORMAT_BC3_UNORM_BLOCK,
9714                                             VK_FORMAT_BC3_SRGB_BLOCK,
9715                                             VK_FORMAT_BC5_UNORM_BLOCK,
9716                                             VK_FORMAT_BC5_SNORM_BLOCK,
9717                                             VK_FORMAT_BC6H_UFLOAT_BLOCK,
9718                                             VK_FORMAT_BC6H_SFLOAT_BLOCK,
9719                                             VK_FORMAT_BC7_UNORM_BLOCK,
9720                                             VK_FORMAT_BC7_SRGB_BLOCK,
9721 
9722                                             VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9723                                             VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9724 
9725                                             VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9726                                             VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9727 
9728                                             VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9729                                             VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9730                                             VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9731                                             VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9732                                             VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9733                                             VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9734                                             VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9735                                             VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9736                                             VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9737                                             VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9738                                             VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9739                                             VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9740                                             VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9741                                             VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9742                                             VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9743                                             VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9744                                             VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9745                                             VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9746                                             VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9747                                             VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9748                                             VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9749                                             VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9750                                             VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9751                                             VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9752                                             VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9753                                             VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9754                                             VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9755                                             VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9756 
9757                                             VK_FORMAT_UNDEFINED};
9758 const VkFormat compatibleFormats192Bit[] = {VK_FORMAT_R64G64B64_UINT, VK_FORMAT_R64G64B64_SINT,
9759                                             VK_FORMAT_R64G64B64_SFLOAT,
9760 
9761                                             VK_FORMAT_UNDEFINED};
9762 const VkFormat compatibleFormats256Bit[] = {VK_FORMAT_R64G64B64A64_UINT, VK_FORMAT_R64G64B64A64_SINT,
9763                                             VK_FORMAT_R64G64B64A64_SFLOAT,
9764 
9765                                             VK_FORMAT_UNDEFINED};
9766 
9767 const VkFormat *colorImageFormatsToTest[] = {compatibleFormats8Bit,   compatibleFormats8BitA, compatibleFormats16Bit,
9768                                              compatibleFormats24Bit,  compatibleFormats32Bit, compatibleFormats48Bit,
9769                                              compatibleFormats64Bit,  compatibleFormats96Bit, compatibleFormats128Bit,
9770                                              compatibleFormats192Bit, compatibleFormats256Bit};
9771 
9772 const VkFormat compatibleFormatsUInts[]  = {VK_FORMAT_R8_UINT,
9773                                             VK_FORMAT_R8G8_UINT,
9774                                             VK_FORMAT_R8G8B8_UINT,
9775                                             VK_FORMAT_B8G8R8_UINT,
9776                                             VK_FORMAT_R8G8B8A8_UINT,
9777                                             VK_FORMAT_B8G8R8A8_UINT,
9778                                             VK_FORMAT_A8B8G8R8_UINT_PACK32,
9779                                             VK_FORMAT_A2R10G10B10_UINT_PACK32,
9780                                             VK_FORMAT_A2B10G10R10_UINT_PACK32,
9781                                             VK_FORMAT_R16_UINT,
9782                                             VK_FORMAT_R16G16_UINT,
9783                                             VK_FORMAT_R16G16B16_UINT,
9784                                             VK_FORMAT_R16G16B16A16_UINT,
9785                                             VK_FORMAT_R32_UINT,
9786                                             VK_FORMAT_R32G32_UINT,
9787                                             VK_FORMAT_R32G32B32_UINT,
9788                                             VK_FORMAT_R32G32B32A32_UINT,
9789                                             VK_FORMAT_R64_UINT,
9790                                             VK_FORMAT_R64G64_UINT,
9791                                             VK_FORMAT_R64G64B64_UINT,
9792                                             VK_FORMAT_R64G64B64A64_UINT,
9793 
9794                                             VK_FORMAT_UNDEFINED};
9795 const VkFormat compatibleFormatsSInts[]  = {VK_FORMAT_R8_SINT,
9796                                             VK_FORMAT_R8G8_SINT,
9797                                             VK_FORMAT_R8G8B8_SINT,
9798                                             VK_FORMAT_B8G8R8_SINT,
9799                                             VK_FORMAT_R8G8B8A8_SINT,
9800                                             VK_FORMAT_B8G8R8A8_SINT,
9801                                             VK_FORMAT_A8B8G8R8_SINT_PACK32,
9802                                             VK_FORMAT_A2R10G10B10_SINT_PACK32,
9803                                             VK_FORMAT_A2B10G10R10_SINT_PACK32,
9804                                             VK_FORMAT_R16_SINT,
9805                                             VK_FORMAT_R16G16_SINT,
9806                                             VK_FORMAT_R16G16B16_SINT,
9807                                             VK_FORMAT_R16G16B16A16_SINT,
9808                                             VK_FORMAT_R32_SINT,
9809                                             VK_FORMAT_R32G32_SINT,
9810                                             VK_FORMAT_R32G32B32_SINT,
9811                                             VK_FORMAT_R32G32B32A32_SINT,
9812                                             VK_FORMAT_R64_SINT,
9813                                             VK_FORMAT_R64G64_SINT,
9814                                             VK_FORMAT_R64G64B64_SINT,
9815                                             VK_FORMAT_R64G64B64A64_SINT,
9816 
9817                                             VK_FORMAT_UNDEFINED};
9818 const VkFormat compatibleFormatsFloats[] = {VK_FORMAT_R4G4_UNORM_PACK8,
9819                                             VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9820                                             VK_FORMAT_B4G4R4A4_UNORM_PACK16,
9821                                             VK_FORMAT_R5G6B5_UNORM_PACK16,
9822                                             VK_FORMAT_B5G6R5_UNORM_PACK16,
9823                                             VK_FORMAT_R5G5B5A1_UNORM_PACK16,
9824                                             VK_FORMAT_B5G5R5A1_UNORM_PACK16,
9825                                             VK_FORMAT_A1R5G5B5_UNORM_PACK16,
9826 #ifndef CTS_USES_VULKANSC
9827                                             VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
9828 #endif // CTS_USES_VULKANSC
9829                                             VK_FORMAT_R8_UNORM,
9830                                             VK_FORMAT_R8_SNORM,
9831                                             VK_FORMAT_R8_USCALED,
9832                                             VK_FORMAT_R8_SSCALED,
9833 #ifndef CTS_USES_VULKANSC
9834                                             VK_FORMAT_A8_UNORM_KHR,
9835 #endif // CTS_USES_VULKANSC
9836                                             VK_FORMAT_R8G8_UNORM,
9837                                             VK_FORMAT_R8G8_SNORM,
9838                                             VK_FORMAT_R8G8_USCALED,
9839                                             VK_FORMAT_R8G8_SSCALED,
9840                                             VK_FORMAT_R8G8B8_UNORM,
9841                                             VK_FORMAT_R8G8B8_SNORM,
9842                                             VK_FORMAT_R8G8B8_USCALED,
9843                                             VK_FORMAT_R8G8B8_SSCALED,
9844                                             VK_FORMAT_B8G8R8_UNORM,
9845                                             VK_FORMAT_B8G8R8_SNORM,
9846                                             VK_FORMAT_B8G8R8_USCALED,
9847                                             VK_FORMAT_B8G8R8_SSCALED,
9848                                             VK_FORMAT_R8G8B8A8_UNORM,
9849                                             VK_FORMAT_R8G8B8A8_SNORM,
9850                                             VK_FORMAT_R8G8B8A8_USCALED,
9851                                             VK_FORMAT_R8G8B8A8_SSCALED,
9852                                             VK_FORMAT_B8G8R8A8_UNORM,
9853                                             VK_FORMAT_B8G8R8A8_SNORM,
9854                                             VK_FORMAT_B8G8R8A8_USCALED,
9855                                             VK_FORMAT_B8G8R8A8_SSCALED,
9856                                             VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9857                                             VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9858                                             VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9859                                             VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9860                                             VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9861                                             VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9862                                             VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9863                                             VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9864                                             VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9865                                             VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9866                                             VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9867                                             VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9868                                             VK_FORMAT_R16_UNORM,
9869                                             VK_FORMAT_R16_SNORM,
9870                                             VK_FORMAT_R16_USCALED,
9871                                             VK_FORMAT_R16_SSCALED,
9872                                             VK_FORMAT_R16_SFLOAT,
9873                                             VK_FORMAT_R16G16_UNORM,
9874                                             VK_FORMAT_R16G16_SNORM,
9875                                             VK_FORMAT_R16G16_USCALED,
9876                                             VK_FORMAT_R16G16_SSCALED,
9877                                             VK_FORMAT_R16G16_SFLOAT,
9878                                             VK_FORMAT_R16G16B16_UNORM,
9879                                             VK_FORMAT_R16G16B16_SNORM,
9880                                             VK_FORMAT_R16G16B16_USCALED,
9881                                             VK_FORMAT_R16G16B16_SSCALED,
9882                                             VK_FORMAT_R16G16B16_SFLOAT,
9883                                             VK_FORMAT_R16G16B16A16_UNORM,
9884                                             VK_FORMAT_R16G16B16A16_SNORM,
9885                                             VK_FORMAT_R16G16B16A16_USCALED,
9886                                             VK_FORMAT_R16G16B16A16_SSCALED,
9887                                             VK_FORMAT_R16G16B16A16_SFLOAT,
9888                                             VK_FORMAT_R32_SFLOAT,
9889                                             VK_FORMAT_R32G32_SFLOAT,
9890                                             VK_FORMAT_R32G32B32_SFLOAT,
9891                                             VK_FORMAT_R32G32B32A32_SFLOAT,
9892                                             VK_FORMAT_R64_SFLOAT,
9893                                             VK_FORMAT_R64G64_SFLOAT,
9894                                             VK_FORMAT_R64G64B64_SFLOAT,
9895                                             VK_FORMAT_R64G64B64A64_SFLOAT,
9896                                             VK_FORMAT_B10G11R11_UFLOAT_PACK32,
9897                                             VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
9898 
9899                                             VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
9900                                             VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
9901 
9902                                             VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
9903 
9904                                             VK_FORMAT_UNDEFINED};
9905 
9906 const VkFormat compressedFormatsFloats[] = {VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9907                                             VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9908                                             VK_FORMAT_BC2_UNORM_BLOCK,
9909                                             VK_FORMAT_BC3_UNORM_BLOCK,
9910                                             VK_FORMAT_BC4_UNORM_BLOCK,
9911                                             VK_FORMAT_BC4_SNORM_BLOCK,
9912                                             VK_FORMAT_BC5_UNORM_BLOCK,
9913                                             VK_FORMAT_BC5_SNORM_BLOCK,
9914                                             VK_FORMAT_BC6H_UFLOAT_BLOCK,
9915                                             VK_FORMAT_BC6H_SFLOAT_BLOCK,
9916                                             VK_FORMAT_BC7_UNORM_BLOCK,
9917                                             VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9918                                             VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9919                                             VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9920                                             VK_FORMAT_EAC_R11_UNORM_BLOCK,
9921                                             VK_FORMAT_EAC_R11_SNORM_BLOCK,
9922                                             VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9923                                             VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9924                                             VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9925                                             VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9926                                             VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9927                                             VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9928                                             VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9929                                             VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9930                                             VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9931                                             VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9932                                             VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9933                                             VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9934                                             VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9935                                             VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9936                                             VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9937                                             VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9938 
9939                                             VK_FORMAT_UNDEFINED};
9940 
9941 const VkFormat compatibleFormatsSrgb[] = {
9942     VK_FORMAT_R8_SRGB,       VK_FORMAT_R8G8_SRGB,     VK_FORMAT_R8G8B8_SRGB,          VK_FORMAT_B8G8R8_SRGB,
9943     VK_FORMAT_R8G8B8A8_SRGB, VK_FORMAT_B8G8R8A8_SRGB, VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9944 
9945     VK_FORMAT_UNDEFINED};
9946 
9947 const VkFormat compressedFormatsSrgb[] = {VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9948                                           VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9949                                           VK_FORMAT_BC2_SRGB_BLOCK,
9950                                           VK_FORMAT_BC3_SRGB_BLOCK,
9951                                           VK_FORMAT_BC7_SRGB_BLOCK,
9952                                           VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9953                                           VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9954                                           VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9955                                           VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9956                                           VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9957                                           VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9958                                           VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9959                                           VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9960                                           VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9961                                           VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9962                                           VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9963                                           VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9964                                           VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9965                                           VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9966                                           VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9967                                           VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9968                                           VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9969 
9970                                           VK_FORMAT_UNDEFINED};
9971 
9972 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] = {
9973     // From compatibleFormats8Bit
9974     VK_FORMAT_R4G4_UNORM_PACK8,
9975     VK_FORMAT_R8_SRGB,
9976 
9977     // From compatibleFormats16Bit
9978     VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9979     VK_FORMAT_R16_SFLOAT,
9980 
9981     // From compatibleFormats24Bit
9982     VK_FORMAT_R8G8B8_UNORM,
9983     VK_FORMAT_B8G8R8_SRGB,
9984 
9985     // From compatibleFormats32Bit
9986     VK_FORMAT_R8G8B8A8_UNORM,
9987     VK_FORMAT_R32_SFLOAT,
9988 
9989     // From compatibleFormats48Bit
9990     VK_FORMAT_R16G16B16_UNORM,
9991     VK_FORMAT_R16G16B16_SFLOAT,
9992 
9993     // From compatibleFormats64Bit
9994     VK_FORMAT_R16G16B16A16_UNORM,
9995     VK_FORMAT_R64_SFLOAT,
9996 
9997     // From compatibleFormats96Bit
9998     VK_FORMAT_R32G32B32_UINT,
9999     VK_FORMAT_R32G32B32_SFLOAT,
10000 
10001     // From compatibleFormats128Bit
10002     VK_FORMAT_R32G32B32A32_UINT,
10003     VK_FORMAT_R64G64_SFLOAT,
10004 
10005     // From compatibleFormats192Bit
10006     VK_FORMAT_R64G64B64_UINT,
10007     VK_FORMAT_R64G64B64_SFLOAT,
10008 
10009     // From compatibleFormats256Bit
10010     VK_FORMAT_R64G64B64A64_UINT,
10011     VK_FORMAT_R64G64B64A64_SFLOAT,
10012 };
10013 
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10014 void addImageToImageAllFormatsColorTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10015 {
10016     if (testGroupParams->allocationKind == ALLOCATION_KIND_DEDICATED)
10017     {
10018         const int numOfDedicatedAllocationImageToImageFormatsToTest =
10019             DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
10020         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest;
10021              ++compatibleFormatsIndex)
10022             dedicatedAllocationImageToImageFormatsToTestSet.insert(
10023                 dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
10024     }
10025 
10026     // 1D to 1D tests.
10027     {
10028         // 1D to 1D copies
10029         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_1d"));
10030 
10031         TestParams params;
10032         params.src.image.imageType = VK_IMAGE_TYPE_1D;
10033         params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10034         params.src.image.extent    = default1dExtent;
10035         params.dst.image.extent    = default1dExtent;
10036         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10037         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10038         params.src.image.fillMode  = FILL_MODE_WHITE;
10039         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10040         params.allocationKind      = testGroupParams->allocationKind;
10041         params.extensionFlags      = testGroupParams->extensionFlags;
10042         params.queueSelection      = testGroupParams->queueSelection;
10043 
10044         for (int32_t i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
10045         {
10046             const VkImageCopy testCopy = {
10047                 defaultSourceLayer,         // VkImageSubresourceLayers srcSubresource;
10048                 {0, 0, 0},                  // VkOffset3D srcOffset;
10049                 defaultSourceLayer,         // VkImageSubresourceLayers dstSubresource;
10050                 {i, 0, 0},                  // VkOffset3D dstOffset;
10051                 {defaultQuarterSize, 1, 1}, // VkExtent3D extent;
10052             };
10053 
10054             CopyRegion imageCopy;
10055             imageCopy.imageCopy = testCopy;
10056 
10057             params.regions.push_back(imageCopy);
10058         }
10059 
10060         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10061         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10062              ++compatibleFormatsIndex)
10063         {
10064             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10065             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10066             {
10067                 params.src.image.format = compatibleFormats[srcFormatIndex];
10068                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10069                     continue;
10070 
10071                 CopyColorTestParams testParams;
10072                 testParams.params            = params;
10073                 testParams.compatibleFormats = nullptr;
10074 
10075                 const std::string testName = getFormatCaseName(params.src.image.format);
10076                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10077             }
10078         }
10079 
10080         group->addChild(subGroup.release());
10081     }
10082 
10083     // 1D to 2D tests.
10084     {
10085         // 1D to 2D copies
10086         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_2d"));
10087 
10088         TestParams params;
10089         params.src.image.imageType = VK_IMAGE_TYPE_1D;
10090         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10091         params.src.image.extent    = default1dExtent;
10092         params.dst.image.extent    = defaultRootExtent;
10093         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10094         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10095         params.src.image.fillMode  = FILL_MODE_WHITE;
10096         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10097         params.allocationKind      = testGroupParams->allocationKind;
10098         params.extensionFlags      = testGroupParams->extensionFlags;
10099         params.queueSelection      = testGroupParams->queueSelection;
10100         params.extensionFlags |= MAINTENANCE_5;
10101 
10102         for (uint32_t i = 0; i < defaultRootSize; ++i)
10103         {
10104             const VkImageCopy testCopy = {
10105                 defaultSourceLayer,                                // VkImageSubresourceLayers srcSubresource;
10106                 {static_cast<int32_t>(defaultRootSize * i), 0, 0}, // VkOffset3D srcOffset;
10107                 defaultSourceLayer,                                // VkImageSubresourceLayers dstSubresource;
10108                 {0, static_cast<int32_t>(i), 0},                   // VkOffset3D dstOffset;
10109                 {defaultRootSize, 1, 1},                           // VkExtent3D extent;
10110             };
10111 
10112             CopyRegion imageCopy;
10113             imageCopy.imageCopy = testCopy;
10114 
10115             params.regions.push_back(imageCopy);
10116         }
10117 
10118         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10119         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10120              ++compatibleFormatsIndex)
10121         {
10122             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10123             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10124             {
10125                 params.src.image.format = compatibleFormats[srcFormatIndex];
10126                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10127                     continue;
10128 
10129                 CopyColorTestParams testParams;
10130                 testParams.params            = params;
10131                 testParams.compatibleFormats = nullptr;
10132 
10133                 const std::string testName = getFormatCaseName(params.src.image.format);
10134                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10135             }
10136         }
10137 
10138         group->addChild(subGroup.release());
10139     }
10140 
10141     // 1D to 3D tests.
10142     {
10143         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_3d"));
10144 
10145         TestParams params;
10146         params.src.image.imageType = VK_IMAGE_TYPE_1D;
10147         params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10148         params.src.image.extent    = default1dExtent;
10149         params.dst.image.extent    = default3dSmallExtent;
10150         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10151         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10152         params.src.image.fillMode  = FILL_MODE_WHITE;
10153         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10154         params.allocationKind      = testGroupParams->allocationKind;
10155         params.extensionFlags      = testGroupParams->extensionFlags;
10156         params.queueSelection      = testGroupParams->queueSelection;
10157         params.extensionFlags |= MAINTENANCE_5;
10158 
10159         for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10160         {
10161             for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10162             {
10163                 const VkImageCopy testCopy = {
10164                     defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10165                     {i * defaultQuarterSize + j * defaultSixteenthSize, 0, 0}, // VkOffset3D srcOffset;
10166                     defaultSourceLayer,               // VkImageSubresourceLayers dstSubresource;
10167                     {0, j, i % defaultSixteenthSize}, // VkOffset3D dstOffset;
10168                     {defaultSixteenthSize, 1, 1},     // VkExtent3D extent;
10169                 };
10170 
10171                 CopyRegion imageCopy;
10172                 imageCopy.imageCopy = testCopy;
10173 
10174                 params.regions.push_back(imageCopy);
10175             }
10176         }
10177 
10178         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10179         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10180              ++compatibleFormatsIndex)
10181         {
10182             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10183             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10184             {
10185                 params.src.image.format = compatibleFormats[srcFormatIndex];
10186                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10187                     continue;
10188 
10189                 CopyColorTestParams testParams;
10190                 testParams.params            = params;
10191                 testParams.compatibleFormats = nullptr;
10192 
10193                 const std::string testName = getFormatCaseName(params.src.image.format);
10194                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10195             }
10196         }
10197 
10198         group->addChild(subGroup.release());
10199     }
10200 
10201     // 2D to 1D tests.
10202     {
10203         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_1d"));
10204 
10205         TestParams params;
10206         params.src.image.imageType = VK_IMAGE_TYPE_2D;
10207         params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10208         params.src.image.extent    = defaultQuarterExtent;
10209         params.dst.image.extent    = default1dQuarterSquaredExtent;
10210         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10211         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10212         params.src.image.fillMode  = FILL_MODE_WHITE;
10213         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10214         params.allocationKind      = testGroupParams->allocationKind;
10215         params.extensionFlags      = testGroupParams->extensionFlags;
10216         params.queueSelection      = testGroupParams->queueSelection;
10217         params.extensionFlags |= MAINTENANCE_5;
10218 
10219         for (int32_t i = 0; i < defaultQuarterSize; ++i)
10220         {
10221             const VkImageCopy testCopy = {
10222                 defaultSourceLayer,             // VkImageSubresourceLayers srcSubresource;
10223                 {0, i, 0},                      // VkOffset3D srcOffset;
10224                 defaultSourceLayer,             // VkImageSubresourceLayers dstSubresource;
10225                 {i * defaultQuarterSize, 0, 0}, // VkOffset3D dstOffset;
10226                 {defaultQuarterSize, 1, 1},     // VkExtent3D extent;
10227             };
10228 
10229             CopyRegion imageCopy;
10230             imageCopy.imageCopy = testCopy;
10231 
10232             params.regions.push_back(imageCopy);
10233         }
10234 
10235         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10236         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10237              ++compatibleFormatsIndex)
10238         {
10239             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10240             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10241             {
10242                 params.src.image.format = compatibleFormats[srcFormatIndex];
10243                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10244                     continue;
10245 
10246                 CopyColorTestParams testParams;
10247                 testParams.params            = params;
10248                 testParams.compatibleFormats = compatibleFormats;
10249 
10250                 const std::string testName = getFormatCaseName(params.src.image.format);
10251                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10252             }
10253         }
10254 
10255         group->addChild(subGroup.release());
10256     }
10257 
10258     // 2D to 2D tests.
10259     {
10260         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_2d"));
10261 
10262         TestParams params;
10263         params.src.image.imageType = VK_IMAGE_TYPE_2D;
10264         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10265         params.src.image.extent    = defaultExtent;
10266         params.dst.image.extent    = defaultExtent;
10267         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10268         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10269         params.src.image.fillMode  = FILL_MODE_WHITE;
10270         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10271         params.allocationKind      = testGroupParams->allocationKind;
10272         params.extensionFlags      = testGroupParams->extensionFlags;
10273         params.queueSelection      = testGroupParams->queueSelection;
10274 
10275         for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
10276         {
10277             const VkImageCopy testCopy = {
10278                 defaultSourceLayer,                           // VkImageSubresourceLayers srcSubresource;
10279                 {0, 0, 0},                                    // VkOffset3D srcOffset;
10280                 defaultSourceLayer,                           // VkImageSubresourceLayers dstSubresource;
10281                 {i, defaultSize - i - defaultQuarterSize, 0}, // VkOffset3D dstOffset;
10282                 {defaultQuarterSize, defaultQuarterSize, 1},  // VkExtent3D extent;
10283             };
10284 
10285             CopyRegion imageCopy;
10286             imageCopy.imageCopy = testCopy;
10287 
10288             params.regions.push_back(imageCopy);
10289         }
10290 
10291         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10292         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10293              ++compatibleFormatsIndex)
10294         {
10295             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10296             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10297             {
10298                 params.src.image.format = compatibleFormats[srcFormatIndex];
10299                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10300                     continue;
10301 
10302                 CopyColorTestParams testParams;
10303                 testParams.params            = params;
10304                 testParams.compatibleFormats = compatibleFormats;
10305 
10306                 const std::string testName = getFormatCaseName(params.src.image.format);
10307                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10308             }
10309         }
10310 
10311         group->addChild(subGroup.release());
10312     }
10313 
10314     // 2D to 3D tests.
10315     {
10316         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_3d"));
10317 
10318         TestParams params;
10319         params.src.image.imageType = VK_IMAGE_TYPE_2D;
10320         params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10321         params.src.image.extent    = defaultExtent;
10322         params.dst.image.extent    = default3dSmallExtent;
10323         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10324         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10325         params.src.image.fillMode  = FILL_MODE_WHITE;
10326         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10327         params.allocationKind      = testGroupParams->allocationKind;
10328         params.extensionFlags      = testGroupParams->extensionFlags;
10329         params.queueSelection      = testGroupParams->queueSelection;
10330         params.extensionFlags |= MAINTENANCE_1;
10331 
10332         for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10333         {
10334             const VkImageCopy testCopy = {
10335                 defaultSourceLayer,                                      // VkImageSubresourceLayers srcSubresource;
10336                 {i * defaultSixteenthSize, i % defaultSixteenthSize, 0}, // VkOffset3D srcOffset;
10337                 defaultSourceLayer,                                      // VkImageSubresourceLayers dstSubresource;
10338                 {0, 0, i},                                               // VkOffset3D dstOffset;
10339                 {defaultSixteenthSize, defaultSixteenthSize, 1},         // VkExtent3D extent;
10340             };
10341 
10342             CopyRegion imageCopy;
10343             imageCopy.imageCopy = testCopy;
10344 
10345             params.regions.push_back(imageCopy);
10346         }
10347 
10348         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10349         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10350              ++compatibleFormatsIndex)
10351         {
10352             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10353             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10354             {
10355                 params.src.image.format = compatibleFormats[srcFormatIndex];
10356                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10357                     continue;
10358 
10359                 CopyColorTestParams testParams;
10360                 testParams.params            = params;
10361                 testParams.compatibleFormats = compatibleFormats;
10362 
10363                 const std::string testName = getFormatCaseName(params.src.image.format);
10364                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10365             }
10366         }
10367 
10368         group->addChild(subGroup.release());
10369     }
10370 
10371     // 3D to 1D tests.
10372     {
10373         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_1d"));
10374 
10375         TestParams params;
10376         params.src.image.imageType = VK_IMAGE_TYPE_3D;
10377         params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10378         params.src.image.extent    = default3dSmallExtent;
10379         params.dst.image.extent    = default1dExtent;
10380         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10381         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10382         params.src.image.fillMode  = FILL_MODE_WHITE;
10383         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10384         params.allocationKind      = testGroupParams->allocationKind;
10385         params.extensionFlags      = testGroupParams->extensionFlags;
10386         params.queueSelection      = testGroupParams->queueSelection;
10387         params.extensionFlags |= MAINTENANCE_5;
10388 
10389         for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10390         {
10391             for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10392             {
10393                 const VkImageCopy testCopy = {
10394                     defaultSourceLayer,                                      // VkImageSubresourceLayers srcSubresource;
10395                     {0, j % defaultSixteenthSize, i % defaultSixteenthSize}, // VkOffset3D srcOffset;
10396                     defaultSourceLayer,                                      // VkImageSubresourceLayers dstSubresource;
10397                     {j * defaultSixteenthSize + i * defaultQuarterSize, 0, 0}, // VkOffset3D dstOffset;
10398                     {defaultSixteenthSize, 1, 1},                              // VkExtent3D extent;
10399                 };
10400 
10401                 CopyRegion imageCopy;
10402                 imageCopy.imageCopy = testCopy;
10403 
10404                 params.regions.push_back(imageCopy);
10405             }
10406         }
10407 
10408         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10409         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10410              ++compatibleFormatsIndex)
10411         {
10412             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10413             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10414             {
10415                 params.src.image.format = compatibleFormats[srcFormatIndex];
10416                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10417                     continue;
10418 
10419                 CopyColorTestParams testParams;
10420                 testParams.params            = params;
10421                 testParams.compatibleFormats = nullptr;
10422 
10423                 const std::string testName = getFormatCaseName(params.src.image.format);
10424                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10425             }
10426         }
10427 
10428         group->addChild(subGroup.release());
10429     }
10430 
10431     // 3D to 2D tests.
10432     {
10433         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_2d"));
10434 
10435         TestParams params;
10436         params.src.image.imageType = VK_IMAGE_TYPE_3D;
10437         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10438         params.src.image.extent    = default3dExtent;
10439         params.dst.image.extent    = defaultExtent;
10440         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10441         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10442         params.src.image.fillMode  = FILL_MODE_WHITE;
10443         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10444         params.allocationKind      = testGroupParams->allocationKind;
10445         params.extensionFlags      = testGroupParams->extensionFlags;
10446         params.queueSelection      = testGroupParams->queueSelection;
10447         params.extensionFlags |= MAINTENANCE_1;
10448 
10449         for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10450         {
10451             for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10452             {
10453                 const VkImageCopy testCopy = {
10454                     defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
10455                     {0, 0, i * defaultSixteenthSize + j},                // VkOffset3D srcOffset;
10456                     defaultSourceLayer,                                  // VkImageSubresourceLayers dstSubresource;
10457                     {j * defaultQuarterSize, i * defaultQuarterSize, 0}, // VkOffset3D dstOffset;
10458                     {defaultQuarterSize, defaultQuarterSize, 1},         // VkExtent3D extent;
10459                 };
10460 
10461                 CopyRegion imageCopy;
10462                 imageCopy.imageCopy = testCopy;
10463 
10464                 params.regions.push_back(imageCopy);
10465             }
10466         }
10467 
10468         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10469         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10470              ++compatibleFormatsIndex)
10471         {
10472             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10473             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10474             {
10475                 params.src.image.format = compatibleFormats[srcFormatIndex];
10476                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10477                     continue;
10478 
10479                 CopyColorTestParams testParams;
10480                 testParams.params            = params;
10481                 testParams.compatibleFormats = nullptr;
10482 
10483                 const std::string testName = getFormatCaseName(params.src.image.format);
10484                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10485             }
10486         }
10487 
10488         group->addChild(subGroup.release());
10489     }
10490 
10491     // 3D to 3D tests. Note we use smaller dimensions here for performance reasons.
10492     {
10493         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_3d"));
10494 
10495         TestParams params;
10496         params.src.image.imageType = VK_IMAGE_TYPE_3D;
10497         params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10498         params.src.image.extent    = default3dExtent;
10499         params.dst.image.extent    = default3dExtent;
10500         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10501         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10502         params.src.image.fillMode  = FILL_MODE_WHITE;
10503         params.dst.image.fillMode  = FILL_MODE_GRADIENT;
10504         params.allocationKind      = testGroupParams->allocationKind;
10505         params.extensionFlags      = testGroupParams->extensionFlags;
10506         params.queueSelection      = testGroupParams->queueSelection;
10507 
10508         for (int32_t i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
10509         {
10510             const VkImageCopy testCopy = {
10511                 defaultSourceLayer,                                    // VkImageSubresourceLayers srcSubresource;
10512                 {0, 0, 0},                                             // VkOffset3D srcOffset;
10513                 defaultSourceLayer,                                    // VkImageSubresourceLayers dstSubresource;
10514                 {i, defaultQuarterSize - i - defaultSixteenthSize, i}, // VkOffset3D dstOffset;
10515                 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize}, // VkExtent3D extent;
10516             };
10517 
10518             CopyRegion imageCopy;
10519             imageCopy.imageCopy = testCopy;
10520 
10521             params.regions.push_back(imageCopy);
10522         }
10523 
10524         const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
10525         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
10526              ++compatibleFormatsIndex)
10527         {
10528             const VkFormat *compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
10529             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
10530             {
10531                 params.src.image.format = compatibleFormats[srcFormatIndex];
10532                 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
10533                     continue;
10534 
10535                 CopyColorTestParams testParams;
10536                 testParams.params            = params;
10537                 testParams.compatibleFormats = nullptr;
10538 
10539                 const std::string testName = getFormatCaseName(params.src.image.format);
10540                 addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsColorSrcFormatTests, testParams);
10541             }
10542         }
10543 
10544         group->addChild(subGroup.release());
10545     }
10546 }
10547 
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10548 void addImageToImageDimensionsTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10549 {
10550     tcu::TestContext &testCtx = group->getTestContext();
10551 
10552     const VkFormat testFormats[][2] = {// From compatibleFormats8Bit
10553                                        {VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R8_SRGB},
10554                                        // From compatibleFormats16Bit
10555                                        {
10556                                            VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10557                                            VK_FORMAT_R16_SFLOAT,
10558                                        },
10559                                        // From compatibleFormats24Bit
10560                                        {VK_FORMAT_R8G8B8_UNORM, VK_FORMAT_B8G8R8_SRGB},
10561                                        // From compatibleFormats32Bit
10562                                        {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R32_SFLOAT},
10563                                        // From compatibleFormats48Bit
10564                                        {VK_FORMAT_R16G16B16_UNORM, VK_FORMAT_R16G16B16_SFLOAT},
10565                                        // From compatibleFormats64Bit
10566                                        {VK_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R64_SFLOAT},
10567                                        // From compatibleFormats96Bit
10568                                        {VK_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_SFLOAT},
10569                                        // From compatibleFormats128Bit
10570                                        {VK_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R64G64_SFLOAT},
10571                                        // From compatibleFormats192Bit
10572                                        {
10573                                            VK_FORMAT_R64G64B64_UINT,
10574                                            VK_FORMAT_R64G64B64_SFLOAT,
10575                                        },
10576                                        // From compatibleFormats256Bit
10577                                        {VK_FORMAT_R64G64B64A64_UINT, VK_FORMAT_R64G64B64A64_SFLOAT}};
10578 
10579     const tcu::UVec2 imageDimensions[] = {
10580         // large pot x small pot
10581         tcu::UVec2(4096, 4u), tcu::UVec2(8192, 4u), tcu::UVec2(16384, 4u), tcu::UVec2(32768, 4u),
10582 
10583         // large pot x small npot
10584         tcu::UVec2(4096, 6u), tcu::UVec2(8192, 6u), tcu::UVec2(16384, 6u), tcu::UVec2(32768, 6u),
10585 
10586         // small pot x large pot
10587         tcu::UVec2(4u, 4096), tcu::UVec2(4u, 8192), tcu::UVec2(4u, 16384), tcu::UVec2(4u, 32768),
10588 
10589         // small npot x large pot
10590         tcu::UVec2(6u, 4096), tcu::UVec2(6u, 8192), tcu::UVec2(6u, 16384), tcu::UVec2(6u, 32768)};
10591 
10592     const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10593 
10594     const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10595 
10596     if (testGroupParams->allocationKind == ALLOCATION_KIND_DEDICATED)
10597     {
10598         for (int compatibleFormatsIndex = 0;
10599              compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
10600              compatibleFormatsIndex++)
10601             dedicatedAllocationImageToImageFormatsToTestSet.insert(
10602                 dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
10603     }
10604 
10605     // Image dimensions
10606     for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
10607     {
10608         CopyRegion copyRegion;
10609         CopyColorTestParams testParams;
10610 
10611         const VkExtent3D extent = {imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1};
10612 
10613         const VkImageCopy testCopy = {
10614             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10615             {0, 0, 0},          // VkOffset3D srcOffset;
10616             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10617             {0, 0, 0},          // VkOffset3D dstOffset;
10618             extent,             // VkExtent3D extent;
10619         };
10620 
10621         testParams.params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10622         testParams.params.src.image.imageType = VK_IMAGE_TYPE_2D;
10623         testParams.params.src.image.extent    = extent;
10624 
10625         testParams.params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10626         testParams.params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10627         testParams.params.dst.image.extent    = extent;
10628 
10629         copyRegion.imageCopy               = testCopy;
10630         testParams.params.allocationKind   = testGroupParams->allocationKind;
10631         testParams.params.extensionFlags   = testGroupParams->extensionFlags;
10632         testParams.params.queueSelection   = testGroupParams->queueSelection;
10633         testParams.params.useSparseBinding = testGroupParams->useSparseBinding;
10634 
10635         testParams.params.regions.push_back(copyRegion);
10636 
10637         const std::string dimensionStr = "src" + de::toString(testParams.params.src.image.extent.width) + "x" +
10638                                          de::toString(testParams.params.src.image.extent.height) + "_dst" +
10639                                          de::toString(testParams.params.dst.image.extent.width) + "x" +
10640                                          de::toString(testParams.params.dst.image.extent.height);
10641         tcu::TestCaseGroup *imageSizeGroup = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str());
10642 
10643         // Compatible formats for copying
10644         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats);
10645              compatibleFormatsIndex++)
10646         {
10647             const VkFormat *compatibleFormats = testFormats[compatibleFormatsIndex];
10648 
10649             testParams.compatibleFormats = compatibleFormats;
10650 
10651             // Source image format
10652             for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]);
10653                  srcFormatIndex++)
10654             {
10655                 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
10656 
10657                 if (!isSupportedByFramework(testParams.params.src.image.format) &&
10658                     !isCompressedFormat(testParams.params.src.image.format))
10659                     continue;
10660 
10661                 tcu::TestCaseGroup *srcFormatGroup =
10662                     new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str());
10663 
10664                 // Destination image format
10665                 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]);
10666                      dstFormatIndex++)
10667                 {
10668                     testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
10669 
10670                     if (!isSupportedByFramework(testParams.params.dst.image.format) &&
10671                         !isCompressedFormat(testParams.params.dst.image.format))
10672                         continue;
10673 
10674                     if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
10675                         continue;
10676 
10677                     if (isCompressedFormat(testParams.params.src.image.format) &&
10678                         isCompressedFormat(testParams.params.dst.image.format))
10679                     {
10680                         if ((getBlockWidth(testParams.params.src.image.format) !=
10681                              getBlockWidth(testParams.params.dst.image.format)) ||
10682                             (getBlockHeight(testParams.params.src.image.format) !=
10683                              getBlockHeight(testParams.params.dst.image.format)))
10684                             continue;
10685                     }
10686 
10687                     tcu::TestCaseGroup *dstFormatGroup =
10688                         new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str());
10689 
10690                     // Source/destionation image layouts
10691                     for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
10692                     {
10693                         testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
10694 
10695                         for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
10696                         {
10697                             testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
10698 
10699                             const std::string testName =
10700                                 getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
10701                                 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
10702                             const TestParams params = testParams.params;
10703 
10704                             dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, params));
10705                         }
10706                     }
10707 
10708                     srcFormatGroup->addChild(dstFormatGroup);
10709                 }
10710 
10711                 imageSizeGroup->addChild(srcFormatGroup);
10712             }
10713         }
10714 
10715         group->addChild(imageSizeGroup);
10716     }
10717 }
10718 
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)10719 void addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup *group, TestParams params)
10720 {
10721     const VkImageLayout copySrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10722     const VkImageLayout copyDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
10723 
10724     for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
10725     {
10726         params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
10727         for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
10728         {
10729             params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
10730 
10731             const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
10732                                          getImageLayoutCaseName(params.dst.image.operationLayout);
10733             group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, params));
10734         }
10735     }
10736 }
10737 
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)10738 void addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
10739 {
10740     const VkFormat depthAndStencilFormats[] = {
10741         VK_FORMAT_D16_UNORM,         VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT,         VK_FORMAT_S8_UINT,
10742         VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,   VK_FORMAT_D32_SFLOAT_S8_UINT,
10743     };
10744 
10745     // 1D to 1D tests.
10746     {
10747         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_1d"));
10748 
10749         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10750              ++compatibleFormatsIndex)
10751         {
10752             TestParams params;
10753             params.src.image.imageType = VK_IMAGE_TYPE_1D;
10754             params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10755             params.src.image.extent    = default1dExtent;
10756             params.dst.image.extent    = default1dExtent;
10757             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
10758             params.dst.image.format    = params.src.image.format;
10759             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10760             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10761             params.allocationKind      = testGroupParams->allocationKind;
10762             params.extensionFlags      = testGroupParams->extensionFlags;
10763             params.queueSelection      = testGroupParams->queueSelection;
10764             params.useSparseBinding    = testGroupParams->useSparseBinding;
10765 
10766             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10767             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10768 
10769             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10770             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10771 
10772             for (int32_t i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
10773             {
10774                 CopyRegion copyRegion;
10775                 const VkOffset3D srcOffset = {0, 0, 0};
10776                 const VkOffset3D dstOffset = {i, 0, 0};
10777                 const VkExtent3D extent    = {defaultQuarterSize, 1, 1};
10778 
10779                 if (hasDepth)
10780                 {
10781                     const VkImageCopy testCopy = {
10782                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10783                         srcOffset,               // VkOffset3D srcOffset;
10784                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10785                         dstOffset,               // VkOffset3D dstOffset;
10786                         extent,                  // VkExtent3D extent;
10787                     };
10788 
10789                     copyRegion.imageCopy = testCopy;
10790                     params.regions.push_back(copyRegion);
10791                 }
10792                 if (hasStencil)
10793                 {
10794                     const VkImageCopy testCopy = {
10795                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10796                         srcOffset,                 // VkOffset3D srcOffset;
10797                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10798                         dstOffset,                 // VkOffset3D dstOffset;
10799                         extent,                    // VkExtent3D extent;
10800                     };
10801 
10802                     copyRegion.imageCopy = testCopy;
10803                     params.regions.push_back(copyRegion);
10804                 }
10805             }
10806 
10807             const std::string testName =
10808                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10809             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10810 
10811             if (hasDepth && hasStencil)
10812             {
10813                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10814                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10815                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10816                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10817             }
10818         }
10819 
10820         group->addChild(subGroup.release());
10821     }
10822 
10823     // 1D to 2D tests.
10824     {
10825         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_2d"));
10826 
10827         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10828              ++compatibleFormatsIndex)
10829         {
10830             TestParams params;
10831             params.src.image.imageType = VK_IMAGE_TYPE_1D;
10832             params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10833             params.src.image.extent    = default1dExtent;
10834             params.dst.image.extent    = defaultRootExtent;
10835             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
10836             params.dst.image.format    = params.src.image.format;
10837             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10838             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10839             params.allocationKind      = testGroupParams->allocationKind;
10840             params.extensionFlags      = testGroupParams->extensionFlags;
10841             params.queueSelection      = testGroupParams->queueSelection;
10842             params.useSparseBinding    = testGroupParams->useSparseBinding;
10843             params.extensionFlags |= MAINTENANCE_5;
10844 
10845             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10846             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10847 
10848             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10849             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10850 
10851             for (uint32_t i = 0; i < defaultRootSize; ++i)
10852             {
10853                 CopyRegion copyRegion;
10854                 const VkOffset3D srcOffset = {static_cast<int32_t>(i * defaultRootSize), 0, 0};
10855                 const VkOffset3D dstOffset = {0, static_cast<int32_t>(i), 0};
10856                 const VkExtent3D extent    = {defaultRootSize, 1, 1};
10857 
10858                 if (hasDepth)
10859                 {
10860                     const VkImageCopy testCopy = {
10861                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10862                         srcOffset,               // VkOffset3D srcOffset;
10863                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10864                         dstOffset,               // VkOffset3D dstOffset;
10865                         extent,                  // VkExtent3D extent;
10866                     };
10867 
10868                     copyRegion.imageCopy = testCopy;
10869                     params.regions.push_back(copyRegion);
10870                 }
10871                 if (hasStencil)
10872                 {
10873                     const VkImageCopy testCopy = {
10874                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10875                         srcOffset,                 // VkOffset3D srcOffset;
10876                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10877                         dstOffset,                 // VkOffset3D dstOffset;
10878                         extent,                    // VkExtent3D extent;
10879                     };
10880 
10881                     copyRegion.imageCopy = testCopy;
10882                     params.regions.push_back(copyRegion);
10883                 }
10884             }
10885 
10886             const std::string testName =
10887                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10888             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10889 
10890             if (hasDepth && hasStencil)
10891             {
10892                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10893                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10894                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10895                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10896             }
10897         }
10898 
10899         group->addChild(subGroup.release());
10900     }
10901 
10902     // 1D to 3D tests.
10903     {
10904         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d_to_3d"));
10905 
10906         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10907              ++compatibleFormatsIndex)
10908         {
10909             TestParams params;
10910             params.src.image.imageType = VK_IMAGE_TYPE_1D;
10911             params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10912             params.src.image.extent    = default1dExtent;
10913             params.dst.image.extent    = default3dSmallExtent;
10914             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
10915             params.dst.image.format    = params.src.image.format;
10916             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10917             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10918             params.allocationKind      = testGroupParams->allocationKind;
10919             params.extensionFlags      = testGroupParams->extensionFlags;
10920             params.queueSelection      = testGroupParams->queueSelection;
10921             params.useSparseBinding    = testGroupParams->useSparseBinding;
10922             params.extensionFlags |= MAINTENANCE_5;
10923 
10924             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
10925             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
10926 
10927             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
10928             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
10929 
10930             for (int32_t i = 0; i < defaultSixteenthSize; ++i)
10931             {
10932                 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
10933                 {
10934                     CopyRegion copyRegion;
10935                     const VkOffset3D srcOffset = {i * defaultQuarterSize + j * defaultSixteenthSize, 0, 0};
10936                     const VkOffset3D dstOffset = {0, j, i};
10937                     const VkExtent3D extent    = {defaultSixteenthSize, 1, 1};
10938 
10939                     if (hasDepth)
10940                     {
10941                         const VkImageCopy testCopy = {
10942                             defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
10943                             srcOffset,               // VkOffset3D srcOffset;
10944                             defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
10945                             dstOffset,               // VkOffset3D dstOffset;
10946                             extent,                  // VkExtent3D extent;
10947                         };
10948 
10949                         copyRegion.imageCopy = testCopy;
10950                         params.regions.push_back(copyRegion);
10951                     }
10952                     if (hasStencil)
10953                     {
10954                         const VkImageCopy testCopy = {
10955                             defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
10956                             srcOffset,                 // VkOffset3D srcOffset;
10957                             defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
10958                             dstOffset,                 // VkOffset3D dstOffset;
10959                             extent,                    // VkExtent3D extent;
10960                         };
10961 
10962                         copyRegion.imageCopy = testCopy;
10963                         params.regions.push_back(copyRegion);
10964                     }
10965                 }
10966             }
10967 
10968             const std::string testName =
10969                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
10970             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10971 
10972             if (hasDepth && hasStencil)
10973             {
10974                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
10975                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
10976                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
10977                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
10978             }
10979         }
10980 
10981         group->addChild(subGroup.release());
10982     }
10983 
10984     // 2D to 1D tests.
10985     {
10986         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_1d"));
10987 
10988         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
10989              ++compatibleFormatsIndex)
10990         {
10991             TestParams params;
10992             params.src.image.imageType = VK_IMAGE_TYPE_2D;
10993             params.dst.image.imageType = VK_IMAGE_TYPE_1D;
10994             params.src.image.extent    = defaultQuarterExtent;
10995             params.dst.image.extent    = default1dQuarterSquaredExtent;
10996             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
10997             params.dst.image.format    = params.src.image.format;
10998             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
10999             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11000             params.allocationKind      = testGroupParams->allocationKind;
11001             params.extensionFlags      = testGroupParams->extensionFlags;
11002             params.queueSelection      = testGroupParams->queueSelection;
11003             params.useSparseBinding    = testGroupParams->useSparseBinding;
11004             params.extensionFlags |= MAINTENANCE_5;
11005 
11006             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11007             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11008 
11009             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11010             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11011             const VkImageSubresourceLayers defaultDSSourceLayer      = {
11012                 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11013 
11014             for (int32_t i = 0; i < defaultQuarterSize; ++i)
11015             {
11016                 CopyRegion copyRegion;
11017                 const VkOffset3D srcOffset = {0, i, 0};
11018                 const VkOffset3D dstOffset = {i * defaultQuarterSize, 0, 0};
11019                 const VkExtent3D extent    = {defaultQuarterSize, 1, 1};
11020 
11021                 if (hasDepth)
11022                 {
11023                     const VkImageCopy testCopy = {
11024                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11025                         srcOffset,               // VkOffset3D srcOffset;
11026                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11027                         dstOffset,               // VkOffset3D dstOffset;
11028                         extent,                  // VkExtent3D extent;
11029                     };
11030 
11031                     copyRegion.imageCopy = testCopy;
11032                     params.regions.push_back(copyRegion);
11033                 }
11034                 if (hasStencil)
11035                 {
11036                     const VkImageCopy testCopy = {
11037                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11038                         srcOffset,                 // VkOffset3D srcOffset;
11039                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11040                         dstOffset,                 // VkOffset3D dstOffset;
11041                         extent,                    // VkExtent3D extent;
11042                     };
11043 
11044                     copyRegion.imageCopy = testCopy;
11045                     params.regions.push_back(copyRegion);
11046                 }
11047             }
11048 
11049             const std::string testName =
11050                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11051             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11052 
11053             if (hasDepth && hasStencil)
11054             {
11055                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11056                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11057                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11058                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11059 
11060                 // DS Image copy
11061                 {
11062                     params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11063                     // Clear previous vkImageCopy elements
11064                     params.regions.clear();
11065 
11066                     for (int32_t i = 0; i < defaultQuarterSize; ++i)
11067                     {
11068                         CopyRegion copyRegion;
11069                         const VkOffset3D srcOffset = {0, i, 0};
11070                         const VkOffset3D dstOffset = {i * defaultQuarterSize, 0, 0};
11071                         const VkExtent3D extent    = {defaultQuarterSize, 1, 1};
11072 
11073                         const VkImageCopy testCopy = {
11074                             defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11075                             srcOffset,            // VkOffset3D srcOffset;
11076                             defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11077                             dstOffset,            // VkOffset3D dstOffset;
11078                             extent,               // VkExtent3D extent;
11079                         };
11080 
11081                         copyRegion.imageCopy = testCopy;
11082                         params.regions.push_back(copyRegion);
11083                     }
11084 
11085                     const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11086                                                   getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11087                     addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11088                 }
11089             }
11090         }
11091 
11092         group->addChild(subGroup.release());
11093     }
11094 
11095     // 2D to 2D tests.
11096     {
11097         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_2d"));
11098 
11099         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11100              ++compatibleFormatsIndex)
11101         {
11102             TestParams params;
11103             params.src.image.imageType = VK_IMAGE_TYPE_2D;
11104             params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11105             params.src.image.extent    = defaultExtent;
11106             params.dst.image.extent    = defaultExtent;
11107             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
11108             params.dst.image.format    = params.src.image.format;
11109             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11110             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11111             params.allocationKind      = testGroupParams->allocationKind;
11112             params.extensionFlags      = testGroupParams->extensionFlags;
11113             params.queueSelection      = testGroupParams->queueSelection;
11114             params.useSparseBinding    = testGroupParams->useSparseBinding;
11115 
11116             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11117             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11118 
11119             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11120             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11121             const VkImageSubresourceLayers defaultDSSourceLayer      = {
11122                 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11123 
11124             for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
11125             {
11126                 CopyRegion copyRegion;
11127                 const VkOffset3D srcOffset = {0, 0, 0};
11128                 const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
11129                 const VkExtent3D extent    = {defaultQuarterSize, defaultQuarterSize, 1};
11130 
11131                 if (hasDepth)
11132                 {
11133                     const VkImageCopy testCopy = {
11134                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11135                         srcOffset,               // VkOffset3D srcOffset;
11136                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11137                         dstOffset,               // VkOffset3D dstOffset;
11138                         extent,                  // VkExtent3D extent;
11139                     };
11140 
11141                     copyRegion.imageCopy = testCopy;
11142                     params.regions.push_back(copyRegion);
11143                 }
11144                 if (hasStencil)
11145                 {
11146                     const VkImageCopy testCopy = {
11147                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11148                         srcOffset,                 // VkOffset3D srcOffset;
11149                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11150                         dstOffset,                 // VkOffset3D dstOffset;
11151                         extent,                    // VkExtent3D extent;
11152                     };
11153 
11154                     copyRegion.imageCopy = testCopy;
11155                     params.regions.push_back(copyRegion);
11156                 }
11157             }
11158 
11159             const std::string testName =
11160                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11161             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11162 
11163             if (hasDepth && hasStencil)
11164             {
11165                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11166                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11167                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11168                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11169 
11170                 // DS Image copy
11171                 {
11172                     params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11173                     // Clear previous vkImageCopy elements
11174                     params.regions.clear();
11175 
11176                     for (int32_t i = 0; i < defaultSize; i += defaultQuarterSize)
11177                     {
11178                         CopyRegion copyRegion;
11179                         const VkOffset3D srcOffset = {0, 0, 0};
11180                         const VkOffset3D dstOffset = {i, defaultSize - i - defaultQuarterSize, 0};
11181                         const VkExtent3D extent    = {defaultQuarterSize, defaultQuarterSize, 1};
11182 
11183                         const VkImageCopy testCopy = {
11184                             defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11185                             srcOffset,            // VkOffset3D srcOffset;
11186                             defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11187                             dstOffset,            // VkOffset3D dstOffset;
11188                             extent,               // VkExtent3D extent;
11189                         };
11190 
11191                         copyRegion.imageCopy = testCopy;
11192                         params.regions.push_back(copyRegion);
11193                     }
11194 
11195                     const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11196                                                   getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11197                     addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11198                 }
11199             }
11200         }
11201 
11202         group->addChild(subGroup.release());
11203     }
11204 
11205     // 2D to 3D tests.
11206     {
11207         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d_to_3d"));
11208 
11209         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11210              ++compatibleFormatsIndex)
11211         {
11212             TestParams params;
11213             params.src.image.imageType = VK_IMAGE_TYPE_2D;
11214             params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11215             params.src.image.extent    = defaultExtent;
11216             params.dst.image.extent    = default3dSmallExtent;
11217             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
11218             params.dst.image.format    = params.src.image.format;
11219             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11220             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11221             params.allocationKind      = testGroupParams->allocationKind;
11222             params.extensionFlags      = testGroupParams->extensionFlags;
11223             params.queueSelection      = testGroupParams->queueSelection;
11224             params.useSparseBinding    = testGroupParams->useSparseBinding;
11225             params.extensionFlags |= MAINTENANCE_1;
11226 
11227             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11228             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11229 
11230             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11231             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11232             const VkImageSubresourceLayers defaultDSSourceLayer      = {
11233                 VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11234 
11235             for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11236             {
11237                 CopyRegion copyRegion;
11238                 const VkOffset3D srcOffset = {i * defaultSixteenthSize, i % defaultSixteenthSize, 0};
11239                 const VkOffset3D dstOffset = {0, 0, i};
11240                 const VkExtent3D extent    = {defaultSixteenthSize, defaultSixteenthSize, 1};
11241 
11242                 if (hasDepth)
11243                 {
11244                     const VkImageCopy testCopy = {
11245                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11246                         srcOffset,               // VkOffset3D srcOffset;
11247                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11248                         dstOffset,               // VkOffset3D dstOffset;
11249                         extent,                  // VkExtent3D extent;
11250                     };
11251 
11252                     copyRegion.imageCopy = testCopy;
11253                     params.regions.push_back(copyRegion);
11254                 }
11255                 if (hasStencil)
11256                 {
11257                     const VkImageCopy testCopy = {
11258                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11259                         srcOffset,                 // VkOffset3D srcOffset;
11260                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11261                         dstOffset,                 // VkOffset3D dstOffset;
11262                         extent,                    // VkExtent3D extent;
11263                     };
11264 
11265                     copyRegion.imageCopy = testCopy;
11266                     params.regions.push_back(copyRegion);
11267                 }
11268             }
11269 
11270             const std::string testName =
11271                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11272             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11273 
11274             if (hasDepth && hasStencil)
11275             {
11276                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11277                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11278                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11279                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11280 
11281                 // DS Image copy
11282                 {
11283                     params.extensionFlags &= ~SEPARATE_DEPTH_STENCIL_LAYOUT;
11284                     // Clear previous vkImageCopy elements
11285                     params.regions.clear();
11286 
11287                     for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11288                     {
11289                         CopyRegion copyRegion;
11290                         const VkOffset3D srcOffset = {i * defaultSixteenthSize, i % defaultSixteenthSize, 0};
11291                         const VkOffset3D dstOffset = {0, 0, i};
11292                         const VkExtent3D extent    = {defaultSixteenthSize, defaultSixteenthSize, 1};
11293 
11294                         const VkImageCopy testCopy = {
11295                             defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11296                             srcOffset,            // VkOffset3D srcOffset;
11297                             defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11298                             dstOffset,            // VkOffset3D dstOffset;
11299                             extent,               // VkExtent3D extent;
11300                         };
11301 
11302                         copyRegion.imageCopy = testCopy;
11303                         params.regions.push_back(copyRegion);
11304                     }
11305 
11306                     const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" +
11307                                                   getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
11308                     addTestGroup(subGroup.get(), testName3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11309                 }
11310             }
11311         }
11312 
11313         group->addChild(subGroup.release());
11314     }
11315 
11316     // 3D to 1D tests.
11317     {
11318         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_1d"));
11319 
11320         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11321              ++compatibleFormatsIndex)
11322         {
11323             TestParams params;
11324             params.src.image.imageType = VK_IMAGE_TYPE_3D;
11325             params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11326             params.src.image.extent    = default3dSmallExtent;
11327             params.dst.image.extent    = default1dExtent;
11328             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
11329             params.dst.image.format    = params.src.image.format;
11330             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11331             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11332             params.allocationKind      = testGroupParams->allocationKind;
11333             params.extensionFlags      = testGroupParams->extensionFlags;
11334             params.queueSelection      = testGroupParams->queueSelection;
11335             params.useSparseBinding    = testGroupParams->useSparseBinding;
11336             params.extensionFlags |= MAINTENANCE_5;
11337 
11338             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11339             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11340 
11341             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11342             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11343 
11344             for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11345             {
11346                 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
11347                 {
11348                     CopyRegion copyRegion;
11349                     const VkOffset3D srcOffset = {0, j % defaultSixteenthSize, i % defaultSixteenthSize};
11350                     const VkOffset3D dstOffset = {j * defaultSixteenthSize + i * defaultQuarterSize, 0, 0};
11351                     const VkExtent3D extent    = {defaultSixteenthSize, 1, 1};
11352 
11353                     if (hasDepth)
11354                     {
11355                         const VkImageCopy testCopy = {
11356                             defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11357                             srcOffset,               // VkOffset3D srcOffset;
11358                             defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11359                             dstOffset,               // VkOffset3D dstOffset;
11360                             extent,                  // VkExtent3D extent;
11361                         };
11362 
11363                         copyRegion.imageCopy = testCopy;
11364                         params.regions.push_back(copyRegion);
11365                     }
11366                     if (hasStencil)
11367                     {
11368                         const VkImageCopy testCopy = {
11369                             defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11370                             srcOffset,                 // VkOffset3D srcOffset;
11371                             defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11372                             dstOffset,                 // VkOffset3D dstOffset;
11373                             extent,                    // VkExtent3D extent;
11374                         };
11375 
11376                         copyRegion.imageCopy = testCopy;
11377                         params.regions.push_back(copyRegion);
11378                     }
11379                 }
11380             }
11381 
11382             const std::string testName =
11383                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11384             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11385 
11386             if (hasDepth && hasStencil)
11387             {
11388                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11389                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11390                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11391                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11392             }
11393         }
11394 
11395         group->addChild(subGroup.release());
11396     }
11397 
11398     // 3D to 2D tests.
11399     {
11400         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_2d"));
11401 
11402         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11403              ++compatibleFormatsIndex)
11404         {
11405             TestParams params;
11406             params.src.image.imageType = VK_IMAGE_TYPE_3D;
11407             params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11408             params.src.image.extent    = default3dExtent;
11409             params.dst.image.extent    = defaultExtent;
11410             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
11411             params.dst.image.format    = params.src.image.format;
11412             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11413             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11414             params.allocationKind      = testGroupParams->allocationKind;
11415             params.extensionFlags      = testGroupParams->extensionFlags;
11416             params.queueSelection      = testGroupParams->queueSelection;
11417             params.useSparseBinding    = testGroupParams->useSparseBinding;
11418             params.extensionFlags |= MAINTENANCE_1;
11419 
11420             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11421             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11422 
11423             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11424             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11425 
11426             for (int32_t i = 0; i < defaultSixteenthSize; ++i)
11427             {
11428                 for (int32_t j = 0; j < defaultSixteenthSize; ++j)
11429                 {
11430                     CopyRegion copyRegion;
11431                     const VkOffset3D srcOffset = {0, 0, i % defaultSixteenthSize + j};
11432                     const VkOffset3D dstOffset = {j * defaultQuarterSize, i * defaultQuarterSize, 0};
11433                     const VkExtent3D extent    = {defaultQuarterSize, defaultQuarterSize, 1};
11434 
11435                     if (hasDepth)
11436                     {
11437                         const VkImageCopy testCopy = {
11438                             defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11439                             srcOffset,               // VkOffset3D srcOffset;
11440                             defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11441                             dstOffset,               // VkOffset3D dstOffset;
11442                             extent,                  // VkExtent3D extent;
11443                         };
11444 
11445                         copyRegion.imageCopy = testCopy;
11446                         params.regions.push_back(copyRegion);
11447                     }
11448                     if (hasStencil)
11449                     {
11450                         const VkImageCopy testCopy = {
11451                             defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11452                             srcOffset,                 // VkOffset3D srcOffset;
11453                             defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11454                             dstOffset,                 // VkOffset3D dstOffset;
11455                             extent,                    // VkExtent3D extent;
11456                         };
11457 
11458                         copyRegion.imageCopy = testCopy;
11459                         params.regions.push_back(copyRegion);
11460                     }
11461                 }
11462             }
11463 
11464             const std::string testName =
11465                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11466             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11467 
11468             if (hasDepth && hasStencil)
11469             {
11470                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11471                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11472                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11473                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11474             }
11475         }
11476 
11477         group->addChild(subGroup.release());
11478     }
11479 
11480     // 3D tests. Note we use smaller dimensions here for performance reasons.
11481     {
11482         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d_to_3d"));
11483 
11484         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
11485              ++compatibleFormatsIndex)
11486         {
11487             TestParams params;
11488             params.src.image.imageType = VK_IMAGE_TYPE_3D;
11489             params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11490             params.src.image.extent    = default3dExtent;
11491             params.dst.image.extent    = default3dExtent;
11492             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
11493             params.dst.image.format    = params.src.image.format;
11494             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11495             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
11496             params.allocationKind      = testGroupParams->allocationKind;
11497             params.extensionFlags      = testGroupParams->extensionFlags;
11498             params.queueSelection      = testGroupParams->queueSelection;
11499             params.useSparseBinding    = testGroupParams->useSparseBinding;
11500 
11501             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11502             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11503 
11504             const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
11505             const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
11506 
11507             for (int32_t i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
11508             {
11509                 CopyRegion copyRegion;
11510                 const VkOffset3D srcOffset = {0, 0, 0};
11511                 const VkOffset3D dstOffset = {i, defaultQuarterSize - i - defaultSixteenthSize, i};
11512                 const VkExtent3D extent    = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
11513 
11514                 if (hasDepth)
11515                 {
11516                     const VkImageCopy testCopy = {
11517                         defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11518                         srcOffset,               // VkOffset3D srcOffset;
11519                         defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11520                         dstOffset,               // VkOffset3D dstOffset;
11521                         extent,                  // VkExtent3D extent;
11522                     };
11523 
11524                     copyRegion.imageCopy = testCopy;
11525                     params.regions.push_back(copyRegion);
11526                 }
11527                 if (hasStencil)
11528                 {
11529                     const VkImageCopy testCopy = {
11530                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11531                         srcOffset,                 // VkOffset3D srcOffset;
11532                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11533                         dstOffset,                 // VkOffset3D dstOffset;
11534                         extent,                    // VkExtent3D extent;
11535                     };
11536 
11537                     copyRegion.imageCopy = testCopy;
11538                     params.regions.push_back(copyRegion);
11539                 }
11540             }
11541 
11542             const std::string testName =
11543                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11544             addTestGroup(subGroup.get(), testName, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11545 
11546             if (hasDepth && hasStencil)
11547             {
11548                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
11549                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11550                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11551                 addTestGroup(subGroup.get(), testName2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
11552             }
11553         }
11554 
11555         group->addChild(subGroup.release());
11556     }
11557 }
11558 
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11559 void addImageToImageAllFormatsTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11560 {
11561     addTestGroup(group, "color", addImageToImageAllFormatsColorTests, testGroupParams);
11562     if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
11563         addTestGroup(group, "depth_stencil", addImageToImageAllFormatsDepthStencilTests, testGroupParams);
11564 }
11565 
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11566 void addImageToImage3dImagesTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11567 {
11568     tcu::TestContext &testCtx = group->getTestContext();
11569 
11570     {
11571         TestParams params3DTo2D;
11572         const uint32_t slicesLayers            = 16u;
11573         params3DTo2D.src.image.imageType       = VK_IMAGE_TYPE_3D;
11574         params3DTo2D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11575         params3DTo2D.src.image.extent          = defaultHalfExtent;
11576         params3DTo2D.src.image.extent.depth    = slicesLayers;
11577         params3DTo2D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11578         params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11579         params3DTo2D.dst.image.imageType       = VK_IMAGE_TYPE_2D;
11580         params3DTo2D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11581         params3DTo2D.dst.image.extent          = defaultHalfExtent;
11582         params3DTo2D.dst.image.extent.depth    = slicesLayers;
11583         params3DTo2D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11584         params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11585         params3DTo2D.allocationKind            = testGroupParams->allocationKind;
11586         params3DTo2D.extensionFlags            = testGroupParams->extensionFlags;
11587         params3DTo2D.queueSelection            = testGroupParams->queueSelection;
11588 
11589         for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11590         {
11591             const VkImageSubresourceLayers sourceLayer = {
11592                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11593                 0u,                        // uint32_t mipLevel;
11594                 0u,                        // uint32_t baseArrayLayer;
11595                 1u                         // uint32_t layerCount;
11596             };
11597 
11598             const VkImageSubresourceLayers destinationLayer = {
11599                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11600                 0u,                        // uint32_t mipLevel;
11601                 slicesLayersNdx,           // uint32_t baseArrayLayer;
11602                 1u                         // uint32_t layerCount;
11603             };
11604 
11605             const VkImageCopy testCopy = {
11606                 sourceLayer,                      // VkImageSubresourceLayers srcSubresource;
11607                 {0, 0, (int32_t)slicesLayersNdx}, // VkOffset3D srcOffset;
11608                 destinationLayer,                 // VkImageSubresourceLayers dstSubresource;
11609                 {0, 0, 0},                        // VkOffset3D dstOffset;
11610                 defaultHalfExtent,                // VkExtent3D extent;
11611             };
11612 
11613             CopyRegion imageCopy;
11614             imageCopy.imageCopy = testCopy;
11615 
11616             params3DTo2D.regions.push_back(imageCopy);
11617         }
11618         group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", params3DTo2D));
11619     }
11620 
11621     {
11622         TestParams params2DTo3D;
11623         const uint32_t slicesLayers            = 16u;
11624         params2DTo3D.src.image.imageType       = VK_IMAGE_TYPE_2D;
11625         params2DTo3D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11626         params2DTo3D.src.image.extent          = defaultHalfExtent;
11627         params2DTo3D.src.image.extent.depth    = slicesLayers;
11628         params2DTo3D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11629         params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11630         params2DTo3D.dst.image.imageType       = VK_IMAGE_TYPE_3D;
11631         params2DTo3D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11632         params2DTo3D.dst.image.extent          = defaultHalfExtent;
11633         params2DTo3D.dst.image.extent.depth    = slicesLayers;
11634         params2DTo3D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11635         params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11636         params2DTo3D.allocationKind            = testGroupParams->allocationKind;
11637         params2DTo3D.extensionFlags            = testGroupParams->extensionFlags;
11638         params2DTo3D.queueSelection            = testGroupParams->queueSelection;
11639 
11640         for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11641         {
11642             const VkImageSubresourceLayers sourceLayer = {
11643                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11644                 0u,                        // uint32_t mipLevel;
11645                 slicesLayersNdx,           // uint32_t baseArrayLayer;
11646                 1u                         // uint32_t layerCount;
11647             };
11648 
11649             const VkImageSubresourceLayers destinationLayer = {
11650                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11651                 0u,                        // uint32_t mipLevel;
11652                 0u,                        // uint32_t baseArrayLayer;
11653                 1u                         // uint32_t layerCount;
11654             };
11655 
11656             const VkImageCopy testCopy = {
11657                 sourceLayer,                      // VkImageSubresourceLayers srcSubresource;
11658                 {0, 0, 0},                        // VkOffset3D srcOffset;
11659                 destinationLayer,                 // VkImageSubresourceLayers dstSubresource;
11660                 {0, 0, (int32_t)slicesLayersNdx}, // VkOffset3D dstOffset;
11661                 defaultHalfExtent,                // VkExtent3D extent;
11662             };
11663 
11664             CopyRegion imageCopy;
11665             imageCopy.imageCopy = testCopy;
11666 
11667             params2DTo3D.regions.push_back(imageCopy);
11668         }
11669 
11670         group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", params2DTo3D));
11671     }
11672 
11673     {
11674         TestParams params3DTo2D;
11675         const uint32_t slicesLayers            = 16u;
11676         params3DTo2D.src.image.imageType       = VK_IMAGE_TYPE_3D;
11677         params3DTo2D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11678         params3DTo2D.src.image.extent          = defaultHalfExtent;
11679         params3DTo2D.src.image.extent.depth    = slicesLayers;
11680         params3DTo2D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11681         params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11682         params3DTo2D.dst.image.imageType       = VK_IMAGE_TYPE_2D;
11683         params3DTo2D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11684         params3DTo2D.dst.image.extent          = defaultHalfExtent;
11685         params3DTo2D.dst.image.extent.depth    = slicesLayers;
11686         params3DTo2D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11687         params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11688         params3DTo2D.allocationKind            = testGroupParams->allocationKind;
11689         params3DTo2D.extensionFlags            = testGroupParams->extensionFlags;
11690         params3DTo2D.queueSelection            = testGroupParams->queueSelection;
11691 
11692         {
11693             const VkImageSubresourceLayers sourceLayer = {
11694                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11695                 0u,                        // uint32_t mipLevel;
11696                 0u,                        // uint32_t baseArrayLayer;
11697                 1u                         // uint32_t layerCount;
11698             };
11699 
11700             const VkImageSubresourceLayers destinationLayer = {
11701                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11702                 0u,                        // uint32_t mipLevel;
11703                 0,                         // uint32_t baseArrayLayer;
11704                 slicesLayers               // uint32_t layerCount;
11705             };
11706 
11707             const VkImageCopy testCopy = {
11708                 sourceLayer,                  // VkImageSubresourceLayers srcSubresource;
11709                 {0, 0, 0},                    // VkOffset3D srcOffset;
11710                 destinationLayer,             // VkImageSubresourceLayers dstSubresource;
11711                 {0, 0, 0},                    // VkOffset3D dstOffset;
11712                 params3DTo2D.src.image.extent // VkExtent3D extent;
11713             };
11714 
11715             CopyRegion imageCopy;
11716             imageCopy.imageCopy = testCopy;
11717 
11718             params3DTo2D.regions.push_back(imageCopy);
11719         }
11720         group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", params3DTo2D));
11721     }
11722 
11723     {
11724         TestParams params2DTo3D;
11725         const uint32_t slicesLayers            = 16u;
11726         params2DTo3D.src.image.imageType       = VK_IMAGE_TYPE_2D;
11727         params2DTo3D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11728         params2DTo3D.src.image.extent          = defaultHalfExtent;
11729         params2DTo3D.src.image.extent.depth    = slicesLayers;
11730         params2DTo3D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11731         params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11732         params2DTo3D.dst.image.imageType       = VK_IMAGE_TYPE_3D;
11733         params2DTo3D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11734         params2DTo3D.dst.image.extent          = defaultHalfExtent;
11735         params2DTo3D.dst.image.extent.depth    = slicesLayers;
11736         params2DTo3D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11737         params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11738         params2DTo3D.allocationKind            = testGroupParams->allocationKind;
11739         params2DTo3D.extensionFlags            = testGroupParams->extensionFlags;
11740         params2DTo3D.queueSelection            = testGroupParams->queueSelection;
11741 
11742         {
11743             const VkImageSubresourceLayers sourceLayer = {
11744                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11745                 0u,                        // uint32_t mipLevel;
11746                 0u,                        // uint32_t baseArrayLayer;
11747                 slicesLayers               // uint32_t layerCount;
11748             };
11749 
11750             const VkImageSubresourceLayers destinationLayer = {
11751                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11752                 0u,                        // uint32_t mipLevel;
11753                 0u,                        // uint32_t baseArrayLayer;
11754                 1u                         // uint32_t layerCount;
11755             };
11756 
11757             const VkImageCopy testCopy = {
11758                 sourceLayer,                   // VkImageSubresourceLayers srcSubresource;
11759                 {0, 0, 0},                     // VkOffset3D srcOffset;
11760                 destinationLayer,              // VkImageSubresourceLayers dstSubresource;
11761                 {0, 0, 0},                     // VkOffset3D dstOffset;
11762                 params2DTo3D.src.image.extent, // VkExtent3D extent;
11763             };
11764 
11765             CopyRegion imageCopy;
11766             imageCopy.imageCopy = testCopy;
11767 
11768             params2DTo3D.regions.push_back(imageCopy);
11769         }
11770 
11771         group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", params2DTo3D));
11772     }
11773 
11774     {
11775         TestParams params3DTo2D;
11776         const uint32_t slicesLayers            = 16u;
11777         params3DTo2D.src.image.imageType       = VK_IMAGE_TYPE_3D;
11778         params3DTo2D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11779         params3DTo2D.src.image.extent          = defaultHalfExtent;
11780         params3DTo2D.src.image.extent.depth    = slicesLayers;
11781         params3DTo2D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11782         params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11783         params3DTo2D.dst.image.imageType       = VK_IMAGE_TYPE_2D;
11784         params3DTo2D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11785         params3DTo2D.dst.image.extent          = defaultHalfExtent;
11786         params3DTo2D.dst.image.extent.depth    = slicesLayers;
11787         params3DTo2D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11788         params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11789         params3DTo2D.allocationKind            = testGroupParams->allocationKind;
11790         params3DTo2D.extensionFlags            = testGroupParams->extensionFlags;
11791         params3DTo2D.queueSelection            = testGroupParams->queueSelection;
11792 
11793         const uint32_t regionWidth  = defaultHalfExtent.width / slicesLayers - 1;
11794         const uint32_t regionHeight = defaultHalfExtent.height / slicesLayers - 1;
11795 
11796         for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11797         {
11798             const VkImageSubresourceLayers sourceLayer = {
11799                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11800                 0u,                        // uint32_t mipLevel;
11801                 0u,                        // uint32_t baseArrayLayer;
11802                 1u                         // uint32_t layerCount;
11803             };
11804 
11805             const VkImageSubresourceLayers destinationLayer = {
11806                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11807                 0u,                        // uint32_t mipLevel;
11808                 slicesLayersNdx,           // uint32_t baseArrayLayer;
11809                 1u                         // uint32_t layerCount;
11810             };
11811 
11812             const VkImageCopy testCopy = {
11813                 sourceLayer, // VkImageSubresourceLayers srcSubresource;
11814                 {0, (int32_t)(regionHeight * slicesLayersNdx), (int32_t)slicesLayersNdx}, // VkOffset3D srcOffset;
11815                 destinationLayer,                                 // VkImageSubresourceLayers dstSubresource;
11816                 {(int32_t)(regionWidth * slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
11817                 {(defaultHalfExtent.width - regionWidth * slicesLayersNdx),
11818                  (defaultHalfExtent.height - regionHeight * slicesLayersNdx), 1} // VkExtent3D extent;
11819             };
11820 
11821             CopyRegion imageCopy;
11822             imageCopy.imageCopy = testCopy;
11823             params3DTo2D.regions.push_back(imageCopy);
11824         }
11825         group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", params3DTo2D));
11826     }
11827 
11828     {
11829         TestParams params2DTo3D;
11830         const uint32_t slicesLayers            = 16u;
11831         params2DTo3D.src.image.imageType       = VK_IMAGE_TYPE_2D;
11832         params2DTo3D.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11833         params2DTo3D.src.image.extent          = defaultHalfExtent;
11834         params2DTo3D.src.image.extent.depth    = slicesLayers;
11835         params2DTo3D.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11836         params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11837         params2DTo3D.dst.image.imageType       = VK_IMAGE_TYPE_3D;
11838         params2DTo3D.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11839         params2DTo3D.dst.image.extent          = defaultHalfExtent;
11840         params2DTo3D.dst.image.extent.depth    = slicesLayers;
11841         params2DTo3D.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11842         params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11843         params2DTo3D.allocationKind            = testGroupParams->allocationKind;
11844         params2DTo3D.extensionFlags            = testGroupParams->extensionFlags;
11845         params2DTo3D.queueSelection            = testGroupParams->queueSelection;
11846 
11847         const uint32_t regionWidth  = defaultHalfExtent.width / slicesLayers - 1;
11848         const uint32_t regionHeight = defaultHalfExtent.height / slicesLayers - 1;
11849 
11850         for (uint32_t slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
11851         {
11852             const VkImageSubresourceLayers sourceLayer = {
11853                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11854                 0u,                        // uint32_t mipLevel;
11855                 slicesLayersNdx,           // uint32_t baseArrayLayer;
11856                 1u                         // uint32_t layerCount;
11857             };
11858 
11859             const VkImageSubresourceLayers destinationLayer = {
11860                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11861                 0u,                        // uint32_t mipLevel;
11862                 0u,                        // uint32_t baseArrayLayer;
11863                 1u                         // uint32_t layerCount;
11864             };
11865 
11866             const VkImageCopy testCopy = {
11867                 sourceLayer,                                      // VkImageSubresourceLayers srcSubresource;
11868                 {(int32_t)(regionWidth * slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
11869                 destinationLayer,                                 // VkImageSubresourceLayers dstSubresource;
11870                 {0, (int32_t)(regionHeight * slicesLayersNdx), (int32_t)(slicesLayersNdx)}, // VkOffset3D dstOffset;
11871                 {defaultHalfExtent.width - regionWidth * slicesLayersNdx,
11872                  defaultHalfExtent.height - regionHeight * slicesLayersNdx, 1} // VkExtent3D extent;
11873             };
11874 
11875             CopyRegion imageCopy;
11876             imageCopy.imageCopy = testCopy;
11877 
11878             params2DTo3D.regions.push_back(imageCopy);
11879         }
11880 
11881         group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", params2DTo3D));
11882     }
11883 }
11884 
addImageToImageCubeTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)11885 void addImageToImageCubeTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
11886 {
11887     tcu::TestContext &testCtx = group->getTestContext();
11888 
11889     {
11890         TestParams paramsCubeToArray;
11891         const uint32_t arrayLayers                  = 6u;
11892         paramsCubeToArray.src.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
11893         paramsCubeToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
11894         paramsCubeToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11895         paramsCubeToArray.src.image.extent          = defaultHalfExtent;
11896         paramsCubeToArray.src.image.extent.depth    = arrayLayers;
11897         paramsCubeToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11898         paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11899         paramsCubeToArray.dst.image.createFlags     = 0;
11900         paramsCubeToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
11901         paramsCubeToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11902         paramsCubeToArray.dst.image.extent          = defaultHalfExtent;
11903         paramsCubeToArray.dst.image.extent.depth    = arrayLayers;
11904         paramsCubeToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11905         paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11906         paramsCubeToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
11907         paramsCubeToArray.allocationKind            = testGroupParams->allocationKind;
11908         paramsCubeToArray.extensionFlags            = testGroupParams->extensionFlags;
11909         paramsCubeToArray.queueSelection            = testGroupParams->queueSelection;
11910 
11911         for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
11912         {
11913             const VkImageSubresourceLayers sourceLayer = {
11914                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11915                 0u,                        // uint32_t mipLevel;
11916                 arrayLayersNdx,            // uint32_t baseArrayLayer;
11917                 1u                         // uint32_t layerCount;
11918             };
11919 
11920             const VkImageSubresourceLayers destinationLayer = {
11921                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11922                 0u,                        // uint32_t mipLevel;
11923                 arrayLayersNdx,            // uint32_t baseArrayLayer;
11924                 1u                         // uint32_t layerCount;
11925             };
11926 
11927             const VkImageCopy testCopy = {
11928                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
11929                 {0, 0, 0},        // VkOffset3D srcOffset;
11930                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11931                 {0, 0, 0},        // VkOffset3D dstOffset;
11932                 defaultHalfExtent // VkExtent3D extent;
11933             };
11934 
11935             CopyRegion imageCopy;
11936             imageCopy.imageCopy = testCopy;
11937 
11938             paramsCubeToArray.regions.push_back(imageCopy);
11939         }
11940 
11941         group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", paramsCubeToArray));
11942     }
11943 
11944     {
11945         TestParams paramsCubeToArray;
11946         const uint32_t arrayLayers                  = 6u;
11947         paramsCubeToArray.src.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
11948         paramsCubeToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
11949         paramsCubeToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11950         paramsCubeToArray.src.image.extent          = defaultHalfExtent;
11951         paramsCubeToArray.src.image.extent.depth    = arrayLayers;
11952         paramsCubeToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11953         paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11954         paramsCubeToArray.dst.image.createFlags     = 0;
11955         paramsCubeToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
11956         paramsCubeToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
11957         paramsCubeToArray.dst.image.extent          = defaultHalfExtent;
11958         paramsCubeToArray.dst.image.extent.depth    = arrayLayers;
11959         paramsCubeToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
11960         paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11961         paramsCubeToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
11962         paramsCubeToArray.allocationKind            = testGroupParams->allocationKind;
11963         paramsCubeToArray.extensionFlags            = testGroupParams->extensionFlags;
11964         paramsCubeToArray.queueSelection            = testGroupParams->queueSelection;
11965 
11966         {
11967             const VkImageSubresourceLayers sourceLayer = {
11968                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11969                 0u,                        // uint32_t mipLevel;
11970                 0u,                        // uint32_t baseArrayLayer;
11971                 arrayLayers                // uint32_t layerCount;
11972             };
11973 
11974             const VkImageSubresourceLayers destinationLayer = {
11975                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
11976                 0u,                        // uint32_t mipLevel;
11977                 0u,                        // uint32_t baseArrayLayer;
11978                 arrayLayers                // uint32_t layerCount;
11979             };
11980 
11981             const VkImageCopy testCopy = {
11982                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
11983                 {0, 0, 0},        // VkOffset3D srcOffset;
11984                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
11985                 {0, 0, 0},        // VkOffset3D dstOffset;
11986                 defaultHalfExtent // VkExtent3D extent;
11987             };
11988 
11989             CopyRegion imageCopy;
11990             imageCopy.imageCopy = testCopy;
11991 
11992             paramsCubeToArray.regions.push_back(imageCopy);
11993         }
11994 
11995         group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", paramsCubeToArray));
11996     }
11997 
11998     {
11999         TestParams paramsArrayToCube;
12000         const uint32_t arrayLayers                  = 6u;
12001         paramsArrayToCube.src.image.createFlags     = 0;
12002         paramsArrayToCube.src.image.imageType       = VK_IMAGE_TYPE_2D;
12003         paramsArrayToCube.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12004         paramsArrayToCube.src.image.extent          = defaultHalfExtent;
12005         paramsArrayToCube.src.image.extent.depth    = arrayLayers;
12006         paramsArrayToCube.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12007         paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12008         paramsArrayToCube.dst.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12009         paramsArrayToCube.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12010         paramsArrayToCube.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12011         paramsArrayToCube.dst.image.extent          = defaultHalfExtent;
12012         paramsArrayToCube.dst.image.extent.depth    = arrayLayers;
12013         paramsArrayToCube.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12014         paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12015         paramsArrayToCube.dst.image.fillMode        = FILL_MODE_GRADIENT;
12016         paramsArrayToCube.allocationKind            = testGroupParams->allocationKind;
12017         paramsArrayToCube.extensionFlags            = testGroupParams->extensionFlags;
12018         paramsArrayToCube.queueSelection            = testGroupParams->queueSelection;
12019 
12020         for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12021         {
12022             const VkImageSubresourceLayers sourceLayer = {
12023                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12024                 0u,                        // uint32_t mipLevel;
12025                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12026                 1u                         // uint32_t layerCount;
12027             };
12028 
12029             const VkImageSubresourceLayers destinationLayer = {
12030                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12031                 0u,                        // uint32_t mipLevel;
12032                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12033                 1u                         // uint32_t layerCount;
12034             };
12035 
12036             const VkImageCopy testCopy = {
12037                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12038                 {0, 0, 0},        // VkOffset3D srcOffset;
12039                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12040                 {0, 0, 0},        // VkOffset3D dstOffset;
12041                 defaultHalfExtent // VkExtent3D extent;
12042             };
12043 
12044             CopyRegion imageCopy;
12045             imageCopy.imageCopy = testCopy;
12046 
12047             paramsArrayToCube.regions.push_back(imageCopy);
12048         }
12049 
12050         group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", paramsArrayToCube));
12051     }
12052 
12053     {
12054         TestParams paramsArrayToCube;
12055         const uint32_t arrayLayers                  = 6u;
12056         paramsArrayToCube.src.image.createFlags     = 0;
12057         paramsArrayToCube.src.image.imageType       = VK_IMAGE_TYPE_2D;
12058         paramsArrayToCube.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12059         paramsArrayToCube.src.image.extent          = defaultHalfExtent;
12060         paramsArrayToCube.src.image.extent.depth    = arrayLayers;
12061         paramsArrayToCube.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12062         paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12063         paramsArrayToCube.dst.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12064         paramsArrayToCube.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12065         paramsArrayToCube.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12066         paramsArrayToCube.dst.image.extent          = defaultHalfExtent;
12067         paramsArrayToCube.dst.image.extent.depth    = arrayLayers;
12068         paramsArrayToCube.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12069         paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12070         paramsArrayToCube.dst.image.fillMode        = FILL_MODE_GRADIENT;
12071         paramsArrayToCube.allocationKind            = testGroupParams->allocationKind;
12072         paramsArrayToCube.extensionFlags            = testGroupParams->extensionFlags;
12073         paramsArrayToCube.queueSelection            = testGroupParams->queueSelection;
12074 
12075         {
12076             const VkImageSubresourceLayers sourceLayer = {
12077                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12078                 0u,                        // uint32_t mipLevel;
12079                 0u,                        // uint32_t baseArrayLayer;
12080                 arrayLayers                // uint32_t layerCount;
12081             };
12082 
12083             const VkImageSubresourceLayers destinationLayer = {
12084                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12085                 0u,                        // uint32_t mipLevel;
12086                 0u,                        // uint32_t baseArrayLayer;
12087                 arrayLayers                // uint32_t layerCount;
12088             };
12089 
12090             const VkImageCopy testCopy = {
12091                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12092                 {0, 0, 0},        // VkOffset3D srcOffset;
12093                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12094                 {0, 0, 0},        // VkOffset3D dstOffset;
12095                 defaultHalfExtent // VkExtent3D extent;
12096             };
12097 
12098             CopyRegion imageCopy;
12099             imageCopy.imageCopy = testCopy;
12100 
12101             paramsArrayToCube.regions.push_back(imageCopy);
12102         }
12103 
12104         group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", paramsArrayToCube));
12105     }
12106 
12107     {
12108         TestParams paramsCubeToArray;
12109         const uint32_t arrayLayers                  = 6u;
12110         paramsCubeToArray.src.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12111         paramsCubeToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12112         paramsCubeToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12113         paramsCubeToArray.src.image.extent          = defaultHalfExtent;
12114         paramsCubeToArray.src.image.extent.depth    = arrayLayers;
12115         paramsCubeToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12116         paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12117         paramsCubeToArray.dst.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12118         paramsCubeToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12119         paramsCubeToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12120         paramsCubeToArray.dst.image.extent          = defaultHalfExtent;
12121         paramsCubeToArray.dst.image.extent.depth    = arrayLayers;
12122         paramsCubeToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12123         paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12124         paramsCubeToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12125         paramsCubeToArray.allocationKind            = testGroupParams->allocationKind;
12126         paramsCubeToArray.extensionFlags            = testGroupParams->extensionFlags;
12127         paramsCubeToArray.queueSelection            = testGroupParams->queueSelection;
12128 
12129         for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12130         {
12131             const VkImageSubresourceLayers sourceLayer = {
12132                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12133                 0u,                        // uint32_t mipLevel;
12134                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12135                 1u                         // uint32_t layerCount;
12136             };
12137 
12138             const VkImageSubresourceLayers destinationLayer = {
12139                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12140                 0u,                        // uint32_t mipLevel;
12141                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12142                 1u                         // uint32_t layerCount;
12143             };
12144 
12145             const VkImageCopy testCopy = {
12146                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12147                 {0, 0, 0},        // VkOffset3D srcOffset;
12148                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12149                 {0, 0, 0},        // VkOffset3D dstOffset;
12150                 defaultHalfExtent // VkExtent3D extent;
12151             };
12152 
12153             CopyRegion imageCopy;
12154             imageCopy.imageCopy = testCopy;
12155 
12156             paramsCubeToArray.regions.push_back(imageCopy);
12157         }
12158 
12159         group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", paramsCubeToArray));
12160     }
12161 
12162     {
12163         TestParams paramsCubeToCube;
12164         const uint32_t arrayLayers                 = 6u;
12165         paramsCubeToCube.src.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12166         paramsCubeToCube.src.image.imageType       = VK_IMAGE_TYPE_2D;
12167         paramsCubeToCube.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12168         paramsCubeToCube.src.image.extent          = defaultHalfExtent;
12169         paramsCubeToCube.src.image.extent.depth    = arrayLayers;
12170         paramsCubeToCube.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12171         paramsCubeToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12172         paramsCubeToCube.dst.image.createFlags     = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
12173         paramsCubeToCube.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12174         paramsCubeToCube.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12175         paramsCubeToCube.dst.image.extent          = defaultHalfExtent;
12176         paramsCubeToCube.dst.image.extent.depth    = arrayLayers;
12177         paramsCubeToCube.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12178         paramsCubeToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12179         paramsCubeToCube.dst.image.fillMode        = FILL_MODE_GRADIENT;
12180         paramsCubeToCube.allocationKind            = testGroupParams->allocationKind;
12181         paramsCubeToCube.extensionFlags            = testGroupParams->extensionFlags;
12182         paramsCubeToCube.queueSelection            = testGroupParams->queueSelection;
12183 
12184         {
12185             const VkImageSubresourceLayers sourceLayer = {
12186                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12187                 0u,                        // uint32_t mipLevel;
12188                 0u,                        // uint32_t baseArrayLayer;
12189                 arrayLayers                // uint32_t layerCount;
12190             };
12191 
12192             const VkImageSubresourceLayers destinationLayer = {
12193                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12194                 0u,                        // uint32_t mipLevel;
12195                 0u,                        // uint32_t baseArrayLayer;
12196                 arrayLayers                // uint32_t layerCount;
12197             };
12198 
12199             const VkImageCopy testCopy = {
12200                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12201                 {0, 0, 0},        // VkOffset3D srcOffset;
12202                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12203                 {0, 0, 0},        // VkOffset3D dstOffset;
12204                 defaultHalfExtent // VkExtent3D extent;
12205             };
12206 
12207             CopyRegion imageCopy;
12208             imageCopy.imageCopy = testCopy;
12209 
12210             paramsCubeToCube.regions.push_back(imageCopy);
12211         }
12212 
12213         group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", paramsCubeToCube));
12214     }
12215 }
12216 
addImageToImageArrayTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12217 void addImageToImageArrayTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12218 {
12219     tcu::TestContext &testCtx = group->getTestContext();
12220 
12221     {
12222         TestParams paramsArrayToArray;
12223         const uint32_t arrayLayers                   = 16u;
12224         paramsArrayToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12225         paramsArrayToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12226         paramsArrayToArray.src.image.extent          = defaultHalfExtent;
12227         paramsArrayToArray.src.image.extent.depth    = arrayLayers;
12228         paramsArrayToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12229         paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12230         paramsArrayToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12231         paramsArrayToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12232         paramsArrayToArray.dst.image.extent          = defaultHalfExtent;
12233         paramsArrayToArray.dst.image.extent.depth    = arrayLayers;
12234         paramsArrayToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12235         paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12236         paramsArrayToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12237         paramsArrayToArray.allocationKind            = testGroupParams->allocationKind;
12238         paramsArrayToArray.extensionFlags            = testGroupParams->extensionFlags;
12239         paramsArrayToArray.queueSelection            = testGroupParams->queueSelection;
12240         paramsArrayToArray.useSparseBinding          = testGroupParams->useSparseBinding;
12241 
12242         for (uint32_t arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
12243         {
12244             const VkImageSubresourceLayers sourceLayer = {
12245                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12246                 0u,                        // uint32_t mipLevel;
12247                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12248                 1u                         // uint32_t layerCount;
12249             };
12250 
12251             const VkImageSubresourceLayers destinationLayer = {
12252                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12253                 0u,                        // uint32_t mipLevel;
12254                 arrayLayersNdx,            // uint32_t baseArrayLayer;
12255                 1u                         // uint32_t layerCount;
12256             };
12257 
12258             const VkImageCopy testCopy = {
12259                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12260                 {0, 0, 0},        // VkOffset3D srcOffset;
12261                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12262                 {0, 0, 0},        // VkOffset3D dstOffset;
12263                 defaultHalfExtent // VkExtent3D extent;
12264             };
12265 
12266             CopyRegion imageCopy;
12267             imageCopy.imageCopy = testCopy;
12268 
12269             paramsArrayToArray.regions.push_back(imageCopy);
12270         }
12271 
12272         group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", paramsArrayToArray));
12273     }
12274 
12275     {
12276         TestParams paramsArrayToArray;
12277         const uint32_t arrayLayers                   = 16u;
12278         paramsArrayToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12279         paramsArrayToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12280         paramsArrayToArray.src.image.extent          = defaultHalfExtent;
12281         paramsArrayToArray.src.image.extent.depth    = arrayLayers;
12282         paramsArrayToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12283         paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12284         paramsArrayToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12285         paramsArrayToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12286         paramsArrayToArray.dst.image.extent          = defaultHalfExtent;
12287         paramsArrayToArray.dst.image.extent.depth    = arrayLayers;
12288         paramsArrayToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12289         paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12290         paramsArrayToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12291         paramsArrayToArray.allocationKind            = testGroupParams->allocationKind;
12292         paramsArrayToArray.extensionFlags            = testGroupParams->extensionFlags;
12293         paramsArrayToArray.queueSelection            = testGroupParams->queueSelection;
12294 
12295         {
12296             const VkImageSubresourceLayers sourceLayer = {
12297                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12298                 0u,                        // uint32_t mipLevel;
12299                 0u,                        // uint32_t baseArrayLayer;
12300                 arrayLayers                // uint32_t layerCount;
12301             };
12302 
12303             const VkImageSubresourceLayers destinationLayer = {
12304                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12305                 0u,                        // uint32_t mipLevel;
12306                 0u,                        // uint32_t baseArrayLayer;
12307                 arrayLayers                // uint32_t layerCount;
12308             };
12309 
12310             const VkImageCopy testCopy = {
12311                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12312                 {0, 0, 0},        // VkOffset3D srcOffset;
12313                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12314                 {0, 0, 0},        // VkOffset3D dstOffset;
12315                 defaultHalfExtent // VkExtent3D extent;
12316             };
12317 
12318             CopyRegion imageCopy;
12319             imageCopy.imageCopy = testCopy;
12320 
12321             paramsArrayToArray.regions.push_back(imageCopy);
12322         }
12323 
12324         group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", paramsArrayToArray));
12325     }
12326 
12327     if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
12328     {
12329         TestParams paramsArrayToArray;
12330         const uint32_t arrayLayers                   = 16u;
12331         paramsArrayToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12332         paramsArrayToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12333         paramsArrayToArray.src.image.extent          = defaultHalfExtent;
12334         paramsArrayToArray.src.image.extent.depth    = arrayLayers;
12335         paramsArrayToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12336         paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12337         paramsArrayToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12338         paramsArrayToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12339         paramsArrayToArray.dst.image.extent          = defaultHalfExtent;
12340         paramsArrayToArray.dst.image.extent.depth    = arrayLayers;
12341         paramsArrayToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12342         paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12343         paramsArrayToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12344         paramsArrayToArray.allocationKind            = testGroupParams->allocationKind;
12345         paramsArrayToArray.extensionFlags            = testGroupParams->extensionFlags;
12346         paramsArrayToArray.queueSelection            = testGroupParams->queueSelection;
12347         paramsArrayToArray.extensionFlags |= MAINTENANCE_5;
12348 
12349         {
12350             const VkImageSubresourceLayers sourceLayer = {
12351                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12352                 0u,                        // uint32_t mipLevel;
12353                 0u,                        // uint32_t baseArrayLayer;
12354                 VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12355             };
12356 
12357             const VkImageSubresourceLayers destinationLayer = {
12358                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12359                 0u,                        // uint32_t mipLevel;
12360                 0u,                        // uint32_t baseArrayLayer;
12361                 VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12362             };
12363 
12364             const VkImageCopy testCopy = {
12365                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12366                 {0, 0, 0},        // VkOffset3D srcOffset;
12367                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12368                 {0, 0, 0},        // VkOffset3D dstOffset;
12369                 defaultHalfExtent // VkExtent3D extent;
12370             };
12371 
12372             CopyRegion imageCopy;
12373             imageCopy.imageCopy = testCopy;
12374 
12375             paramsArrayToArray.regions.push_back(imageCopy);
12376         }
12377 
12378         group->addChild(
12379             new CopyImageToImageTestCase(testCtx, "array_to_array_whole_remaining_layers", paramsArrayToArray));
12380     }
12381 
12382     {
12383         TestParams paramsArrayToArray;
12384         const uint32_t arrayLayers                   = 16u;
12385         paramsArrayToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12386         paramsArrayToArray.src.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12387         paramsArrayToArray.src.image.extent          = defaultHalfExtent;
12388         paramsArrayToArray.src.image.extent.depth    = arrayLayers;
12389         paramsArrayToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12390         paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12391         paramsArrayToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12392         paramsArrayToArray.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
12393         paramsArrayToArray.dst.image.extent          = defaultHalfExtent;
12394         paramsArrayToArray.dst.image.extent.depth    = arrayLayers;
12395         paramsArrayToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12396         paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12397         paramsArrayToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12398         paramsArrayToArray.allocationKind            = testGroupParams->allocationKind;
12399         paramsArrayToArray.extensionFlags            = testGroupParams->extensionFlags;
12400         paramsArrayToArray.queueSelection            = testGroupParams->queueSelection;
12401         paramsArrayToArray.extensionFlags |= MAINTENANCE_5;
12402 
12403         {
12404             const VkImageSubresourceLayers sourceLayer = {
12405                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12406                 0u,                        // uint32_t mipLevel;
12407                 3u,                        // uint32_t baseArrayLayer;
12408                 VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12409             };
12410 
12411             const VkImageSubresourceLayers destinationLayer = {
12412                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12413                 0u,                        // uint32_t mipLevel;
12414                 3u,                        // uint32_t baseArrayLayer;
12415                 VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12416             };
12417 
12418             const VkImageCopy testCopy = {
12419                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12420                 {0, 0, 0},        // VkOffset3D srcOffset;
12421                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12422                 {0, 0, 0},        // VkOffset3D dstOffset;
12423                 defaultHalfExtent // VkExtent3D extent;
12424             };
12425 
12426             CopyRegion imageCopy;
12427             imageCopy.imageCopy = testCopy;
12428 
12429             paramsArrayToArray.regions.push_back(imageCopy);
12430         }
12431 
12432         group->addChild(
12433             new CopyImageToImageTestCase(testCtx, "array_to_array_partial_remaining_layers", paramsArrayToArray));
12434     }
12435 
12436     {
12437         TestParams paramsArrayToArray;
12438         const uint32_t arrayLayers                   = 16u;
12439         paramsArrayToArray.src.image.imageType       = VK_IMAGE_TYPE_2D;
12440         paramsArrayToArray.src.image.extent          = defaultHalfExtent;
12441         paramsArrayToArray.src.image.extent.depth    = arrayLayers;
12442         paramsArrayToArray.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12443         paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12444         paramsArrayToArray.dst.image.imageType       = VK_IMAGE_TYPE_2D;
12445         paramsArrayToArray.dst.image.extent          = defaultHalfExtent;
12446         paramsArrayToArray.dst.image.extent.depth    = arrayLayers;
12447         paramsArrayToArray.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12448         paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12449         paramsArrayToArray.dst.image.fillMode        = FILL_MODE_GRADIENT;
12450         paramsArrayToArray.allocationKind            = testGroupParams->allocationKind;
12451         paramsArrayToArray.extensionFlags            = testGroupParams->extensionFlags;
12452         paramsArrayToArray.queueSelection            = testGroupParams->queueSelection;
12453         paramsArrayToArray.useSparseBinding          = testGroupParams->useSparseBinding;
12454         paramsArrayToArray.mipLevels = deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
12455 
12456         for (uint32_t mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
12457         {
12458             const VkImageSubresourceLayers sourceLayer = {
12459                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12460                 mipLevelNdx,               // uint32_t mipLevel;
12461                 0u,                        // uint32_t baseArrayLayer;
12462                 arrayLayers                // uint32_t layerCount;
12463             };
12464 
12465             const VkImageSubresourceLayers destinationLayer = {
12466                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12467                 mipLevelNdx,               // uint32_t mipLevel;
12468                 0u,                        // uint32_t baseArrayLayer;
12469                 arrayLayers                // uint32_t layerCount;
12470             };
12471 
12472             const VkExtent3D extent = {
12473                 (uint32_t)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),  // uint32_t    width;
12474                 (uint32_t)deMax(defaultHalfExtent.height >> mipLevelNdx, 1), // uint32_t    height;
12475                 1u,                                                          // uint32_t    depth;
12476             };
12477 
12478             const VkImageCopy testCopy = {
12479                 sourceLayer,      // VkImageSubresourceLayers srcSubresource;
12480                 {0, 0, 0},        // VkOffset3D srcOffset;
12481                 destinationLayer, // VkImageSubresourceLayers dstSubresource;
12482                 {0, 0, 0},        // VkOffset3D dstOffset;
12483                 extent            // VkExtent3D extent;
12484             };
12485 
12486             CopyRegion imageCopy;
12487             imageCopy.imageCopy = testCopy;
12488 
12489             paramsArrayToArray.regions.push_back(imageCopy);
12490         }
12491 
12492         VkFormat imageFormats[] = {VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM,
12493                                    VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
12494 
12495         for (uint32_t imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
12496         {
12497             paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
12498             paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
12499             for (uint32_t regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
12500             {
12501                 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask =
12502                     getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
12503                 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask =
12504                     getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
12505             }
12506             std::ostringstream testName;
12507             const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
12508             testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
12509             group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), paramsArrayToArray));
12510         }
12511     }
12512 }
12513 
addImageToImageTestsSimpleOnly(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12514 void addImageToImageTestsSimpleOnly(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12515 {
12516     addTestGroup(group, "simple_tests", addImageToImageSimpleTests, testGroupParams);
12517 }
12518 
addImageToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12519 void addImageToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12520 {
12521     addTestGroup(group, "simple_tests", addImageToImageSimpleTests, testGroupParams);
12522     if (!testGroupParams->useSparseBinding)
12523         addTestGroup(group, "all_formats", addImageToImageAllFormatsTests, testGroupParams);
12524     addTestGroup(group, "3d_images", addImageToImage3dImagesTests, testGroupParams);
12525     if (!testGroupParams->useSparseBinding)
12526         addTestGroup(group, "dimensions", addImageToImageDimensionsTests, testGroupParams);
12527     addTestGroup(group, "cube", addImageToImageCubeTests, testGroupParams);
12528     addTestGroup(group, "array", addImageToImageArrayTests, testGroupParams);
12529 }
12530 
add1dImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12531 void add1dImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12532 {
12533     tcu::TestContext &testCtx = group->getTestContext();
12534 
12535     {
12536         TestParams params;
12537         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12538         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12539         params.src.image.extent          = default1dExtent;
12540         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12541         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12542         params.dst.buffer.size           = defaultSize;
12543         params.allocationKind            = testGroupParams->allocationKind;
12544         params.extensionFlags            = testGroupParams->extensionFlags;
12545         params.queueSelection            = testGroupParams->queueSelection;
12546         params.useSparseBinding          = testGroupParams->useSparseBinding;
12547 
12548         const VkBufferImageCopy bufferImageCopy = {
12549             0u,                 // VkDeviceSize bufferOffset;
12550             0u,                 // uint32_t bufferRowLength;
12551             0u,                 // uint32_t bufferImageHeight;
12552             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12553             {0, 0, 0},          // VkOffset3D imageOffset;
12554             default1dExtent     // VkExtent3D imageExtent;
12555         };
12556         CopyRegion copyRegion;
12557         copyRegion.bufferImageCopy = bufferImageCopy;
12558 
12559         params.regions.push_back(copyRegion);
12560 
12561         group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", params));
12562     }
12563 
12564     {
12565         TestParams params;
12566         uint32_t bufferImageHeight       = defaultSize + 1u;
12567         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12568         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12569         params.src.image.extent          = default1dExtent;
12570         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12571         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12572         params.dst.buffer.size           = bufferImageHeight;
12573         params.allocationKind            = testGroupParams->allocationKind;
12574         params.extensionFlags            = testGroupParams->extensionFlags;
12575         params.queueSelection            = testGroupParams->queueSelection;
12576         params.useSparseBinding          = testGroupParams->useSparseBinding;
12577 
12578         const VkBufferImageCopy bufferImageCopy = {
12579             0u,                 // VkDeviceSize bufferOffset;
12580             0u,                 // uint32_t bufferRowLength;
12581             bufferImageHeight,  // uint32_t bufferImageHeight;
12582             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12583             {0, 0, 0},          // VkOffset3D imageOffset;
12584             default1dExtent     // VkExtent3D imageExtent;
12585         };
12586         CopyRegion copyRegion;
12587         copyRegion.bufferImageCopy = bufferImageCopy;
12588 
12589         params.regions.push_back(copyRegion);
12590 
12591         group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", params));
12592     }
12593 
12594     {
12595         TestParams params;
12596         uint32_t arrayLayers             = 16u;
12597         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12598         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12599         params.src.image.extent          = default1dExtent;
12600         params.src.image.extent.depth    = arrayLayers;
12601         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12602         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12603         params.dst.buffer.size           = defaultSize * arrayLayers;
12604         params.allocationKind            = testGroupParams->allocationKind;
12605         params.extensionFlags            = testGroupParams->extensionFlags;
12606         params.queueSelection            = testGroupParams->queueSelection;
12607         params.useSparseBinding          = testGroupParams->useSparseBinding;
12608 
12609         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12610         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
12611         {
12612             const VkDeviceSize offset               = defaultSize * pixelSize * arrayLayerNdx;
12613             const VkBufferImageCopy bufferImageCopy = {
12614                 offset,      // VkDeviceSize bufferOffset;
12615                 0u,          // uint32_t bufferRowLength;
12616                 defaultSize, // uint32_t bufferImageHeight;
12617                 {
12618                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12619                     0u,                        // uint32_t mipLevel;
12620                     arrayLayerNdx,             // uint32_t baseArrayLayer;
12621                     1u,                        // uint32_t layerCount;
12622                 },                             // VkImageSubresourceLayers imageSubresource;
12623                 {0, 0, 0},                     // VkOffset3D imageOffset;
12624                 default1dExtent                // VkExtent3D imageExtent;
12625             };
12626             CopyRegion copyRegion;
12627             copyRegion.bufferImageCopy = bufferImageCopy;
12628 
12629             params.regions.push_back(copyRegion);
12630         }
12631 
12632         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", params));
12633     }
12634 
12635     {
12636         TestParams params;
12637         uint32_t arrayLayers             = 16u;
12638         uint32_t bufferImageHeight       = defaultSize + 1u;
12639         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12640         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12641         params.src.image.extent          = default1dExtent;
12642         params.src.image.extent.depth    = arrayLayers;
12643         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12644         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12645         params.dst.buffer.size           = bufferImageHeight * arrayLayers;
12646         params.allocationKind            = testGroupParams->allocationKind;
12647         params.extensionFlags            = testGroupParams->extensionFlags;
12648         params.queueSelection            = testGroupParams->queueSelection;
12649         params.useSparseBinding          = testGroupParams->useSparseBinding;
12650 
12651         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12652         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
12653         {
12654             const VkDeviceSize offset               = bufferImageHeight * pixelSize * arrayLayerNdx;
12655             const VkBufferImageCopy bufferImageCopy = {
12656                 offset,            // VkDeviceSize bufferOffset;
12657                 0u,                // uint32_t bufferRowLength;
12658                 bufferImageHeight, // uint32_t bufferImageHeight;
12659                 {
12660                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12661                     0u,                        // uint32_t mipLevel;
12662                     arrayLayerNdx,             // uint32_t baseArrayLayer;
12663                     1u,                        // uint32_t layerCount;
12664                 },                             // VkImageSubresourceLayers imageSubresource;
12665                 {0, 0, 0},                     // VkOffset3D imageOffset;
12666                 default1dExtent                // VkExtent3D imageExtent;
12667             };
12668             CopyRegion copyRegion;
12669             copyRegion.bufferImageCopy = bufferImageCopy;
12670 
12671             params.regions.push_back(copyRegion);
12672         }
12673 
12674         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", params));
12675     }
12676 
12677     {
12678         TestParams params;
12679         const uint32_t baseLayer         = 0u;
12680         const uint32_t layerCount        = 16u;
12681         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12682         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12683         params.src.image.extent          = default1dExtent;
12684         params.src.image.extent.depth    = layerCount;
12685         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12686         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12687         params.src.image.fillMode        = FILL_MODE_RED;
12688         params.dst.buffer.size           = defaultSize * layerCount;
12689         params.dst.buffer.fillMode       = FILL_MODE_RED;
12690         params.allocationKind            = testGroupParams->allocationKind;
12691         params.extensionFlags            = testGroupParams->extensionFlags;
12692         params.queueSelection            = testGroupParams->queueSelection;
12693         params.useSparseBinding          = testGroupParams->useSparseBinding;
12694         params.extensionFlags |= MAINTENANCE_5;
12695 
12696         const VkImageSubresourceLayers defaultLayer = {
12697             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12698             0u,                        // uint32_t mipLevel;
12699             baseLayer,                 // uint32_t baseArrayLayer;
12700             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12701         };
12702 
12703         const VkBufferImageCopy bufferImageCopy = {
12704             0u,             // VkDeviceSize bufferOffset;
12705             0u,             // uint32_t bufferRowLength;
12706             0u,             // uint32_t bufferImageHeight;
12707             defaultLayer,   // VkImageSubresourceLayers imageSubresource;
12708             {0, 0, 0},      // VkOffset3D imageOffset;
12709             default1dExtent // VkExtent3D imageExtent;
12710         };
12711 
12712         CopyRegion copyRegion;
12713         copyRegion.bufferImageCopy = bufferImageCopy;
12714 
12715         params.regions.push_back(copyRegion);
12716 
12717         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_all_remaining_layers", params));
12718     }
12719 
12720     {
12721         TestParams params;
12722         const uint32_t baseLayer         = 2u;
12723         const uint32_t layerCount        = 16u;
12724         params.src.image.imageType       = VK_IMAGE_TYPE_1D;
12725         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12726         params.src.image.extent          = default1dExtent;
12727         params.src.image.extent.depth    = layerCount;
12728         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12729         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12730         params.src.image.fillMode        = FILL_MODE_RED;
12731         params.dst.buffer.size           = defaultSize * layerCount;
12732         params.dst.buffer.fillMode       = FILL_MODE_RED;
12733         params.allocationKind            = testGroupParams->allocationKind;
12734         params.extensionFlags            = testGroupParams->extensionFlags;
12735         params.queueSelection            = testGroupParams->queueSelection;
12736         params.useSparseBinding          = testGroupParams->useSparseBinding;
12737         params.extensionFlags |= MAINTENANCE_5;
12738 
12739         const VkImageSubresourceLayers defaultLayer = {
12740             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12741             0u,                        // uint32_t mipLevel;
12742             baseLayer,                 // uint32_t baseArrayLayer;
12743             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
12744         };
12745 
12746         const VkBufferImageCopy bufferImageCopy = {
12747             0u,             // VkDeviceSize bufferOffset;
12748             0u,             // uint32_t bufferRowLength;
12749             0u,             // uint32_t bufferImageHeight;
12750             defaultLayer,   // VkImageSubresourceLayers imageSubresource;
12751             {0, 0, 0},      // VkOffset3D imageOffset;
12752             default1dExtent // VkExtent3D imageExtent;
12753         };
12754 
12755         CopyRegion copyRegion;
12756         copyRegion.bufferImageCopy = bufferImageCopy;
12757 
12758         params.regions.push_back(copyRegion);
12759 
12760         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_not_all_remaining_layers", params));
12761     }
12762 }
12763 
add2dImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)12764 void add2dImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
12765 {
12766     tcu::TestContext &testCtx = group->getTestContext();
12767 
12768     {
12769         TestParams params;
12770         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12771         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12772         params.src.image.extent          = defaultExtent;
12773         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12774         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12775         params.dst.buffer.size           = defaultSize * defaultSize;
12776         params.allocationKind            = testGroupParams->allocationKind;
12777         params.extensionFlags            = testGroupParams->extensionFlags;
12778         params.queueSelection            = testGroupParams->queueSelection;
12779         params.useSparseBinding          = testGroupParams->useSparseBinding;
12780 
12781         const VkBufferImageCopy bufferImageCopy = {
12782             0u,                 // VkDeviceSize bufferOffset;
12783             0u,                 // uint32_t bufferRowLength;
12784             0u,                 // uint32_t bufferImageHeight;
12785             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12786             {0, 0, 0},          // VkOffset3D imageOffset;
12787             defaultExtent       // VkExtent3D imageExtent;
12788         };
12789         CopyRegion copyRegion;
12790         copyRegion.bufferImageCopy = bufferImageCopy;
12791 
12792         params.regions.push_back(copyRegion);
12793 
12794         group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", params));
12795     }
12796 
12797     {
12798         TestParams params;
12799         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12800         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12801         params.src.image.extent          = defaultExtent;
12802         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12803         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12804         params.dst.buffer.size           = defaultSize * defaultSize;
12805         params.allocationKind            = testGroupParams->allocationKind;
12806         params.extensionFlags            = testGroupParams->extensionFlags;
12807         params.queueSelection            = testGroupParams->queueSelection;
12808         params.useSparseBinding          = testGroupParams->useSparseBinding;
12809 
12810         const VkBufferImageCopy bufferImageCopy = {
12811             defaultSize * defaultHalfSize,               // VkDeviceSize bufferOffset;
12812             0u,                                          // uint32_t bufferRowLength;
12813             0u,                                          // uint32_t bufferImageHeight;
12814             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
12815             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12816             defaultHalfExtent                            // VkExtent3D imageExtent;
12817         };
12818         CopyRegion copyRegion;
12819         copyRegion.bufferImageCopy = bufferImageCopy;
12820 
12821         params.regions.push_back(copyRegion);
12822 
12823         group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", params));
12824     }
12825 
12826     if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
12827     {
12828         TestParams params;
12829         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12830         params.src.image.format          = VK_FORMAT_R8_UNORM;
12831         params.src.image.extent          = defaultExtent;
12832         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12833         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12834         params.dst.buffer.size           = defaultSize * defaultSize;
12835         params.allocationKind            = testGroupParams->allocationKind;
12836         params.extensionFlags            = testGroupParams->extensionFlags;
12837         params.queueSelection            = testGroupParams->queueSelection;
12838         params.useSparseBinding          = testGroupParams->useSparseBinding;
12839 
12840         const VkBufferImageCopy bufferImageCopy = {
12841             defaultSize * defaultHalfSize + 1u,          // VkDeviceSize bufferOffset;
12842             0u,                                          // uint32_t bufferRowLength;
12843             0u,                                          // uint32_t bufferImageHeight;
12844             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
12845             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12846             defaultHalfExtent                            // VkExtent3D imageExtent;
12847         };
12848         CopyRegion copyRegion;
12849         copyRegion.bufferImageCopy = bufferImageCopy;
12850 
12851         params.regions.push_back(copyRegion);
12852 
12853         group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", params));
12854     }
12855 
12856     {
12857         TestParams params;
12858         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12859         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12860         params.src.image.extent          = defaultExtent;
12861         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12862         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12863         params.dst.buffer.size           = defaultSize * defaultSize;
12864         params.allocationKind            = testGroupParams->allocationKind;
12865         params.extensionFlags            = testGroupParams->extensionFlags;
12866         params.queueSelection            = testGroupParams->queueSelection;
12867         params.useSparseBinding          = testGroupParams->useSparseBinding;
12868 
12869         const int pixelSize           = tcu::getPixelSize(mapVkFormat(params.src.image.format));
12870         const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
12871         const VkDeviceSize offsetSize = pixelSize * defaultQuarterSize * defaultQuarterSize;
12872         uint32_t divisor              = 1;
12873         for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
12874         {
12875             const uint32_t bufferRowLength   = defaultQuarterSize;
12876             const uint32_t bufferImageHeight = defaultQuarterSize;
12877             const VkExtent3D imageExtent     = {defaultQuarterSize / divisor, defaultQuarterSize, 1};
12878             DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
12879             DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
12880             DE_ASSERT(imageExtent.width * imageExtent.height * imageExtent.depth <= offsetSize);
12881 
12882             CopyRegion region;
12883             const VkBufferImageCopy bufferImageCopy = {
12884                 offset,             // VkDeviceSize bufferOffset;
12885                 bufferRowLength,    // uint32_t bufferRowLength;
12886                 bufferImageHeight,  // uint32_t bufferImageHeight;
12887                 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12888                 {0, 0, 0},          // VkOffset3D imageOffset;
12889                 imageExtent         // VkExtent3D imageExtent;
12890             };
12891             region.bufferImageCopy = bufferImageCopy;
12892             params.regions.push_back(region);
12893         }
12894 
12895         group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", params));
12896     }
12897 
12898     {
12899         TestParams params;
12900         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12901         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12902         params.src.image.extent          = defaultExtent;
12903         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12904         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12905         params.dst.buffer.size           = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
12906         params.allocationKind            = testGroupParams->allocationKind;
12907         params.extensionFlags            = testGroupParams->extensionFlags;
12908         params.queueSelection            = testGroupParams->queueSelection;
12909         params.useSparseBinding          = testGroupParams->useSparseBinding;
12910 
12911         const VkBufferImageCopy bufferImageCopy = {
12912             0u,                                          // VkDeviceSize bufferOffset;
12913             defaultSize,                                 // uint32_t bufferRowLength;
12914             defaultSize,                                 // uint32_t bufferImageHeight;
12915             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
12916             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12917             defaultHalfExtent                            // VkExtent3D imageExtent;
12918         };
12919         CopyRegion copyRegion;
12920         copyRegion.bufferImageCopy = bufferImageCopy;
12921 
12922         params.regions.push_back(copyRegion);
12923 
12924         group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", params));
12925     }
12926 
12927     {
12928         TestParams params;
12929         uint32_t bufferImageHeight       = defaultSize + 1u;
12930         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12931         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12932         params.src.image.extent          = defaultExtent;
12933         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12934         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12935         params.dst.buffer.size           = bufferImageHeight * defaultSize;
12936         params.allocationKind            = testGroupParams->allocationKind;
12937         params.extensionFlags            = testGroupParams->extensionFlags;
12938         params.queueSelection            = testGroupParams->queueSelection;
12939         params.useSparseBinding          = testGroupParams->useSparseBinding;
12940 
12941         const VkBufferImageCopy bufferImageCopy = {
12942             0u,                 // VkDeviceSize bufferOffset;
12943             defaultSize,        // uint32_t bufferRowLength;
12944             bufferImageHeight,  // uint32_t bufferImageHeight;
12945             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
12946             {0, 0, 0},          // VkOffset3D imageOffset;
12947             defaultExtent       // VkExtent3D imageExtent;
12948         };
12949         CopyRegion copyRegion;
12950         copyRegion.bufferImageCopy = bufferImageCopy;
12951 
12952         params.regions.push_back(copyRegion);
12953 
12954         group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", params));
12955     }
12956 
12957     {
12958         TestParams params;
12959         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12960         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12961         params.src.image.extent          = defaultExtent;
12962         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12963         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12964         params.dst.buffer.size           = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
12965         params.allocationKind            = testGroupParams->allocationKind;
12966         params.extensionFlags            = testGroupParams->extensionFlags;
12967         params.queueSelection            = testGroupParams->queueSelection;
12968         params.useSparseBinding          = testGroupParams->useSparseBinding;
12969 
12970         const VkBufferImageCopy bufferImageCopy = {
12971             defaultQuarterSize,                          // VkDeviceSize bufferOffset;
12972             defaultSize,                                 // uint32_t bufferRowLength;
12973             defaultSize,                                 // uint32_t bufferImageHeight;
12974             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
12975             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
12976             defaultHalfExtent                            // VkExtent3D imageExtent;
12977         };
12978         CopyRegion copyRegion;
12979         copyRegion.bufferImageCopy = bufferImageCopy;
12980 
12981         params.regions.push_back(copyRegion);
12982 
12983         group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", params));
12984     }
12985 
12986     {
12987         TestParams params;
12988         uint32_t arrayLayers             = 16u;
12989         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
12990         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
12991         params.src.image.extent          = defaultHalfExtent;
12992         params.src.image.extent.depth    = arrayLayers;
12993         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
12994         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12995         params.dst.buffer.size           = defaultHalfSize * defaultHalfSize * arrayLayers;
12996         params.allocationKind            = testGroupParams->allocationKind;
12997         params.extensionFlags            = testGroupParams->extensionFlags;
12998         params.queueSelection            = testGroupParams->queueSelection;
12999         params.useSparseBinding          = testGroupParams->useSparseBinding;
13000 
13001         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13002         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13003         {
13004             const VkDeviceSize offset               = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13005             const VkBufferImageCopy bufferImageCopy = {
13006                 offset, // VkDeviceSize bufferOffset;
13007                 0u,     // uint32_t bufferRowLength;
13008                 0u,     // uint32_t bufferImageHeight;
13009                 {
13010                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13011                     0u,                        // uint32_t mipLevel;
13012                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13013                     1u,                        // uint32_t layerCount;
13014                 },                             // VkImageSubresourceLayers imageSubresource;
13015                 {0, 0, 0},                     // VkOffset3D imageOffset;
13016                 defaultHalfExtent              // VkExtent3D imageExtent;
13017             };
13018             CopyRegion copyRegion;
13019             copyRegion.bufferImageCopy = bufferImageCopy;
13020 
13021             params.regions.push_back(copyRegion);
13022         }
13023         group->addChild(new CopyImageToBufferTestCase(testCtx, "array", params));
13024     }
13025 
13026     {
13027         TestParams params;
13028         uint32_t arrayLayers             = 16u;
13029         uint32_t imageBufferHeight       = defaultHalfSize + 1u;
13030         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
13031         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13032         params.src.image.extent          = defaultHalfExtent;
13033         params.src.image.extent.depth    = arrayLayers;
13034         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13035         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13036         params.dst.buffer.size           = defaultHalfSize * imageBufferHeight * arrayLayers;
13037         params.allocationKind            = testGroupParams->allocationKind;
13038         params.extensionFlags            = testGroupParams->extensionFlags;
13039         params.queueSelection            = testGroupParams->queueSelection;
13040         params.useSparseBinding          = testGroupParams->useSparseBinding;
13041 
13042         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13043         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13044         {
13045             const VkDeviceSize offset               = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
13046             const VkBufferImageCopy bufferImageCopy = {
13047                 offset,            // VkDeviceSize bufferOffset;
13048                 0u,                // uint32_t bufferRowLength;
13049                 imageBufferHeight, // uint32_t bufferImageHeight;
13050                 {
13051                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13052                     0u,                        // uint32_t mipLevel;
13053                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13054                     1u,                        // uint32_t layerCount;
13055                 },                             // VkImageSubresourceLayers imageSubresource;
13056                 {0, 0, 0},                     // VkOffset3D imageOffset;
13057                 defaultHalfExtent              // VkExtent3D imageExtent;
13058             };
13059             CopyRegion copyRegion;
13060             copyRegion.bufferImageCopy = bufferImageCopy;
13061 
13062             params.regions.push_back(copyRegion);
13063         }
13064         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", params));
13065     }
13066 
13067     {
13068         TestParams params;
13069         uint32_t arrayLayers             = 16u;
13070         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
13071         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13072         params.src.image.extent          = defaultHalfExtent;
13073         params.src.image.extent.depth    = arrayLayers;
13074         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13075         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13076         params.dst.buffer.size           = defaultHalfSize * defaultHalfSize * arrayLayers;
13077         params.allocationKind            = testGroupParams->allocationKind;
13078         params.extensionFlags            = testGroupParams->extensionFlags;
13079         params.queueSelection            = testGroupParams->queueSelection;
13080         params.useSparseBinding          = testGroupParams->useSparseBinding;
13081 
13082         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
13083         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13084         {
13085             const VkDeviceSize offset               = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13086             const VkBufferImageCopy bufferImageCopy = {
13087                 offset,          // VkDeviceSize bufferOffset;
13088                 defaultHalfSize, // uint32_t bufferRowLength;
13089                 defaultHalfSize, // uint32_t bufferImageHeight;
13090                 {
13091                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13092                     0u,                        // uint32_t mipLevel;
13093                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13094                     1u,                        // uint32_t layerCount;
13095                 },                             // VkImageSubresourceLayers imageSubresource;
13096                 {0, 0, 0},                     // VkOffset3D imageOffset;
13097                 defaultHalfExtent              // VkExtent3D imageExtent;
13098             };
13099             CopyRegion copyRegion;
13100             copyRegion.bufferImageCopy = bufferImageCopy;
13101 
13102             params.regions.push_back(copyRegion);
13103         }
13104         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", params));
13105     }
13106 
13107     {
13108         TestParams params;
13109         const uint32_t baseLayer         = 0u;
13110         const uint32_t layerCount        = 16u;
13111         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
13112         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13113         params.src.image.extent          = defaultHalfExtent;
13114         params.src.image.extent.depth    = layerCount;
13115         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13116         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13117         params.src.image.fillMode        = FILL_MODE_RED;
13118         params.dst.buffer.size           = defaultHalfSize * defaultHalfSize * layerCount;
13119         params.dst.buffer.fillMode       = FILL_MODE_RED;
13120         params.allocationKind            = testGroupParams->allocationKind;
13121         params.extensionFlags            = testGroupParams->extensionFlags;
13122         params.queueSelection            = testGroupParams->queueSelection;
13123         params.useSparseBinding          = testGroupParams->useSparseBinding;
13124         params.extensionFlags |= MAINTENANCE_5;
13125 
13126         const VkImageSubresourceLayers defaultLayer = {
13127             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13128             0u,                        // uint32_t mipLevel;
13129             baseLayer,                 // uint32_t baseArrayLayer;
13130             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
13131         };
13132 
13133         const VkBufferImageCopy bufferImageCopy = {
13134             0,                // VkDeviceSize bufferOffset;
13135             0,                // uint32_t bufferRowLength;
13136             0,                // uint32_t bufferImageHeight;
13137             defaultLayer,     // VkImageSubresourceLayers imageSubresource;
13138             {0, 0, 0},        // VkOffset3D imageOffset;
13139             defaultHalfExtent // VkExtent3D imageExtent;
13140         };
13141 
13142         CopyRegion copyRegion;
13143         copyRegion.bufferImageCopy = bufferImageCopy;
13144 
13145         params.regions.push_back(copyRegion);
13146 
13147         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_all_remaining_layers", params));
13148     }
13149 
13150     {
13151         TestParams params;
13152         const uint32_t baseLayer         = 2u;
13153         const uint32_t layerCount        = 16u;
13154         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
13155         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13156         params.src.image.extent          = defaultHalfExtent;
13157         params.src.image.extent.depth    = layerCount;
13158         params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13159         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13160         params.src.image.fillMode        = FILL_MODE_RED;
13161         params.dst.buffer.size           = defaultHalfSize * defaultHalfSize * layerCount;
13162         params.dst.buffer.fillMode       = FILL_MODE_RED;
13163         params.allocationKind            = testGroupParams->allocationKind;
13164         params.extensionFlags            = testGroupParams->extensionFlags;
13165         params.queueSelection            = testGroupParams->queueSelection;
13166         params.useSparseBinding          = testGroupParams->useSparseBinding;
13167         params.extensionFlags |= MAINTENANCE_5;
13168 
13169         const VkImageSubresourceLayers defaultLayer = {
13170             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13171             0u,                        // uint32_t mipLevel;
13172             baseLayer,                 // uint32_t baseArrayLayer;
13173             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
13174         };
13175 
13176         const VkBufferImageCopy bufferImageCopy = {
13177             0,                // VkDeviceSize bufferOffset;
13178             0,                // uint32_t bufferRowLength;
13179             0,                // uint32_t bufferImageHeight;
13180             defaultLayer,     // VkImageSubresourceLayers imageSubresource;
13181             {0, 0, 0},        // VkOffset3D imageOffset;
13182             defaultHalfExtent // VkExtent3D imageExtent;
13183         };
13184 
13185         CopyRegion copyRegion;
13186         copyRegion.bufferImageCopy = bufferImageCopy;
13187 
13188         params.regions.push_back(copyRegion);
13189 
13190         group->addChild(new CopyImageToBufferTestCase(testCtx, "array_not_all_remaining_layers", params));
13191     }
13192 
13193     // those tests are performed for all queues, no need to repeat them
13194     // when testGroupParams->queueSelection is set to TransferOnly
13195     if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
13196     {
13197         VkExtent3D extents[] = {
13198             // Most miplevels will be multiples of four. All power-of-2 edge sizes. Never a weird mip level with extents smaller than the blockwidth.
13199             {64, 64, 1},
13200             // Odd mip edge multiples, two lowest miplevels on the y-axis will have widths of 3 and 1 respectively, less than the compression blocksize, and potentially tricky.
13201             {64, 192, 1},
13202         };
13203 
13204         uint32_t arrayLayers[] = {1, 2, 5};
13205 
13206         auto getCaseName = [](VkFormat format, VkExtent3D extent, uint32_t numLayers, std::string queueName)
13207         {
13208             std::string caseName = "mip_copies_" + getFormatCaseName(format) + "_" + std::to_string(extent.width) +
13209                                    "x" + std::to_string(extent.height);
13210             if (numLayers > 1)
13211                 caseName.append("_" + std::to_string(numLayers) + "_layers");
13212             caseName.append("_" + queueName);
13213             return caseName;
13214         };
13215 
13216         for (const auto &extent : extents)
13217             for (const auto numLayers : arrayLayers)
13218             {
13219                 TestParams params;
13220                 params.src.image.imageType       = VK_IMAGE_TYPE_2D;
13221                 params.src.image.extent          = extent;
13222                 params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13223                 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
13224                 params.allocationKind            = testGroupParams->allocationKind;
13225                 params.extensionFlags            = testGroupParams->extensionFlags;
13226                 params.queueSelection            = testGroupParams->queueSelection;
13227                 params.useSparseBinding          = testGroupParams->useSparseBinding;
13228                 params.arrayLayers               = numLayers;
13229 
13230                 for (const VkFormat *format = compressedFormatsFloats; *format != VK_FORMAT_UNDEFINED; format++)
13231                 {
13232                     params.src.image.format = *format;
13233                     {
13234                         params.queueSelection = QueueSelectionOptions::Universal;
13235                         group->addChild(new CopyCompressedImageToBufferTestCase(
13236                             testCtx, getCaseName(*format, params.src.image.extent, numLayers, "universal"), params));
13237                         params.queueSelection = QueueSelectionOptions::ComputeOnly;
13238                         group->addChild(new CopyCompressedImageToBufferTestCase(
13239                             testCtx, getCaseName(*format, params.src.image.extent, numLayers, "compute"), params));
13240                         params.queueSelection = QueueSelectionOptions::TransferOnly;
13241                         group->addChild(new CopyCompressedImageToBufferTestCase(
13242                             testCtx, getCaseName(*format, params.src.image.extent, numLayers, "transfer"), params));
13243                     }
13244                 }
13245             }
13246     }
13247 }
13248 
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)13249 void addBufferToDepthStencilTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
13250 {
13251     tcu::TestContext &testCtx = group->getTestContext();
13252 
13253     const struct
13254     {
13255         const char *name;
13256         const VkFormat format;
13257     } depthAndStencilFormats[] = {{"d16_unorm", VK_FORMAT_D16_UNORM},
13258                                   {"x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32},
13259                                   {"d32_sfloat", VK_FORMAT_D32_SFLOAT},
13260                                   {"d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT},
13261                                   {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
13262                                   {"d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT}};
13263 
13264     const VkImageSubresourceLayers depthSourceLayer = {
13265         VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
13266         0u,                        // uint32_t mipLevel;
13267         0u,                        // uint32_t baseArrayLayer;
13268         1u,                        // uint32_t layerCount;
13269     };
13270 
13271     const VkBufferImageCopy bufferDepthCopy = {
13272         0u,               // VkDeviceSize bufferOffset;
13273         0u,               // uint32_t bufferRowLength;
13274         0u,               // uint32_t bufferImageHeight;
13275         depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
13276         {0, 0, 0},        // VkOffset3D imageOffset;
13277         defaultExtent     // VkExtent3D imageExtent;
13278     };
13279 
13280     const VkBufferImageCopy bufferDepthCopyOffset = {
13281         32,                                          // VkDeviceSize bufferOffset;
13282         defaultHalfSize + defaultQuarterSize,        // uint32_t bufferRowLength;
13283         defaultHalfSize + defaultQuarterSize,        // uint32_t bufferImageHeight;
13284         depthSourceLayer,                            // VkImageSubresourceLayers imageSubresource;
13285         {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13286         defaultHalfExtent                            // VkExtent3D imageExtent;
13287     };
13288 
13289     const VkImageSubresourceLayers stencilSourceLayer = {
13290         VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
13291         0u,                          // uint32_t mipLevel;
13292         0u,                          // uint32_t baseArrayLayer;
13293         1u,                          // uint32_t layerCount;
13294     };
13295 
13296     const VkBufferImageCopy bufferStencilCopy = {
13297         0u,                 // VkDeviceSize bufferOffset;
13298         0u,                 // uint32_t bufferRowLength;
13299         0u,                 // uint32_t bufferImageHeight;
13300         stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
13301         {0, 0, 0},          // VkOffset3D imageOffset;
13302         defaultExtent       // VkExtent3D imageExtent;
13303     };
13304 
13305     const VkBufferImageCopy bufferStencilCopyOffset = {
13306         32,                                          // VkDeviceSize bufferOffset;
13307         defaultHalfSize + defaultQuarterSize,        // uint32_t bufferRowLength;
13308         defaultHalfSize + defaultQuarterSize,        // uint32_t bufferImageHeight;
13309         stencilSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
13310         {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13311         defaultHalfExtent                            // VkExtent3D imageExtent;
13312     };
13313 
13314     const bool useOffset[] = {false, true};
13315 
13316     // Note: Depth stencil tests I want to do
13317     // Formats: D16, D24S8, D32FS8
13318     // Test writing each component with separate CopyBufferToImage commands
13319     // Test writing both components in one CopyBufferToImage command
13320     // Swap order of writes of Depth & Stencil
13321     // whole surface, subimages?
13322     // Similar tests as BufferToImage?
13323     for (const auto config : depthAndStencilFormats)
13324         for (const auto offset : useOffset)
13325         {
13326             // TODO: Check that this format is supported before creating tests?
13327             //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
13328 
13329             CopyRegion copyDepthRegion;
13330             CopyRegion copyStencilRegion;
13331             TestParams params;
13332             const tcu::TextureFormat format = mapVkFormat(config.format);
13333             const bool hasDepth             = tcu::hasDepthComponent(format.order);
13334             const bool hasStencil           = tcu::hasStencilComponent(format.order);
13335             std::string testName            = config.name;
13336 
13337             if (offset)
13338             {
13339                 copyDepthRegion.bufferImageCopy   = bufferDepthCopyOffset;
13340                 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
13341                 testName                          = "buffer_offset_" + testName;
13342                 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
13343             }
13344             else
13345             {
13346                 copyDepthRegion.bufferImageCopy   = bufferDepthCopy;
13347                 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
13348                 params.src.buffer.size            = defaultSize * defaultSize;
13349             }
13350 
13351             params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13352             params.dst.image.format          = config.format;
13353             params.dst.image.extent          = defaultExtent;
13354             params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13355             params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13356             params.allocationKind            = allocationKind;
13357             params.extensionFlags            = extensionFlags;
13358 
13359             if (hasDepth && hasStencil)
13360             {
13361                 params.singleCommand = true;
13362 
13363                 params.regions.push_back(copyDepthRegion);
13364                 params.regions.push_back(copyStencilRegion);
13365 
13366                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_DS", params));
13367 
13368                 params.singleCommand = false;
13369 
13370                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_D_S", params));
13371 
13372                 params.regions.clear();
13373                 params.regions.push_back(copyStencilRegion);
13374                 params.regions.push_back(copyDepthRegion);
13375 
13376                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_S_D", params));
13377 
13378                 params.singleCommand = true;
13379                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_SD", params));
13380             }
13381 
13382             if (hasStencil)
13383             {
13384                 params.regions.clear();
13385                 params.regions.push_back(copyStencilRegion);
13386 
13387                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_S", params));
13388             }
13389 
13390             if (hasDepth)
13391             {
13392                 params.regions.clear();
13393                 params.regions.push_back(copyDepthRegion);
13394 
13395                 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, testName + "_D", params));
13396             }
13397         }
13398 }
13399 
add1dBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)13400 void add1dBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
13401 {
13402     tcu::TestContext &testCtx = group->getTestContext();
13403 
13404     {
13405         TestParams params;
13406         params.src.buffer.size           = defaultSize;
13407         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13408         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
13409         params.dst.image.extent          = default1dExtent;
13410         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13411         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13412         params.allocationKind            = testGroupParams->allocationKind;
13413         params.extensionFlags            = testGroupParams->extensionFlags;
13414         params.queueSelection            = testGroupParams->queueSelection;
13415         params.useSparseBinding          = testGroupParams->useSparseBinding;
13416 
13417         const VkBufferImageCopy bufferImageCopy = {
13418             0u,                 // VkDeviceSize bufferOffset;
13419             0u,                 // uint32_t bufferRowLength;
13420             0u,                 // uint32_t bufferImageHeight;
13421             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13422             {0, 0, 0},          // VkOffset3D imageOffset;
13423             default1dExtent     // VkExtent3D imageExtent;
13424         };
13425         CopyRegion copyRegion;
13426         copyRegion.bufferImageCopy = bufferImageCopy;
13427 
13428         params.regions.push_back(copyRegion);
13429 
13430         group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", params));
13431     }
13432 
13433     {
13434         TestParams params;
13435         uint32_t bufferImageHeight       = defaultSize + 1u;
13436         params.src.buffer.size           = bufferImageHeight;
13437         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13438         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
13439         params.dst.image.extent          = default1dExtent;
13440         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13441         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13442         params.allocationKind            = testGroupParams->allocationKind;
13443         params.extensionFlags            = testGroupParams->extensionFlags;
13444         params.queueSelection            = testGroupParams->queueSelection;
13445         params.useSparseBinding          = testGroupParams->useSparseBinding;
13446 
13447         const VkBufferImageCopy bufferImageCopy = {
13448             0u,                 // VkDeviceSize bufferOffset;
13449             0u,                 // uint32_t bufferRowLength;
13450             bufferImageHeight,  // uint32_t bufferImageHeight;
13451             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13452             {0, 0, 0},          // VkOffset3D imageOffset;
13453             default1dExtent     // VkExtent3D imageExtent;
13454         };
13455         CopyRegion copyRegion;
13456         copyRegion.bufferImageCopy = bufferImageCopy;
13457 
13458         params.regions.push_back(copyRegion);
13459 
13460         group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", params));
13461     }
13462 
13463     {
13464         TestParams params;
13465         uint32_t arrayLayers             = 16u;
13466         params.src.buffer.size           = defaultSize * arrayLayers;
13467         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13468         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13469         params.dst.image.extent          = default1dExtent;
13470         params.dst.image.extent.depth    = arrayLayers;
13471         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13472         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13473         params.allocationKind            = testGroupParams->allocationKind;
13474         params.extensionFlags            = testGroupParams->extensionFlags;
13475         params.queueSelection            = testGroupParams->queueSelection;
13476         params.useSparseBinding          = testGroupParams->useSparseBinding;
13477 
13478         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13479         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13480         {
13481             const VkDeviceSize offset               = defaultSize * pixelSize * arrayLayerNdx;
13482             const VkBufferImageCopy bufferImageCopy = {
13483                 offset, // VkDeviceSize bufferOffset;
13484                 0u,     // uint32_t bufferRowLength;
13485                 0u,     // uint32_t bufferImageHeight;
13486                 {
13487                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13488                     0u,                        // uint32_t mipLevel;
13489                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13490                     1u,                        // uint32_t layerCount;
13491                 },                             // VkImageSubresourceLayers imageSubresource;
13492                 {0, 0, 0},                     // VkOffset3D imageOffset;
13493                 default1dExtent                // VkExtent3D imageExtent;
13494             };
13495             CopyRegion copyRegion;
13496             copyRegion.bufferImageCopy = bufferImageCopy;
13497 
13498             params.regions.push_back(copyRegion);
13499         }
13500 
13501         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", params));
13502     }
13503 
13504     {
13505         TestParams params;
13506         const uint32_t baseLayer         = 0u;
13507         const uint32_t layerCount        = 16u;
13508         params.src.buffer.size           = defaultSize * layerCount;
13509         params.src.buffer.fillMode       = FILL_MODE_RED;
13510         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13511         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13512         params.dst.image.extent          = default1dExtent;
13513         params.dst.image.extent.depth    = layerCount;
13514         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13515         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13516         params.dst.image.fillMode        = FILL_MODE_RED;
13517         params.allocationKind            = testGroupParams->allocationKind;
13518         params.extensionFlags            = testGroupParams->extensionFlags;
13519         params.queueSelection            = testGroupParams->queueSelection;
13520         params.useSparseBinding          = testGroupParams->useSparseBinding;
13521         params.extensionFlags |= MAINTENANCE_5;
13522 
13523         const VkImageSubresourceLayers defaultLayer = {
13524             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13525             0u,                        // uint32_t mipLevel;
13526             baseLayer,                 // uint32_t baseArrayLayer;
13527             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
13528         };
13529 
13530         const VkBufferImageCopy bufferImageCopy = {
13531             0u,             // VkDeviceSize bufferOffset;
13532             0u,             // uint32_t bufferRowLength;
13533             0u,             // uint32_t bufferImageHeight;
13534             defaultLayer,   // VkImageSubresourceLayers imageSubresource;
13535             {0, 0, 0},      // VkOffset3D imageOffset;
13536             default1dExtent // VkExtent3D imageExtent;
13537         };
13538 
13539         CopyRegion copyRegion;
13540         copyRegion.bufferImageCopy = bufferImageCopy;
13541 
13542         params.regions.push_back(copyRegion);
13543 
13544         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_all_remaining_layers", params));
13545     }
13546 
13547     {
13548         TestParams params;
13549         const uint32_t baseLayer         = 2u;
13550         const uint32_t layerCount        = 16u;
13551         params.src.buffer.size           = defaultSize * layerCount;
13552         params.src.buffer.fillMode       = FILL_MODE_RED;
13553         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13554         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13555         params.dst.image.extent          = default1dExtent;
13556         params.dst.image.extent.depth    = layerCount;
13557         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13558         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13559         params.dst.image.fillMode        = FILL_MODE_RED;
13560         params.allocationKind            = testGroupParams->allocationKind;
13561         params.extensionFlags            = testGroupParams->extensionFlags;
13562         params.queueSelection            = testGroupParams->queueSelection;
13563         params.useSparseBinding          = testGroupParams->useSparseBinding;
13564         params.extensionFlags |= MAINTENANCE_5;
13565 
13566         const VkImageSubresourceLayers defaultLayer = {
13567             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13568             0u,                        // uint32_t mipLevel;
13569             baseLayer,                 // uint32_t baseArrayLayer;
13570             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
13571         };
13572 
13573         const VkBufferImageCopy bufferImageCopy = {
13574             0u,             // VkDeviceSize bufferOffset;
13575             0u,             // uint32_t bufferRowLength;
13576             0u,             // uint32_t bufferImageHeight;
13577             defaultLayer,   // VkImageSubresourceLayers imageSubresource;
13578             {0, 0, 0},      // VkOffset3D imageOffset;
13579             default1dExtent // VkExtent3D imageExtent;
13580         };
13581 
13582         CopyRegion copyRegion;
13583         copyRegion.bufferImageCopy = bufferImageCopy;
13584 
13585         params.regions.push_back(copyRegion);
13586 
13587         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_not_all_remaining_layers", params));
13588     }
13589 
13590     {
13591         TestParams params;
13592         uint32_t arrayLayers             = 16u;
13593         uint32_t bufferImageHeight       = defaultSize + 1u;
13594         params.src.buffer.size           = defaultSize * arrayLayers;
13595         params.dst.image.imageType       = VK_IMAGE_TYPE_1D;
13596         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13597         params.dst.image.extent          = default1dExtent;
13598         params.dst.image.extent.depth    = arrayLayers;
13599         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13600         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13601         params.allocationKind            = testGroupParams->allocationKind;
13602         params.extensionFlags            = testGroupParams->extensionFlags;
13603         params.queueSelection            = testGroupParams->queueSelection;
13604         params.useSparseBinding          = testGroupParams->useSparseBinding;
13605 
13606         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13607         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13608         {
13609             const VkDeviceSize offset               = defaultSize * pixelSize * arrayLayerNdx;
13610             const VkBufferImageCopy bufferImageCopy = {
13611                 offset,            // VkDeviceSize bufferOffset;
13612                 0u,                // uint32_t bufferRowLength;
13613                 bufferImageHeight, // uint32_t bufferImageHeight;
13614                 {
13615                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13616                     0u,                        // uint32_t mipLevel;
13617                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13618                     1u,                        // uint32_t layerCount;
13619                 },                             // VkImageSubresourceLayers imageSubresource;
13620                 {0, 0, 0},                     // VkOffset3D imageOffset;
13621                 default1dExtent                // VkExtent3D imageExtent;
13622             };
13623             CopyRegion copyRegion;
13624             copyRegion.bufferImageCopy = bufferImageCopy;
13625 
13626             params.regions.push_back(copyRegion);
13627         }
13628 
13629         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", params));
13630     }
13631 }
13632 
add2dBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)13633 void add2dBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
13634 {
13635     tcu::TestContext &testCtx = group->getTestContext();
13636 
13637     {
13638         TestParams params;
13639         params.src.buffer.size           = defaultSize * defaultSize;
13640         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13641         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UINT;
13642         params.dst.image.extent          = defaultExtent;
13643         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13644         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13645         params.allocationKind            = testGroupParams->allocationKind;
13646         params.extensionFlags            = testGroupParams->extensionFlags;
13647         params.queueSelection            = testGroupParams->queueSelection;
13648         params.useSparseBinding          = testGroupParams->useSparseBinding;
13649 
13650         const VkBufferImageCopy bufferImageCopy = {
13651             0u,                 // VkDeviceSize bufferOffset;
13652             0u,                 // uint32_t bufferRowLength;
13653             0u,                 // uint32_t bufferImageHeight;
13654             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13655             {0, 0, 0},          // VkOffset3D imageOffset;
13656             defaultExtent       // VkExtent3D imageExtent;
13657         };
13658         CopyRegion copyRegion;
13659         copyRegion.bufferImageCopy = bufferImageCopy;
13660 
13661         params.regions.push_back(copyRegion);
13662 
13663         group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", params));
13664     }
13665 
13666     {
13667         TestParams params;
13668         params.src.buffer.size           = defaultSize * defaultSize;
13669         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13670         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13671         params.dst.image.extent          = defaultExtent;
13672         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13673         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13674         params.allocationKind            = testGroupParams->allocationKind;
13675         params.extensionFlags            = testGroupParams->extensionFlags;
13676         params.queueSelection            = testGroupParams->queueSelection;
13677         params.useSparseBinding          = testGroupParams->useSparseBinding;
13678 
13679         CopyRegion region;
13680         uint32_t divisor = 1;
13681         for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor);
13682              offset += defaultQuarterSize / divisor++)
13683         {
13684             const VkBufferImageCopy bufferImageCopy = {
13685                 0u,                           // VkDeviceSize bufferOffset;
13686                 0u,                           // uint32_t bufferRowLength;
13687                 0u,                           // uint32_t bufferImageHeight;
13688                 defaultSourceLayer,           // VkImageSubresourceLayers imageSubresource;
13689                 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
13690                 {defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1} // VkExtent3D imageExtent;
13691             };
13692             region.bufferImageCopy = bufferImageCopy;
13693             params.regions.push_back(region);
13694         }
13695 
13696         group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", params));
13697     }
13698 
13699     {
13700         TestParams params;
13701         params.src.buffer.size           = defaultSize * defaultSize;
13702         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13703         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13704         params.dst.image.extent          = defaultExtent;
13705         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13706         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13707         params.allocationKind            = testGroupParams->allocationKind;
13708         params.extensionFlags            = testGroupParams->extensionFlags;
13709         params.queueSelection            = testGroupParams->queueSelection;
13710         params.useSparseBinding          = testGroupParams->useSparseBinding;
13711 
13712         const VkBufferImageCopy bufferImageCopy = {
13713             defaultQuarterSize,                          // VkDeviceSize bufferOffset;
13714             defaultHalfSize + defaultQuarterSize,        // uint32_t bufferRowLength;
13715             defaultHalfSize + defaultQuarterSize,        // uint32_t bufferImageHeight;
13716             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
13717             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13718             defaultHalfExtent                            // VkExtent3D imageExtent;
13719         };
13720         CopyRegion copyRegion;
13721         copyRegion.bufferImageCopy = bufferImageCopy;
13722 
13723         params.regions.push_back(copyRegion);
13724 
13725         group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", params));
13726     }
13727 
13728     if (testGroupParams->queueSelection == QueueSelectionOptions::Universal)
13729     {
13730         TestParams params;
13731         params.src.buffer.size           = defaultSize * defaultSize;
13732         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13733         params.dst.image.format          = VK_FORMAT_R8_UNORM;
13734         params.dst.image.extent          = defaultExtent;
13735         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13736         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13737         params.allocationKind            = testGroupParams->allocationKind;
13738         params.extensionFlags            = testGroupParams->extensionFlags;
13739         params.queueSelection            = testGroupParams->queueSelection;
13740         params.useSparseBinding          = testGroupParams->useSparseBinding;
13741 
13742         const VkBufferImageCopy bufferImageCopy = {
13743             defaultQuarterSize + 1u,                     // VkDeviceSize bufferOffset;
13744             defaultHalfSize + defaultQuarterSize,        // uint32_t bufferRowLength;
13745             defaultHalfSize + defaultQuarterSize,        // uint32_t bufferImageHeight;
13746             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
13747             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13748             defaultHalfExtent                            // VkExtent3D imageExtent;
13749         };
13750         CopyRegion copyRegion;
13751         copyRegion.bufferImageCopy = bufferImageCopy;
13752 
13753         params.regions.push_back(copyRegion);
13754 
13755         group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", params));
13756     }
13757 
13758     {
13759         TestParams params;
13760         params.src.buffer.size           = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
13761         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13762         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13763         params.dst.image.extent          = defaultExtent;
13764         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13765         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13766         params.allocationKind            = testGroupParams->allocationKind;
13767         params.extensionFlags            = testGroupParams->extensionFlags;
13768         params.queueSelection            = testGroupParams->queueSelection;
13769         params.useSparseBinding          = testGroupParams->useSparseBinding;
13770 
13771         const VkBufferImageCopy bufferImageCopy = {
13772             0u,                                          // VkDeviceSize bufferOffset;
13773             defaultSize,                                 // uint32_t bufferRowLength;
13774             defaultSize,                                 // uint32_t bufferImageHeight;
13775             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
13776             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13777             defaultHalfExtent                            // VkExtent3D imageExtent;
13778         };
13779         CopyRegion copyRegion;
13780         copyRegion.bufferImageCopy = bufferImageCopy;
13781 
13782         params.regions.push_back(copyRegion);
13783 
13784         group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", params));
13785     }
13786 
13787     {
13788         TestParams params;
13789         uint32_t bufferImageHeight       = defaultSize + 1u;
13790         params.src.buffer.size           = defaultSize * bufferImageHeight;
13791         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13792         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13793         params.dst.image.extent          = defaultExtent;
13794         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13795         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13796         params.allocationKind            = testGroupParams->allocationKind;
13797         params.extensionFlags            = testGroupParams->extensionFlags;
13798         params.queueSelection            = testGroupParams->queueSelection;
13799         params.useSparseBinding          = testGroupParams->useSparseBinding;
13800 
13801         const VkBufferImageCopy bufferImageCopy = {
13802             0u,                 // VkDeviceSize bufferOffset;
13803             defaultSize,        // uint32_t bufferRowLength;
13804             bufferImageHeight,  // uint32_t bufferImageHeight;
13805             defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
13806             {0, 0, 0},          // VkOffset3D imageOffset;
13807             defaultHalfExtent   // VkExtent3D imageExtent;
13808         };
13809         CopyRegion copyRegion;
13810         copyRegion.bufferImageCopy = bufferImageCopy;
13811 
13812         params.regions.push_back(copyRegion);
13813 
13814         group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", params));
13815     }
13816 
13817     {
13818         TestParams params;
13819         params.src.buffer.size           = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
13820         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13821         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13822         params.dst.image.extent          = defaultExtent;
13823         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13824         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13825         params.allocationKind            = testGroupParams->allocationKind;
13826         params.extensionFlags            = testGroupParams->extensionFlags;
13827         params.queueSelection            = testGroupParams->queueSelection;
13828         params.useSparseBinding          = testGroupParams->useSparseBinding;
13829 
13830         const VkBufferImageCopy bufferImageCopy = {
13831             defaultQuarterSize,                          // VkDeviceSize bufferOffset;
13832             defaultSize,                                 // uint32_t bufferRowLength;
13833             defaultSize,                                 // uint32_t bufferImageHeight;
13834             defaultSourceLayer,                          // VkImageSubresourceLayers imageSubresource;
13835             {defaultQuarterSize, defaultQuarterSize, 0}, // VkOffset3D imageOffset;
13836             defaultHalfExtent                            // VkExtent3D imageExtent;
13837         };
13838         CopyRegion copyRegion;
13839         copyRegion.bufferImageCopy = bufferImageCopy;
13840 
13841         params.regions.push_back(copyRegion);
13842 
13843         group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", params));
13844     }
13845 
13846     {
13847         TestParams params;
13848         uint32_t arrayLayers             = 16u;
13849         params.src.buffer.size           = defaultHalfSize * defaultHalfSize * arrayLayers;
13850         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13851         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13852         params.dst.image.extent          = defaultHalfExtent;
13853         params.dst.image.extent.depth    = arrayLayers;
13854         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13855         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13856         params.allocationKind            = testGroupParams->allocationKind;
13857         params.extensionFlags            = testGroupParams->extensionFlags;
13858         params.queueSelection            = testGroupParams->queueSelection;
13859         params.useSparseBinding          = testGroupParams->useSparseBinding;
13860 
13861         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13862         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13863         {
13864             const VkDeviceSize offset               = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13865             const VkBufferImageCopy bufferImageCopy = {
13866                 offset, // VkDeviceSize bufferOffset;
13867                 0u,     // uint32_t bufferRowLength;
13868                 0u,     // uint32_t bufferImageHeight;
13869                 {
13870                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13871                     0u,                        // uint32_t mipLevel;
13872                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13873                     1u,                        // uint32_t layerCount;
13874                 },                             // VkImageSubresourceLayers imageSubresource;
13875                 {0, 0, 0},                     // VkOffset3D imageOffset;
13876                 defaultHalfExtent              // VkExtent3D imageExtent;
13877             };
13878             CopyRegion copyRegion;
13879             copyRegion.bufferImageCopy = bufferImageCopy;
13880 
13881             params.regions.push_back(copyRegion);
13882         }
13883         group->addChild(new CopyBufferToImageTestCase(testCtx, "array", params));
13884     }
13885 
13886     {
13887         TestParams params;
13888         uint32_t arrayLayers             = 16u;
13889         uint32_t bufferImageHeight       = defaultHalfSize + 1u;
13890         params.src.buffer.size           = defaultHalfSize * bufferImageHeight * arrayLayers;
13891         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13892         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13893         params.dst.image.extent          = defaultHalfExtent;
13894         params.dst.image.extent.depth    = arrayLayers;
13895         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13896         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13897         params.allocationKind            = testGroupParams->allocationKind;
13898         params.extensionFlags            = testGroupParams->extensionFlags;
13899         params.queueSelection            = testGroupParams->queueSelection;
13900         params.useSparseBinding          = testGroupParams->useSparseBinding;
13901 
13902         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13903         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13904         {
13905             const VkDeviceSize offset               = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
13906             const VkBufferImageCopy bufferImageCopy = {
13907                 offset,            // VkDeviceSize bufferOffset;
13908                 defaultHalfSize,   // uint32_t bufferRowLength;
13909                 bufferImageHeight, // uint32_t bufferImageHeight;
13910                 {
13911                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13912                     0u,                        // uint32_t mipLevel;
13913                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13914                     1u,                        // uint32_t layerCount;
13915                 },                             // VkImageSubresourceLayers imageSubresource;
13916                 {0, 0, 0},                     // VkOffset3D imageOffset;
13917                 defaultHalfExtent              // VkExtent3D imageExtent;
13918             };
13919             CopyRegion copyRegion;
13920             copyRegion.bufferImageCopy = bufferImageCopy;
13921 
13922             params.regions.push_back(copyRegion);
13923         }
13924         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", params));
13925     }
13926 
13927     {
13928         TestParams params;
13929         uint32_t arrayLayers             = 16u;
13930         params.src.buffer.size           = defaultHalfSize * defaultHalfSize * arrayLayers;
13931         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13932         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13933         params.dst.image.extent          = defaultHalfExtent;
13934         params.dst.image.extent.depth    = arrayLayers;
13935         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13936         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13937         params.allocationKind            = testGroupParams->allocationKind;
13938         params.extensionFlags            = testGroupParams->extensionFlags;
13939         params.queueSelection            = testGroupParams->queueSelection;
13940         params.useSparseBinding          = testGroupParams->useSparseBinding;
13941 
13942         const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
13943         for (uint32_t arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
13944         {
13945             const VkDeviceSize offset               = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
13946             const VkBufferImageCopy bufferImageCopy = {
13947                 offset,          // VkDeviceSize bufferOffset;
13948                 defaultHalfSize, // uint32_t bufferRowLength;
13949                 defaultHalfSize, // uint32_t bufferImageHeight;
13950                 {
13951                     VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13952                     0u,                        // uint32_t mipLevel;
13953                     arrayLayerNdx,             // uint32_t baseArrayLayer;
13954                     1u,                        // uint32_t layerCount;
13955                 },                             // VkImageSubresourceLayers imageSubresource;
13956                 {0, 0, 0},                     // VkOffset3D imageOffset;
13957                 defaultHalfExtent              // VkExtent3D imageExtent;
13958             };
13959             CopyRegion copyRegion;
13960             copyRegion.bufferImageCopy = bufferImageCopy;
13961 
13962             params.regions.push_back(copyRegion);
13963         }
13964         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", params));
13965     }
13966 
13967     {
13968         TestParams params;
13969         const uint32_t baseLayer         = 0u;
13970         const uint32_t layerCount        = 16u;
13971         params.src.buffer.size           = defaultHalfSize * defaultHalfSize * layerCount;
13972         params.src.buffer.fillMode       = FILL_MODE_RED;
13973         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
13974         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
13975         params.dst.image.extent          = defaultHalfExtent;
13976         params.dst.image.extent.depth    = layerCount;
13977         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
13978         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
13979         params.dst.image.fillMode        = FILL_MODE_RED;
13980         params.allocationKind            = testGroupParams->allocationKind;
13981         params.extensionFlags            = testGroupParams->extensionFlags;
13982         params.queueSelection            = testGroupParams->queueSelection;
13983         params.useSparseBinding          = testGroupParams->useSparseBinding;
13984         params.extensionFlags |= MAINTENANCE_5;
13985 
13986         const VkImageSubresourceLayers defaultLayer = {
13987             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
13988             0u,                        // uint32_t mipLevel;
13989             baseLayer,                 // uint32_t baseArrayLayer;
13990             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
13991         };
13992 
13993         const VkBufferImageCopy bufferImageCopy = {
13994             0,                // VkDeviceSize bufferOffset;
13995             0,                // uint32_t bufferRowLength;
13996             0,                // uint32_t bufferImageHeight;
13997             defaultLayer,     // VkImageSubresourceLayers imageSubresource;
13998             {0, 0, 0},        // VkOffset3D imageOffset;
13999             defaultHalfExtent // VkExtent3D imageExtent;
14000         };
14001 
14002         CopyRegion copyRegion;
14003         copyRegion.bufferImageCopy = bufferImageCopy;
14004 
14005         params.regions.push_back(copyRegion);
14006 
14007         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_all_remaining_layers", params));
14008     }
14009 
14010     {
14011         TestParams params;
14012         const uint32_t baseLayer         = 2u;
14013         const uint32_t layerCount        = 16u;
14014         params.src.buffer.size           = defaultHalfSize * defaultHalfSize * layerCount;
14015         params.src.buffer.fillMode       = FILL_MODE_RED;
14016         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
14017         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
14018         params.dst.image.extent          = defaultHalfExtent;
14019         params.dst.image.extent.depth    = layerCount;
14020         params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
14021         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14022         params.dst.image.fillMode        = FILL_MODE_RED;
14023         params.allocationKind            = testGroupParams->allocationKind;
14024         params.extensionFlags            = testGroupParams->extensionFlags;
14025         params.queueSelection            = testGroupParams->queueSelection;
14026         params.useSparseBinding          = testGroupParams->useSparseBinding;
14027         params.extensionFlags |= MAINTENANCE_5;
14028 
14029         const VkImageSubresourceLayers defaultLayer = {
14030             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14031             0u,                        // uint32_t mipLevel;
14032             baseLayer,                 // uint32_t baseArrayLayer;
14033             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
14034         };
14035 
14036         const VkBufferImageCopy bufferImageCopy = {
14037             0,                // VkDeviceSize bufferOffset;
14038             0,                // uint32_t bufferRowLength;
14039             0,                // uint32_t bufferImageHeight;
14040             defaultLayer,     // VkImageSubresourceLayers imageSubresource;
14041             {0, 0, 0},        // VkOffset3D imageOffset;
14042             defaultHalfExtent // VkExtent3D imageExtent;
14043         };
14044 
14045         CopyRegion copyRegion;
14046         copyRegion.bufferImageCopy = bufferImageCopy;
14047 
14048         params.regions.push_back(copyRegion);
14049 
14050         group->addChild(new CopyBufferToImageTestCase(testCtx, "array_not_all_remaining_layers", params));
14051     }
14052 }
14053 
addBufferToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14054 void addBufferToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
14055 {
14056     tcu::TestContext &testCtx = group->getTestContext();
14057 
14058     {
14059         TestParams params;
14060         params.src.buffer.size  = defaultSize;
14061         params.dst.buffer.size  = defaultSize;
14062         params.allocationKind   = testGroupParams->allocationKind;
14063         params.extensionFlags   = testGroupParams->extensionFlags;
14064         params.queueSelection   = testGroupParams->queueSelection;
14065         params.useSparseBinding = testGroupParams->useSparseBinding;
14066 
14067         const VkBufferCopy bufferCopy = {
14068             0u,          // VkDeviceSize srcOffset;
14069             0u,          // VkDeviceSize dstOffset;
14070             defaultSize, // VkDeviceSize size;
14071         };
14072 
14073         CopyRegion copyRegion;
14074         copyRegion.bufferCopy = bufferCopy;
14075         params.regions.push_back(copyRegion);
14076 
14077         group->addChild(new BufferToBufferTestCase(testCtx, "whole", params));
14078     }
14079 
14080     // Filter is VK_FILTER_NEAREST.
14081     {
14082         TestParams params;
14083         params.src.buffer.size  = defaultQuarterSize;
14084         params.dst.buffer.size  = defaultQuarterSize;
14085         params.allocationKind   = testGroupParams->allocationKind;
14086         params.extensionFlags   = testGroupParams->extensionFlags;
14087         params.queueSelection   = testGroupParams->queueSelection;
14088         params.useSparseBinding = testGroupParams->useSparseBinding;
14089 
14090         const VkBufferCopy bufferCopy = {
14091             12u, // VkDeviceSize srcOffset;
14092             4u,  // VkDeviceSize dstOffset;
14093             1u,  // VkDeviceSize size;
14094         };
14095 
14096         CopyRegion copyRegion;
14097         copyRegion.bufferCopy = bufferCopy;
14098         params.regions.push_back(copyRegion);
14099 
14100         group->addChild(new BufferToBufferTestCase(testCtx, "partial", params));
14101     }
14102 
14103     {
14104         const uint32_t size = 16;
14105         TestParams params;
14106         params.src.buffer.size  = size;
14107         params.dst.buffer.size  = size * (size + 1);
14108         params.allocationKind   = testGroupParams->allocationKind;
14109         params.extensionFlags   = testGroupParams->extensionFlags;
14110         params.queueSelection   = testGroupParams->queueSelection;
14111         params.useSparseBinding = testGroupParams->useSparseBinding;
14112 
14113         // Copy region with size 1..size
14114         for (unsigned int i = 1; i <= size; i++)
14115         {
14116             const VkBufferCopy bufferCopy = {
14117                 0,        // VkDeviceSize srcOffset;
14118                 i * size, // VkDeviceSize dstOffset;
14119                 i,        // VkDeviceSize size;
14120             };
14121 
14122             CopyRegion copyRegion;
14123             copyRegion.bufferCopy = bufferCopy;
14124             params.regions.push_back(copyRegion);
14125         }
14126 
14127         group->addChild(new BufferToBufferTestCase(testCtx, "regions", params));
14128     }
14129 
14130     {
14131         TestParams params;
14132         params.src.buffer.size  = 32;
14133         params.dst.buffer.size  = 32;
14134         params.allocationKind   = testGroupParams->allocationKind;
14135         params.extensionFlags   = testGroupParams->extensionFlags;
14136         params.queueSelection   = testGroupParams->queueSelection;
14137         params.useSparseBinding = testGroupParams->useSparseBinding;
14138 
14139         // Copy four unaligned regions
14140         for (unsigned int i = 0; i < 4; i++)
14141         {
14142             const VkBufferCopy bufferCopy{
14143                 3 + i * 3, // VkDeviceSize    srcOffset;    3  6   9  12
14144                 1 + i * 5, // VkDeviceSize    dstOffset;    1  6  11  16
14145                 2 + i,     // VkDeviceSize    size;        2  3   4   5
14146             };
14147 
14148             CopyRegion copyRegion;
14149             copyRegion.bufferCopy = bufferCopy;
14150             params.regions.push_back(copyRegion);
14151         }
14152 
14153         group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", params));
14154     }
14155 }
14156 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)14157 void addBlittingImageSimpleTests(tcu::TestCaseGroup *group, TestParams &params)
14158 {
14159     tcu::TestContext &testCtx = group->getTestContext();
14160 
14161     // Filter is VK_FILTER_NEAREST.
14162     {
14163         params.filter = VK_FILTER_NEAREST;
14164 
14165         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14166         group->addChild(new BlitImageTestCase(testCtx, "nearest", params));
14167 
14168         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14169         group->addChild(
14170             new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", params));
14171 
14172         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14173         group->addChild(
14174             new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", params));
14175     }
14176 
14177     // Filter is VK_FILTER_LINEAR.
14178     {
14179         params.filter = VK_FILTER_LINEAR;
14180 
14181         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14182         group->addChild(new BlitImageTestCase(testCtx, "linear", params));
14183 
14184         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14185         group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", params));
14186 
14187         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14188         group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", params));
14189     }
14190 
14191     // Filter is VK_FILTER_CUBIC_EXT.
14192     // Cubic filtering can only be used with 2D images.
14193     if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
14194     {
14195         params.filter = VK_FILTER_CUBIC_EXT;
14196 
14197         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
14198         group->addChild(new BlitImageTestCase(testCtx, "cubic", params));
14199 
14200         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
14201         group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", params));
14202 
14203         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
14204         group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", params));
14205     }
14206 }
14207 
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)14208 void addBlittingImageSimpleWholeTests(tcu::TestCaseGroup *group, TestParams params)
14209 {
14210     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14211     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14212     params.src.image.extent       = defaultExtent;
14213     params.dst.image.extent       = defaultExtent;
14214     params.src.image.extent.depth = imageDepth;
14215     params.dst.image.extent.depth = imageDepth;
14216 
14217     {
14218         const VkImageBlit imageBlit = {
14219             defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
14220             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14221 
14222             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14223             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14224         };
14225 
14226         CopyRegion region;
14227         region.imageBlit = imageBlit;
14228         params.regions.push_back(region);
14229     }
14230 
14231     addBlittingImageSimpleTests(group, params);
14232 }
14233 
addBlittingImageArrayTests(tcu::TestCaseGroup * group,TestParams params)14234 void addBlittingImageArrayTests(tcu::TestCaseGroup *group, TestParams params)
14235 {
14236     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14237 
14238     tcu::TestContext &testCtx = group->getTestContext();
14239 
14240     {
14241         const uint32_t baseLayer      = 0u;
14242         const uint32_t layerCount     = 16u;
14243         params.dst.image.format       = VK_FORMAT_R8G8B8A8_UNORM;
14244         params.src.image.extent       = defaultExtent;
14245         params.dst.image.extent       = defaultExtent;
14246         params.src.image.extent.depth = layerCount;
14247         params.dst.image.extent.depth = layerCount;
14248         params.filter                 = VK_FILTER_NEAREST;
14249         params.extensionFlags |= MAINTENANCE_5;
14250 
14251         const VkImageSubresourceLayers defaultLayer = {
14252             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14253             0u,                        // uint32_t mipLevel;
14254             baseLayer,                 // uint32_t baseArrayLayer;
14255             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
14256         };
14257 
14258         const VkImageBlit imageBlit = {
14259             defaultLayer,                               // VkImageSubresourceLayers srcSubresource;
14260             {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
14261 
14262             defaultLayer,                              // VkImageSubresourceLayers dstSubresource;
14263             {{0, 0, 0}, {defaultSize, defaultSize, 1}} // VkOffset3D dstOffset[2];
14264         };
14265 
14266         CopyRegion region;
14267         region.imageBlit = imageBlit;
14268 
14269         params.regions.push_back(region);
14270 
14271         group->addChild(new BlitImageTestCase(testCtx, "all_remaining_layers", params));
14272     }
14273 
14274     params.regions.clear();
14275 
14276     {
14277         const uint32_t baseLayer      = 2u;
14278         const uint32_t layerCount     = 16u;
14279         params.dst.image.format       = VK_FORMAT_R8G8B8A8_UNORM;
14280         params.src.image.extent       = defaultExtent;
14281         params.dst.image.extent       = defaultExtent;
14282         params.src.image.extent.depth = layerCount;
14283         params.dst.image.extent.depth = layerCount;
14284         params.filter                 = VK_FILTER_NEAREST;
14285         params.extensionFlags |= MAINTENANCE_5;
14286 
14287         const VkImageSubresourceLayers defaultLayer = {
14288             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
14289             0u,                        // uint32_t mipLevel;
14290             baseLayer,                 // uint32_t baseArrayLayer;
14291             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
14292         };
14293 
14294         const VkImageBlit imageBlit = {
14295             defaultLayer,                               // VkImageSubresourceLayers srcSubresource;
14296             {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
14297 
14298             defaultLayer,                              // VkImageSubresourceLayers dstSubresource;
14299             {{0, 0, 0}, {defaultSize, defaultSize, 1}} // VkOffset3D dstOffset[2];
14300         };
14301 
14302         CopyRegion region;
14303         region.imageBlit = imageBlit;
14304 
14305         params.regions.push_back(region);
14306 
14307         group->addChild(new BlitImageTestCase(testCtx, "not_all_remaining_layers", params));
14308     }
14309 }
14310 
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)14311 void addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup *group, TestParams params)
14312 {
14313     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14314     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14315     params.src.image.extent       = defaultExtent;
14316     params.dst.image.extent       = defaultExtent;
14317     params.src.image.extent.depth = imageDepth;
14318     params.dst.image.extent.depth = imageDepth;
14319 
14320     {
14321         const VkImageBlit imageBlit = {
14322             defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
14323             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14324 
14325             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14326             {{defaultSize, defaultSize, 0}, {0, 0, imageDepth}} // VkOffset3D dstOffset[2];
14327         };
14328 
14329         CopyRegion region;
14330         region.imageBlit = imageBlit;
14331         params.regions.push_back(region);
14332     }
14333 
14334     addBlittingImageSimpleTests(group, params);
14335 }
14336 
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)14337 void addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup *group, TestParams params)
14338 {
14339     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14340     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14341     params.src.image.extent       = defaultExtent;
14342     params.dst.image.extent       = defaultExtent;
14343     params.src.image.extent.depth = imageDepth;
14344     params.dst.image.extent.depth = imageDepth;
14345 
14346     {
14347         const VkImageBlit imageBlit = {
14348             defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
14349             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14350 
14351             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14352             {{defaultSize, 0, 0}, {0, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14353         };
14354 
14355         CopyRegion region;
14356         region.imageBlit = imageBlit;
14357         params.regions.push_back(region);
14358     }
14359 
14360     addBlittingImageSimpleTests(group, params);
14361 }
14362 
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)14363 void addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup *group, TestParams params)
14364 {
14365     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14366     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14367     params.src.image.extent       = defaultExtent;
14368     params.dst.image.extent       = defaultExtent;
14369     params.src.image.extent.depth = imageDepth;
14370     params.dst.image.extent.depth = imageDepth;
14371 
14372     {
14373         const VkImageBlit imageBlit = {
14374             defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
14375             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14376 
14377             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14378             {{0, defaultSize, 0}, {defaultSize, 0, imageDepth}} // VkOffset3D dstOffset[2];
14379         };
14380 
14381         CopyRegion region;
14382         region.imageBlit = imageBlit;
14383         params.regions.push_back(region);
14384     }
14385 
14386     addBlittingImageSimpleTests(group, params);
14387 }
14388 
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)14389 void addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup *group, TestParams params)
14390 {
14391     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14392     DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
14393     params.src.image.extent       = defaultExtent;
14394     params.dst.image.extent       = defaultExtent;
14395     params.src.image.extent.depth = defaultSize;
14396     params.dst.image.extent.depth = defaultSize;
14397 
14398     {
14399         const VkImageBlit imageBlit = {
14400             defaultSourceLayer,                                   // VkImageSubresourceLayers srcSubresource;
14401             {{0, 0, 0}, {defaultSize, defaultSize, defaultSize}}, // VkOffset3D srcOffsets[2];
14402 
14403             defaultSourceLayer,                                  // VkImageSubresourceLayers dstSubresource;
14404             {{0, 0, defaultSize}, {defaultSize, defaultSize, 0}} // VkOffset3D dstOffset[2];
14405         };
14406 
14407         CopyRegion region;
14408         region.imageBlit = imageBlit;
14409         params.regions.push_back(region);
14410     }
14411 
14412     addBlittingImageSimpleTests(group, params);
14413 }
14414 
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)14415 void addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup *group, TestParams params)
14416 {
14417     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14418     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14419     params.src.image.extent       = defaultExtent;
14420     params.dst.image.extent       = defaultExtent;
14421     params.src.image.extent.depth = imageDepth;
14422     params.dst.image.extent.depth = imageDepth;
14423 
14424     // No mirroring.
14425     {
14426         const VkImageBlit imageBlit = {
14427             defaultSourceLayer,                                          // VkImageSubresourceLayers srcSubresource;
14428             {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14429 
14430             defaultSourceLayer,                                         // VkImageSubresourceLayers dstSubresource;
14431             {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}} // VkOffset3D dstOffset[2];
14432         };
14433 
14434         CopyRegion region;
14435         region.imageBlit = imageBlit;
14436         params.regions.push_back(region);
14437     }
14438 
14439     // Flipping y coordinates.
14440     {
14441         const VkImageBlit imageBlit = {
14442             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14443             {{defaultHalfSize, 0, 0}, {defaultSize, defaultHalfSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14444 
14445             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14446             {{defaultHalfSize, defaultHalfSize, 0}, {defaultSize, 0, imageDepth}} // VkOffset3D dstOffset[2];
14447         };
14448         CopyRegion region;
14449         region.imageBlit = imageBlit;
14450         params.regions.push_back(region);
14451     }
14452 
14453     // Flipping x coordinates.
14454     {
14455         const VkImageBlit imageBlit = {
14456             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14457             {{0, defaultHalfSize, 0}, {defaultHalfSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14458 
14459             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14460             {{defaultHalfSize, defaultHalfSize, 0}, {0, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14461         };
14462 
14463         CopyRegion region;
14464         region.imageBlit = imageBlit;
14465         params.regions.push_back(region);
14466     }
14467 
14468     // Flipping x and y coordinates.
14469     {
14470         const VkImageBlit imageBlit = {
14471             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14472             {{defaultHalfSize, defaultHalfSize, 0},
14473              {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14474 
14475             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14476             {{defaultSize, defaultSize, 0}, {defaultHalfSize, defaultHalfSize, imageDepth}} // VkOffset3D dstOffset[2];
14477         };
14478 
14479         CopyRegion region;
14480         region.imageBlit = imageBlit;
14481         params.regions.push_back(region);
14482     }
14483 
14484     addBlittingImageSimpleTests(group, params);
14485 }
14486 
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)14487 void addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup *group, TestParams params)
14488 {
14489     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14490     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14491     const int32_t halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
14492     params.src.image.extent       = defaultExtent;
14493     params.dst.image.extent       = defaultHalfExtent;
14494     params.src.image.extent.depth = imageDepth;
14495     params.dst.image.extent.depth = halfImageDepth;
14496 
14497     {
14498         const VkImageBlit imageBlit = {
14499             defaultSourceLayer,                                  // VkImageSubresourceLayers srcSubresource;
14500             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}}, // VkOffset3D srcOffsets[2];
14501 
14502             defaultSourceLayer,                                             // VkImageSubresourceLayers dstSubresource;
14503             {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, halfImageDepth}} // VkOffset3D dstOffset[2];
14504         };
14505 
14506         CopyRegion region;
14507         region.imageBlit = imageBlit;
14508         params.regions.push_back(region);
14509     }
14510 
14511     addBlittingImageSimpleTests(group, params);
14512 }
14513 
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)14514 void addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup *group, TestParams params)
14515 {
14516     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14517     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14518     const int32_t halfImageDepth  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
14519     params.src.image.extent       = defaultHalfExtent;
14520     params.dst.image.extent       = defaultExtent;
14521     params.src.image.extent.depth = halfImageDepth;
14522     params.dst.image.extent.depth = imageDepth;
14523 
14524     {
14525         const VkImageBlit imageBlit = {
14526             defaultSourceLayer,                                              // VkImageSubresourceLayers srcSubresource;
14527             {{0, 0, 0}, {defaultHalfSize, defaultHalfSize, halfImageDepth}}, // VkOffset3D srcOffsets[2];
14528 
14529             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14530             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14531         };
14532 
14533         CopyRegion region;
14534         region.imageBlit = imageBlit;
14535         params.regions.push_back(region);
14536     }
14537 
14538     addBlittingImageSimpleTests(group, params);
14539 }
14540 
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)14541 void addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup *group, TestParams params)
14542 {
14543     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14544     const int32_t imageDepth      = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
14545     const int32_t srcDepthOffset  = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
14546     const int32_t srcDepthSize    = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
14547     params.src.image.extent       = defaultExtent;
14548     params.dst.image.extent       = defaultExtent;
14549     params.src.image.extent.depth = imageDepth;
14550     params.dst.image.extent.depth = imageDepth;
14551 
14552     {
14553         const VkImageBlit imageBlit = {
14554             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14555             {{defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
14556              {defaultQuarterSize * 3, defaultQuarterSize * 3, srcDepthSize}}, // VkOffset3D srcOffsets[2];
14557 
14558             defaultSourceLayer,                                 // VkImageSubresourceLayers dstSubresource;
14559             {{0, 0, 0}, {defaultSize, defaultSize, imageDepth}} // VkOffset3D dstOffset[2];
14560         };
14561 
14562         CopyRegion region;
14563         region.imageBlit = imageBlit;
14564         params.regions.push_back(region);
14565     }
14566 
14567     addBlittingImageSimpleTests(group, params);
14568 }
14569 
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)14570 void addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup *group, TestParams params)
14571 {
14572     DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
14573     const bool is3dBlit     = params.src.image.imageType == VK_IMAGE_TYPE_3D;
14574     params.src.image.extent = defaultExtent;
14575     params.dst.image.extent = defaultExtent;
14576 
14577     if (is3dBlit)
14578     {
14579         params.src.image.extent.depth = defaultSize;
14580         params.dst.image.extent.depth = defaultSize;
14581     }
14582 
14583     {
14584         CopyRegion region;
14585         for (int i = 0; i < defaultSize; i += defaultQuarterSize)
14586         {
14587             const VkImageBlit imageBlit = {
14588                 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14589                 {{defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i,
14590                   is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
14591                  {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}}, // VkOffset3D srcOffsets[2];
14592 
14593                 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14594                 {{i, i, is3dBlit ? i : 0},
14595                  {i + defaultQuarterSize, i + defaultQuarterSize,
14596                   is3dBlit ? i + defaultQuarterSize : 1}} // VkOffset3D dstOffset[2];
14597             };
14598             region.imageBlit = imageBlit;
14599             params.regions.push_back(region);
14600         }
14601     }
14602 
14603     addBlittingImageSimpleTests(group, params);
14604 }
14605 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)14606 void addBlittingImageSimpleTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
14607 {
14608     TestParams params;
14609     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
14610     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
14611     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14612     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
14613     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14614     params.allocationKind            = allocationKind;
14615     params.extensionFlags            = extensionFlags;
14616     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
14617     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
14618     addTestGroup(group, "whole", addBlittingImageSimpleWholeTests, params);
14619     addTestGroup(group, "array", addBlittingImageArrayTests, params);
14620     addTestGroup(group, "mirror_xy", addBlittingImageSimpleMirrorXYTests, params);
14621     addTestGroup(group, "mirror_x", addBlittingImageSimpleMirrorXTests, params);
14622     addTestGroup(group, "mirror_y", addBlittingImageSimpleMirrorYTests, params);
14623     addTestGroup(group, "mirror_subregions", addBlittingImageSimpleMirrorSubregionsTests, params);
14624     addTestGroup(group, "scaling_whole1", addBlittingImageSimpleScalingWhole1Tests, params);
14625     addTestGroup(group, "scaling_whole2", addBlittingImageSimpleScalingWhole2Tests, params);
14626     addTestGroup(group, "scaling_and_offset", addBlittingImageSimpleScalingAndOffsetTests, params);
14627     addTestGroup(group, "without_scaling_partial", addBlittingImageSimpleWithoutScalingPartialTests, params);
14628 
14629     params.src.image.imageType = VK_IMAGE_TYPE_3D;
14630     params.dst.image.imageType = VK_IMAGE_TYPE_3D;
14631     addTestGroup(group, "whole_3d", addBlittingImageSimpleWholeTests, params);
14632     addTestGroup(group, "mirror_xy_3d", addBlittingImageSimpleMirrorXYTests, params);
14633     addTestGroup(group, "mirror_x_3d", addBlittingImageSimpleMirrorXTests, params);
14634     addTestGroup(group, "mirror_y_3d", addBlittingImageSimpleMirrorYTests, params);
14635     addTestGroup(group, "mirror_z_3d", addBlittingImageSimpleMirrorZTests, params);
14636     addTestGroup(group, "mirror_subregions_3d", addBlittingImageSimpleMirrorSubregionsTests, params);
14637     addTestGroup(group, "scaling_whole1_3d", addBlittingImageSimpleScalingWhole1Tests, params);
14638     addTestGroup(group, "scaling_whole2_3d", addBlittingImageSimpleScalingWhole2Tests, params);
14639     addTestGroup(group, "scaling_and_offset_3d", addBlittingImageSimpleScalingAndOffsetTests, params);
14640     addTestGroup(group, "without_scaling_partial_3d", addBlittingImageSimpleWithoutScalingPartialTests, params);
14641 }
14642 
14643 enum FilterMaskBits
14644 {
14645     FILTER_MASK_NEAREST = 0, // Always tested.
14646     FILTER_MASK_LINEAR  = (1u << 0),
14647     FILTER_MASK_CUBIC   = (1u << 1),
14648 };
14649 
14650 using FilterMask = uint32_t;
14651 
makeFilterMask(bool onlyNearest,bool discardCubicFilter)14652 FilterMask makeFilterMask(bool onlyNearest, bool discardCubicFilter)
14653 {
14654     FilterMask mask = FILTER_MASK_NEAREST;
14655 
14656     if (!onlyNearest)
14657     {
14658         mask |= FILTER_MASK_LINEAR;
14659         if (!discardCubicFilter)
14660             mask |= FILTER_MASK_CUBIC;
14661     }
14662 
14663     return mask;
14664 }
14665 
14666 struct BlitColorTestParams
14667 {
14668     TestParams params;
14669     const VkFormat *compatibleFormats;
14670     FilterMask testFilters;
14671 };
14672 
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)14673 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams &testParams)
14674 {
14675     bool result = true;
14676 
14677     if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
14678     {
14679         DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
14680 
14681         result = de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
14682                  de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
14683     }
14684 
14685     return result;
14686 }
14687 
14688 const VkFormat linearOtherImageFormatsToTest[] = {
14689     // From compatibleFormats8Bit
14690     VK_FORMAT_R4G4_UNORM_PACK8,
14691     VK_FORMAT_R8_SRGB,
14692 
14693     // From compatibleFormats16Bit
14694     VK_FORMAT_R4G4B4A4_UNORM_PACK16,
14695     VK_FORMAT_R16_SFLOAT,
14696 
14697     // From compatibleFormats24Bit
14698     VK_FORMAT_R8G8B8_UNORM,
14699     VK_FORMAT_B8G8R8_SRGB,
14700 
14701     // From compatibleFormats32Bit
14702     VK_FORMAT_R8G8B8A8_UNORM,
14703     VK_FORMAT_R32_SFLOAT,
14704 
14705     // From compatibleFormats48Bit
14706     VK_FORMAT_R16G16B16_UNORM,
14707     VK_FORMAT_R16G16B16_SFLOAT,
14708 
14709     // From compatibleFormats64Bit
14710     VK_FORMAT_R16G16B16A16_UNORM,
14711     VK_FORMAT_R64_SFLOAT,
14712 
14713     // From compatibleFormats96Bit
14714     VK_FORMAT_R32G32B32_UINT,
14715     VK_FORMAT_R32G32B32_SFLOAT,
14716 
14717     // From compatibleFormats128Bit
14718     VK_FORMAT_R32G32B32A32_UINT,
14719     VK_FORMAT_R64G64_SFLOAT,
14720 
14721     // From compatibleFormats192Bit
14722     VK_FORMAT_R64G64B64_UINT,
14723     VK_FORMAT_R64G64B64_SFLOAT,
14724 
14725     // From compatibleFormats256Bit
14726     VK_FORMAT_R64G64B64A64_UINT,
14727     VK_FORMAT_R64G64B64A64_SFLOAT,
14728 };
14729 
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)14730 std::string getBlitImageTilingLayoutCaseName(VkImageTiling tiling, VkImageLayout layout)
14731 {
14732     switch (tiling)
14733     {
14734     case VK_IMAGE_TILING_OPTIMAL:
14735         return getImageLayoutCaseName(layout);
14736     case VK_IMAGE_TILING_LINEAR:
14737         return "linear";
14738     default:
14739         DE_ASSERT(false);
14740         return "";
14741     }
14742 }
14743 
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)14744 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
14745 {
14746     tcu::TestContext &testCtx = group->getTestContext();
14747 
14748     FormatSet linearOtherImageFormatsToTestSet;
14749     const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
14750     for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter;
14751          ++otherImageFormatsIndex)
14752         linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
14753 
14754     const VkImageTiling blitSrcTilings[] = {
14755         VK_IMAGE_TILING_OPTIMAL,
14756         VK_IMAGE_TILING_LINEAR,
14757     };
14758     const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
14759     const VkImageTiling blitDstTilings[] = {
14760         VK_IMAGE_TILING_OPTIMAL,
14761         VK_IMAGE_TILING_LINEAR,
14762     };
14763     const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
14764 
14765     for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
14766     {
14767         testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
14768 
14769         for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
14770         {
14771             testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
14772 
14773             // 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
14774             if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR &&
14775                 testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14776                 continue;
14777 
14778             for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
14779             {
14780                 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
14781 
14782                 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
14783                 {
14784                     testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
14785 
14786                     // 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
14787                     if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR &&
14788                         testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
14789                         continue;
14790 
14791                     if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR &&
14792                          !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
14793                         (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR &&
14794                          !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
14795                         continue;
14796 
14797                     testParams.params.filter = VK_FILTER_NEAREST;
14798                     const std::string testName =
14799                         getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling,
14800                                                          testParams.params.src.image.operationLayout) +
14801                         "_" +
14802                         getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling,
14803                                                          testParams.params.dst.image.operationLayout);
14804                     group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", testParams.params));
14805 
14806                     if (testParams.testFilters & FILTER_MASK_LINEAR)
14807                     {
14808                         testParams.params.filter = VK_FILTER_LINEAR;
14809                         group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", testParams.params));
14810                     }
14811 
14812                     if (testParams.testFilters & FILTER_MASK_CUBIC)
14813                     {
14814                         testParams.params.filter = VK_FILTER_CUBIC_EXT;
14815                         group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", testParams.params));
14816                     }
14817 
14818                     if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) &&
14819                         !isCompressedFormat(testParams.params.src.image.format))
14820                     {
14821                         const struct
14822                         {
14823                             FillMode mode;
14824                             const char *name;
14825                         } modeList[] = {
14826                             {FILL_MODE_BLUE_RED_X, "x"},
14827                             {FILL_MODE_BLUE_RED_Y, "y"},
14828                             {FILL_MODE_BLUE_RED_Z, "z"},
14829                         };
14830 
14831                         auto otherParams                      = testParams;
14832                         otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
14833 
14834                         for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
14835                         {
14836                             otherParams.params.src.image.fillMode = modeList[i].mode;
14837 
14838                             otherParams.params.filter = VK_FILTER_LINEAR;
14839                             group->addChild(new BlitImageTestCase(
14840                                 testCtx, testName + "_linear_stripes_" + modeList[i].name, otherParams.params));
14841 
14842                             otherParams.params.filter = VK_FILTER_NEAREST;
14843                             group->addChild(new BlitImageTestCase(
14844                                 testCtx, testName + "_nearest_stripes_" + modeList[i].name, otherParams.params));
14845                         }
14846                     }
14847                 }
14848             }
14849         }
14850     }
14851 }
14852 
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)14853 void addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
14854 {
14855     VkFormat srcFormat = testParams.params.src.image.format;
14856 
14857     if (testParams.compatibleFormats)
14858     {
14859         for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED;
14860              ++dstFormatIndex)
14861         {
14862             testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
14863             if (!isSupportedByFramework(testParams.params.dst.image.format))
14864                 continue;
14865 
14866             if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
14867                 continue;
14868 
14869             addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format),
14870                          addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
14871         }
14872     }
14873 
14874     // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
14875     // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
14876     // as it is not on compatibleFormats list
14877     if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
14878     {
14879         testParams.params.dst.image.format = srcFormat;
14880 
14881         addTestGroup(group, getFormatCaseName(srcFormat), addBlittingImageAllFormatsColorSrcFormatDstFormatTests,
14882                      testParams);
14883     }
14884 }
14885 
14886 const VkFormat dedicatedAllocationBlittingFormatsToTest[] = {
14887     // compatibleFormatsUInts
14888     VK_FORMAT_R8_UINT,
14889     VK_FORMAT_R64G64B64A64_UINT,
14890 
14891     // compatibleFormatsSInts
14892     VK_FORMAT_R8_SINT,
14893     VK_FORMAT_R64G64B64A64_SINT,
14894 
14895     // compatibleFormatsFloats
14896     VK_FORMAT_R4G4_UNORM_PACK8,
14897     VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
14898 
14899     // compatibleFormatsSrgb
14900     VK_FORMAT_R8_SRGB,
14901     VK_FORMAT_A8B8G8R8_SRGB_PACK32,
14902 };
14903 
14904 // skip cubic filtering test for the following data formats
14905 const FormatSet onlyNearestAndLinearFormatsToTest = {VK_FORMAT_A8B8G8R8_USCALED_PACK32,
14906                                                      VK_FORMAT_A8B8G8R8_SSCALED_PACK32, VK_FORMAT_A8B8G8R8_UINT_PACK32,
14907                                                      VK_FORMAT_A8B8G8R8_SINT_PACK32};
14908 
14909 // astc formats have diferent block sizes and thus require diferent resolutions for images
14910 enum class AstcImageSizeType
14911 {
14912     SIZE_64_64 = 0,
14913     SIZE_60_64,
14914     SIZE_64_60,
14915     SIZE_60_60,
14916 };
14917 
14918 const std::map<VkFormat, AstcImageSizeType> astcSizes{
14919     {VK_FORMAT_ASTC_4x4_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64},
14920     {VK_FORMAT_ASTC_4x4_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64},
14921     {VK_FORMAT_ASTC_5x4_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64},
14922     {VK_FORMAT_ASTC_5x4_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64},
14923     {VK_FORMAT_ASTC_5x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14924     {VK_FORMAT_ASTC_5x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14925     {VK_FORMAT_ASTC_6x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14926     {VK_FORMAT_ASTC_6x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14927     {VK_FORMAT_ASTC_6x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14928     {VK_FORMAT_ASTC_6x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14929     {VK_FORMAT_ASTC_8x5_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60},
14930     {VK_FORMAT_ASTC_8x5_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60},
14931     {VK_FORMAT_ASTC_8x6_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60},
14932     {VK_FORMAT_ASTC_8x6_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60},
14933     {VK_FORMAT_ASTC_8x8_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64},
14934     {VK_FORMAT_ASTC_8x8_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64},
14935     {VK_FORMAT_ASTC_10x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14936     {VK_FORMAT_ASTC_10x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14937     {VK_FORMAT_ASTC_10x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14938     {VK_FORMAT_ASTC_10x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14939     {VK_FORMAT_ASTC_10x8_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64},
14940     {VK_FORMAT_ASTC_10x8_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64},
14941     {VK_FORMAT_ASTC_10x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14942     {VK_FORMAT_ASTC_10x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14943     {VK_FORMAT_ASTC_12x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14944     {VK_FORMAT_ASTC_12x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60},
14945     {VK_FORMAT_ASTC_12x12_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60},
14946     {VK_FORMAT_ASTC_12x12_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60}};
14947 
create2DCopyRegions(int32_t srcWidth,int32_t srcHeight,int32_t dstWidth,int32_t dstHeight)14948 std::vector<CopyRegion> create2DCopyRegions(int32_t srcWidth, int32_t srcHeight, int32_t dstWidth, int32_t dstHeight)
14949 {
14950     CopyRegion region;
14951     std::vector<CopyRegion> regionsVector;
14952 
14953     int32_t fourthOfSrcWidth  = srcWidth / 4;
14954     int32_t fourthOfSrcHeight = srcHeight / 4;
14955     int32_t fourthOfDstWidth  = dstWidth / 4;
14956     int32_t fourthOfDstHeight = dstHeight / 4;
14957 
14958     // to the top of resulting image copy whole source image but with increasingly smaller sizes
14959     for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
14960     {
14961         region.imageBlit = {
14962             defaultSourceLayer,                    // VkImageSubresourceLayers srcSubresource;
14963             {{0, 0, 0}, {srcWidth, srcHeight, 1}}, // VkOffset3D srcOffsets[2];
14964 
14965             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14966             {{i, 0, 0}, {i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}} // VkOffset3D dstOffset[2];
14967         };
14968         regionsVector.push_back(region);
14969     }
14970 
14971     // to the bottom of resulting image copy parts of source image;
14972     for (int i = 0; i < 4; ++i)
14973     {
14974         int srcX = i * fourthOfSrcWidth;
14975         int srcY = i * fourthOfSrcHeight;
14976         int dstX = i * fourthOfDstWidth;
14977 
14978         region.imageBlit = {
14979             defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
14980             {{srcX, srcY, 0}, {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}}, // VkOffset3D srcOffsets[2];
14981 
14982             defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
14983             {{dstX, 2 * fourthOfDstHeight, 0},
14984              {dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}} // VkOffset3D dstOffset[2];
14985         };
14986 
14987         regionsVector.push_back(region);
14988     }
14989 
14990     return regionsVector;
14991 }
14992 
addBufferToImageTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14993 void addBufferToImageTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
14994 {
14995     addTestGroup(group, "1d_images", add1dBufferToImageTests, testGroupParams);
14996     addTestGroup(group, "2d_images", add2dBufferToImageTests, testGroupParams);
14997 }
14998 
addImageToBufferTests(tcu::TestCaseGroup * group,TestGroupParamsPtr testGroupParams)14999 void addImageToBufferTests(tcu::TestCaseGroup *group, TestGroupParamsPtr testGroupParams)
15000 {
15001     addTestGroup(group, "1d_images", add1dImageToBufferTests, testGroupParams);
15002     addTestGroup(group, "2d_images", add2dImageToBufferTests, testGroupParams);
15003 }
15004 
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15005 void addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15006                                           uint32_t extensionFlags)
15007 {
15008     const struct
15009     {
15010         const VkFormat *sourceFormats;
15011         const VkFormat *destinationFormats;
15012         const bool onlyNearest;
15013     } colorImageFormatsToTestBlit[] = {
15014         {compatibleFormatsUInts, compatibleFormatsUInts, true},
15015         {compatibleFormatsSInts, compatibleFormatsSInts, true},
15016         {compatibleFormatsFloats, compatibleFormatsFloats, false},
15017         {compressedFormatsFloats, compatibleFormatsFloats, false},
15018         {compatibleFormatsSrgb, compatibleFormatsSrgb, false},
15019         {compressedFormatsSrgb, compatibleFormatsSrgb, false},
15020     };
15021 
15022     const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15023 
15024     if (allocationKind == ALLOCATION_KIND_DEDICATED)
15025     {
15026         const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15027         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15028              ++compatibleFormatsIndex)
15029             dedicatedAllocationBlittingFormatsToTestSet.insert(
15030                 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15031     }
15032 
15033     // 2D tests.
15034     {
15035         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d"));
15036 
15037         TestParams params;
15038         params.src.image.imageType = VK_IMAGE_TYPE_2D;
15039         params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15040         params.src.image.extent    = defaultExtent;
15041         params.dst.image.extent    = defaultExtent;
15042         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15043         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15044         params.allocationKind      = allocationKind;
15045         params.extensionFlags      = extensionFlags;
15046 
15047         // create all required copy regions
15048         const std::map<AstcImageSizeType, std::vector<CopyRegion>> imageRegions{
15049             {AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64, 64, 64)},
15050             {AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64, 60, 64)},
15051             {AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60, 64, 60)},
15052             {AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60, 60, 60)},
15053         };
15054 
15055         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15056              ++compatibleFormatsIndex)
15057         {
15058             const VkFormat *sourceFormats      = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15059             const VkFormat *destinationFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
15060             const bool onlyNearest             = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15061             for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15062             {
15063                 VkFormat srcFormat      = sourceFormats[srcFormatIndex];
15064                 params.src.image.format = srcFormat;
15065 
15066                 const bool onlyNearestAndLinear =
15067                     de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15068 
15069                 // most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
15070                 params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
15071                 if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
15072                     params.regions = imageRegions.at(astcSizes.at(srcFormat));
15073 
15074                 // use the fact that first region contains the size of full source image
15075                 // and make source and destination the same size - this is needed for astc formats
15076                 const VkOffset3D &srcImageSize = params.regions[0].imageBlit.srcOffsets[1];
15077                 VkExtent3D &srcImageExtent     = params.src.image.extent;
15078                 VkExtent3D &dstImageExtent     = params.dst.image.extent;
15079                 srcImageExtent.width           = srcImageSize.x;
15080                 srcImageExtent.height          = srcImageSize.y;
15081                 dstImageExtent.width           = srcImageSize.x;
15082                 dstImageExtent.height          = srcImageSize.y;
15083 
15084                 BlitColorTestParams testParams{params, destinationFormats,
15085                                                makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15086 
15087                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15088                              addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15089             }
15090         }
15091 
15092         group->addChild(subGroup.release());
15093     }
15094 
15095     // 1D tests.
15096     {
15097         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d"));
15098 
15099         TestParams params;
15100         params.src.image.imageType = VK_IMAGE_TYPE_1D;
15101         params.dst.image.imageType = VK_IMAGE_TYPE_1D;
15102         params.src.image.extent    = default1dExtent;
15103         params.dst.image.extent    = default1dExtent;
15104         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15105         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15106         params.allocationKind      = allocationKind;
15107         params.extensionFlags      = extensionFlags;
15108 
15109         CopyRegion region;
15110         for (int i = 0; i < defaultSize; i += defaultSize / 2)
15111         {
15112             const VkImageBlit imageBlit = {
15113                 defaultSourceLayer,               // VkImageSubresourceLayers srcSubresource;
15114                 {{0, 0, 0}, {defaultSize, 1, 1}}, // VkOffset3D srcOffsets[2];
15115 
15116                 defaultSourceLayer,                         // VkImageSubresourceLayers dstSubresource;
15117                 {{i, 0, 0}, {i + defaultQuarterSize, 1, 1}} // VkOffset3D dstOffset[2];
15118             };
15119             region.imageBlit = imageBlit;
15120             params.regions.push_back(region);
15121         }
15122 
15123         {
15124             const VkImageBlit imageBlit = {
15125                 defaultSourceLayer,                      // VkImageSubresourceLayers srcSubresource;
15126                 {{0, 0, 0}, {defaultQuarterSize, 1, 1}}, // VkOffset3D srcOffsets[2];
15127 
15128                 defaultSourceLayer,                                          // VkImageSubresourceLayers dstSubresource;
15129                 {{defaultQuarterSize, 0, 0}, {2 * defaultQuarterSize, 1, 1}} // VkOffset3D dstOffset[2];
15130             };
15131             region.imageBlit = imageBlit;
15132             params.regions.push_back(region);
15133         }
15134 
15135         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15136              ++compatibleFormatsIndex)
15137         {
15138             const VkFormat *sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15139             const bool onlyNearest        = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15140             for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15141             {
15142                 params.src.image.format = sourceFormats[srcFormatIndex];
15143                 if (!isSupportedByFramework(params.src.image.format))
15144                     continue;
15145 
15146                 // Cubic filtering can only be used with 2D images.
15147                 const bool onlyNearestAndLinear = true;
15148 
15149                 BlitColorTestParams testParams{params, nullptr, makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15150 
15151                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15152                              addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15153             }
15154         }
15155 
15156         group->addChild(subGroup.release());
15157     }
15158 
15159     // 3D tests. Note we use smaller dimensions here for performance reasons.
15160     {
15161         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d"));
15162 
15163         TestParams params;
15164         params.src.image.imageType = VK_IMAGE_TYPE_3D;
15165         params.dst.image.imageType = VK_IMAGE_TYPE_3D;
15166         params.src.image.extent    = default3dExtent;
15167         params.dst.image.extent    = default3dExtent;
15168         params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15169         params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15170         params.allocationKind      = allocationKind;
15171         params.extensionFlags      = extensionFlags;
15172 
15173         CopyRegion region;
15174         for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j);
15175              i += defaultSixteenthSize / j++)
15176         {
15177             const VkImageBlit imageBlit = {
15178                 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15179                 {{0, 0, 0}, {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}}, // VkOffset3D srcOffsets[2];
15180 
15181                 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15182                 {{i, 0, i},
15183                  {i + defaultSixteenthSize / j, defaultSixteenthSize / j,
15184                   i + defaultSixteenthSize / j}} // VkOffset3D dstOffset[2];
15185             };
15186             region.imageBlit = imageBlit;
15187             params.regions.push_back(region);
15188         }
15189         for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
15190         {
15191             const VkImageBlit imageBlit = {
15192                 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
15193                 {{i, i, i},
15194                  {i + defaultSixteenthSize, i + defaultSixteenthSize,
15195                   i + defaultSixteenthSize}}, // VkOffset3D srcOffsets[2];
15196 
15197                 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
15198                 {{i, defaultQuarterSize / 2, i},
15199                  {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize,
15200                   i + defaultSixteenthSize}} // VkOffset3D dstOffset[2];
15201             };
15202             region.imageBlit = imageBlit;
15203             params.regions.push_back(region);
15204         }
15205 
15206         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15207              ++compatibleFormatsIndex)
15208         {
15209             const VkFormat *sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
15210             const bool onlyNearest        = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15211             for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15212             {
15213                 params.src.image.format = sourceFormats[srcFormatIndex];
15214                 if (!isSupportedByFramework(params.src.image.format))
15215                     continue;
15216 
15217                 // Cubic filtering can only be used with 2D images.
15218                 const bool onlyNearestAndLinear = true;
15219 
15220                 BlitColorTestParams testParams{params, nullptr, makeFilterMask(onlyNearest, onlyNearestAndLinear)};
15221 
15222                 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format),
15223                              addBlittingImageAllFormatsColorSrcFormatTests, testParams);
15224             }
15225         }
15226 
15227         group->addChild(subGroup.release());
15228     }
15229 }
15230 
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)15231 void addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup *group, TestParams params)
15232 {
15233     const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15234     const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15235 
15236     for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
15237     {
15238         params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
15239 
15240         for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
15241         {
15242             params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
15243             params.filter                    = VK_FILTER_NEAREST;
15244 
15245             const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
15246                                          getImageLayoutCaseName(params.dst.image.operationLayout);
15247 
15248             group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", params));
15249         }
15250     }
15251 }
15252 
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15253 void addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15254                                                  uint32_t extensionFlags)
15255 {
15256     const VkFormat depthAndStencilFormats[] = {
15257         VK_FORMAT_D16_UNORM,         VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT,         VK_FORMAT_S8_UINT,
15258         VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,   VK_FORMAT_D32_SFLOAT_S8_UINT,
15259     };
15260 
15261     const VkImageSubresourceLayers defaultDepthSourceLayer   = {VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u};
15262     const VkImageSubresourceLayers defaultStencilSourceLayer = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u};
15263     const VkImageSubresourceLayers defaultDSSourceLayer = {VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u,
15264                                                            0u, 1u};
15265 
15266     // 2D tests
15267     {
15268         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d"));
15269 
15270         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15271              ++compatibleFormatsIndex)
15272         {
15273             TestParams params;
15274             params.src.image.imageType = VK_IMAGE_TYPE_2D;
15275             params.src.image.extent    = defaultExtent;
15276             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15277             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
15278             params.dst.image.extent    = defaultExtent;
15279             params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15280             params.dst.image.format    = params.src.image.format;
15281             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15282             params.allocationKind      = allocationKind;
15283             params.extensionFlags      = extensionFlags;
15284 
15285             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15286             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15287 
15288             CopyRegion region;
15289             for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j);
15290                  i += defaultQuarterSize / j++)
15291             {
15292                 const VkOffset3D srcOffset0 = {0, 0, 0};
15293                 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1};
15294                 const VkOffset3D dstOffset0 = {i, 0, 0};
15295                 const VkOffset3D dstOffset1 = {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
15296 
15297                 if (hasDepth)
15298                 {
15299                     const VkImageBlit imageBlit = {
15300                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15301                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15302                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15303                         {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15304                     };
15305                     region.imageBlit = imageBlit;
15306                     params.regions.push_back(region);
15307                 }
15308                 if (hasStencil)
15309                 {
15310                     const VkImageBlit imageBlit = {
15311                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15312                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15313                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15314                         {dstOffset0, dstOffset1},  // VkOffset3D dstOffset[2];
15315                     };
15316                     region.imageBlit = imageBlit;
15317                     params.regions.push_back(region);
15318                 }
15319             }
15320             for (int i = 0; i < defaultSize; i += defaultQuarterSize)
15321             {
15322                 const VkOffset3D srcOffset0 = {i, i, 0};
15323                 const VkOffset3D srcOffset1 = {i + defaultQuarterSize, i + defaultQuarterSize, 1};
15324                 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0};
15325                 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
15326 
15327                 if (hasDepth)
15328                 {
15329                     const VkImageBlit imageBlit = {
15330                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15331                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15332                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15333                         {dstOffset0, dstOffset1}  // VkOffset3D dstOffset[2];
15334                     };
15335                     region.imageBlit = imageBlit;
15336                     params.regions.push_back(region);
15337                 }
15338                 if (hasStencil)
15339                 {
15340                     const VkImageBlit imageBlit = {
15341                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15342                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15343                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15344                         {dstOffset0, dstOffset1}   // VkOffset3D dstOffset[2];
15345                     };
15346                     region.imageBlit = imageBlit;
15347                     params.regions.push_back(region);
15348                 }
15349                 if (hasDepth && hasStencil)
15350                 {
15351                     const VkOffset3D dstDSOffset0 = {i, 3 * defaultQuarterSize, 0};
15352                     const VkOffset3D dstDSOffset1 = {i + defaultQuarterSize, defaultSize, 1};
15353                     const VkImageBlit imageBlit   = {
15354                         defaultDSSourceLayer,        // VkImageSubresourceLayers srcSubresource;
15355                         {srcOffset0, srcOffset1},    // VkOffset3D srcOffsets[2];
15356                         defaultDSSourceLayer,        // VkImageSubresourceLayers dstSubresource;
15357                         {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15358                     };
15359                     region.imageBlit = imageBlit;
15360                     params.regions.push_back(region);
15361                 }
15362             }
15363 
15364             const std::string testName =
15365                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15366             addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15367 
15368             if (hasDepth && hasStencil)
15369             {
15370                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15371                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15372                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15373                 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15374             }
15375         }
15376 
15377         group->addChild(subGroup.release());
15378     }
15379 
15380     // 1D tests
15381     {
15382         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d"));
15383 
15384         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15385              ++compatibleFormatsIndex)
15386         {
15387             TestParams params;
15388             params.src.image.imageType = VK_IMAGE_TYPE_1D;
15389             params.dst.image.imageType = VK_IMAGE_TYPE_1D;
15390             params.src.image.extent    = default1dExtent;
15391             params.dst.image.extent    = default1dExtent;
15392             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
15393             params.dst.image.format    = params.src.image.format;
15394             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15395             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15396             params.allocationKind      = allocationKind;
15397             params.extensionFlags      = extensionFlags;
15398 
15399             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15400             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15401 
15402             CopyRegion region;
15403             for (int i = 0; i < defaultSize; i += defaultSize / 2)
15404             {
15405                 const VkOffset3D srcOffset0 = {0, 0, 0};
15406                 const VkOffset3D srcOffset1 = {defaultSize, 1, 1};
15407                 const VkOffset3D dstOffset0 = {i, 0, 0};
15408                 const VkOffset3D dstOffset1 = {i + defaultQuarterSize, 1, 1};
15409 
15410                 if (hasDepth)
15411                 {
15412                     const VkImageBlit imageBlit = {
15413                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15414                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15415                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15416                         {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15417                     };
15418                     region.imageBlit = imageBlit;
15419                     params.regions.push_back(region);
15420                 }
15421                 if (hasStencil)
15422                 {
15423                     const VkImageBlit imageBlit = {
15424                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15425                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15426                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15427                         {dstOffset0, dstOffset1},  // VkOffset3D dstOffset[2];
15428                     };
15429                     region.imageBlit = imageBlit;
15430                     params.regions.push_back(region);
15431                 }
15432             }
15433 
15434             {
15435                 const VkOffset3D srcOffset0 = {0, 0, 0};
15436                 const VkOffset3D srcOffset1 = {defaultQuarterSize, 1, 1};
15437                 const VkOffset3D dstOffset0 = {defaultQuarterSize, 0, 0};
15438                 const VkOffset3D dstOffset1 = {2 * defaultQuarterSize, 1, 1};
15439 
15440                 if (hasDepth)
15441                 {
15442                     const VkImageBlit imageBlit = {
15443                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15444                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15445                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15446                         {dstOffset0, dstOffset1}  // VkOffset3D dstOffset[2];
15447                     };
15448                     region.imageBlit = imageBlit;
15449                     params.regions.push_back(region);
15450                 }
15451                 if (hasStencil)
15452                 {
15453                     const VkImageBlit imageBlit = {
15454                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15455                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15456                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15457                         {dstOffset0, dstOffset1}   // VkOffset3D dstOffset[2];
15458                     };
15459                     region.imageBlit = imageBlit;
15460                     params.regions.push_back(region);
15461                 }
15462                 if (hasDepth && hasStencil)
15463                 {
15464                     const VkOffset3D dstDSOffset0 = {3 * defaultQuarterSize, 0, 0};
15465                     const VkOffset3D dstDSOffset1 = {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
15466                     const VkImageBlit imageBlit   = {
15467                         defaultDSSourceLayer,        // VkImageSubresourceLayers srcSubresource;
15468                         {srcOffset0, srcOffset1},    // VkOffset3D srcOffsets[2];
15469                         defaultDSSourceLayer,        // VkImageSubresourceLayers dstSubresource;
15470                         {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15471                     };
15472                     region.imageBlit = imageBlit;
15473                     params.regions.push_back(region);
15474                 }
15475             }
15476 
15477             const std::string testName =
15478                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15479             addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15480 
15481             if (hasDepth && hasStencil)
15482             {
15483                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15484                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15485                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15486                 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15487             }
15488         }
15489 
15490         group->addChild(subGroup.release());
15491     }
15492 
15493     // 3D tests. Note we use smaller dimensions here for performance reasons.
15494     {
15495         de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d"));
15496 
15497         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats);
15498              ++compatibleFormatsIndex)
15499         {
15500             TestParams params;
15501             params.src.image.imageType = VK_IMAGE_TYPE_3D;
15502             params.dst.image.imageType = VK_IMAGE_TYPE_3D;
15503             params.src.image.extent    = default3dExtent;
15504             params.dst.image.extent    = default3dExtent;
15505             params.src.image.format    = depthAndStencilFormats[compatibleFormatsIndex];
15506             params.dst.image.format    = params.src.image.format;
15507             params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15508             params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15509             params.allocationKind      = allocationKind;
15510             params.extensionFlags      = extensionFlags;
15511 
15512             bool hasDepth   = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
15513             bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
15514 
15515             CopyRegion region;
15516             for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j);
15517                  i += defaultSixteenthSize / j++)
15518             {
15519                 const VkOffset3D srcOffset0 = {0, 0, 0};
15520                 const VkOffset3D srcOffset1 = {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
15521                 const VkOffset3D dstOffset0 = {i, 0, i};
15522                 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize / j, defaultSixteenthSize / j,
15523                                                i + defaultSixteenthSize / j};
15524 
15525                 if (hasDepth)
15526                 {
15527                     const VkImageBlit imageBlit = {
15528                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15529                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15530                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15531                         {dstOffset0, dstOffset1}, // VkOffset3D dstOffset[2];
15532                     };
15533                     region.imageBlit = imageBlit;
15534                     params.regions.push_back(region);
15535                 }
15536                 if (hasStencil)
15537                 {
15538                     const VkImageBlit imageBlit = {
15539                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15540                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15541                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15542                         {dstOffset0, dstOffset1},  // VkOffset3D dstOffset[2];
15543                     };
15544                     region.imageBlit = imageBlit;
15545                     params.regions.push_back(region);
15546                 }
15547             }
15548             for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
15549             {
15550                 const VkOffset3D srcOffset0 = {i, i, i};
15551                 const VkOffset3D srcOffset1 = {i + defaultSixteenthSize, i + defaultSixteenthSize,
15552                                                i + defaultSixteenthSize};
15553                 const VkOffset3D dstOffset0 = {i, defaultQuarterSize / 2, i};
15554                 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize,
15555                                                i + defaultSixteenthSize};
15556 
15557                 if (hasDepth)
15558                 {
15559                     const VkImageBlit imageBlit = {
15560                         defaultDepthSourceLayer,  // VkImageSubresourceLayers srcSubresource;
15561                         {srcOffset0, srcOffset1}, // VkOffset3D srcOffsets[2];
15562                         defaultDepthSourceLayer,  // VkImageSubresourceLayers dstSubresource;
15563                         {dstOffset0, dstOffset1}  // VkOffset3D dstOffset[2];
15564                     };
15565                     region.imageBlit = imageBlit;
15566                     params.regions.push_back(region);
15567                 }
15568                 if (hasStencil)
15569                 {
15570                     const VkImageBlit imageBlit = {
15571                         defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
15572                         {srcOffset0, srcOffset1},  // VkOffset3D srcOffsets[2];
15573                         defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
15574                         {dstOffset0, dstOffset1}   // VkOffset3D dstOffset[2];
15575                     };
15576                     region.imageBlit = imageBlit;
15577                     params.regions.push_back(region);
15578                 }
15579                 if (hasDepth && hasStencil)
15580                 {
15581                     const VkOffset3D dstDSOffset0 = {i, 3 * defaultSixteenthSize, i};
15582                     const VkOffset3D dstDSOffset1 = {i + defaultSixteenthSize, defaultQuarterSize,
15583                                                      i + defaultSixteenthSize};
15584                     const VkImageBlit imageBlit   = {
15585                         defaultDSSourceLayer,        // VkImageSubresourceLayers srcSubresource;
15586                         {srcOffset0, srcOffset1},    // VkOffset3D srcOffsets[2];
15587                         defaultDSSourceLayer,        // VkImageSubresourceLayers dstSubresource;
15588                         {dstDSOffset0, dstDSOffset1} // VkOffset3D dstOffset[2];
15589                     };
15590                     region.imageBlit = imageBlit;
15591                     params.regions.push_back(region);
15592                 }
15593             }
15594 
15595             const std::string testName =
15596                 getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
15597             addTestGroup(subGroup.get(), testName, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15598 
15599             if (hasDepth && hasStencil)
15600             {
15601                 params.extensionFlags |= SEPARATE_DEPTH_STENCIL_LAYOUT;
15602                 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
15603                                               getFormatCaseName(params.dst.image.format) + "_separate_layouts";
15604                 addTestGroup(subGroup.get(), testName2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
15605             }
15606         }
15607 
15608         group->addChild(subGroup.release());
15609     }
15610 }
15611 
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)15612 void addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup *group, BlitColorTestParams testParams)
15613 {
15614     tcu::TestContext &testCtx = group->getTestContext();
15615 
15616     const VkImageLayout blitSrcLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15617     const VkImageLayout blitDstLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
15618 
15619     for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
15620     {
15621         testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
15622         for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
15623         {
15624             testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
15625 
15626             testParams.params.filter   = VK_FILTER_NEAREST;
15627             const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
15628                                          getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
15629             group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", testParams.params));
15630 
15631             if (testParams.testFilters & FILTER_MASK_LINEAR)
15632             {
15633                 testParams.params.filter = VK_FILTER_LINEAR;
15634                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", testParams.params));
15635             }
15636 
15637             if (testParams.testFilters & FILTER_MASK_CUBIC)
15638             {
15639                 testParams.params.filter = VK_FILTER_CUBIC_EXT;
15640                 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", testParams.params));
15641             }
15642         }
15643     }
15644 }
15645 
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15646 void addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15647                                                     uint32_t extensionFlags)
15648 {
15649     const struct
15650     {
15651         const VkFormat *const compatibleFormats;
15652         const bool onlyNearest;
15653     } colorImageFormatsToTestBlit[] = {
15654         {compatibleFormatsUInts, true},
15655         {compatibleFormatsSInts, true},
15656         {compatibleFormatsFloats, false},
15657         {compatibleFormatsSrgb, false},
15658     };
15659 
15660     const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15661 
15662     const int layerCountsToTest[] = {1, 6};
15663 
15664     TestParams params;
15665     params.src.image.imageType = VK_IMAGE_TYPE_2D;
15666     params.src.image.extent    = defaultExtent;
15667     params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15668     params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15669     params.dst.image.extent    = defaultExtent;
15670     params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15671     params.allocationKind      = allocationKind;
15672     params.extensionFlags      = extensionFlags;
15673     params.mipLevels           = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
15674     params.singleCommand       = true;
15675 
15676     CopyRegion region;
15677     for (uint32_t mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
15678     {
15679         VkImageSubresourceLayers destLayer = defaultSourceLayer;
15680         destLayer.mipLevel                 = mipLevelNdx;
15681 
15682         const VkImageBlit imageBlit = {
15683             defaultSourceLayer,                         // VkImageSubresourceLayers srcSubresource;
15684             {{0, 0, 0}, {defaultSize, defaultSize, 1}}, // VkOffset3D srcOffsets[2];
15685 
15686             destLayer, // VkImageSubresourceLayers dstSubresource;
15687             {{0, 0, 0}, {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}} // VkOffset3D dstOffset[2];
15688         };
15689         region.imageBlit = imageBlit;
15690         params.regions.push_back(region);
15691     }
15692 
15693     if (allocationKind == ALLOCATION_KIND_DEDICATED)
15694     {
15695         const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15696         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15697              ++compatibleFormatsIndex)
15698             dedicatedAllocationBlittingFormatsToTestSet.insert(
15699                 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15700     }
15701 
15702     for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
15703     {
15704         const int layerCount             = layerCountsToTest[layerCountIndex];
15705         const std::string layerGroupName = "layercount_" + de::toString(layerCount);
15706 
15707         de::MovePtr<tcu::TestCaseGroup> layerCountGroup(
15708             new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str()));
15709 
15710         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15711              ++compatibleFormatsIndex)
15712         {
15713             const VkFormat *compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
15714             const bool onlyNearest            = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15715 
15716             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15717             {
15718                 params.src.image.format = compatibleFormats[srcFormatIndex];
15719                 params.dst.image.format = compatibleFormats[srcFormatIndex];
15720 
15721                 if (!isSupportedByFramework(params.src.image.format))
15722                     continue;
15723 
15724                 const bool onlyNearestAndLinear =
15725                     de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15726 
15727                 BlitColorTestParams testParams;
15728                 testParams.params            = params;
15729                 testParams.compatibleFormats = compatibleFormats;
15730                 testParams.testFilters       = makeFilterMask(onlyNearest, onlyNearestAndLinear);
15731 
15732                 testParams.params.src.image.extent.depth = layerCount;
15733                 testParams.params.dst.image.extent.depth = layerCount;
15734 
15735                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15736                 {
15737                     testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15738                     testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15739                 }
15740 
15741                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format),
15742                              addBlittingImageAllFormatsMipmapFormatTests, testParams);
15743             }
15744         }
15745         group->addChild(layerCountGroup.release());
15746     }
15747 }
15748 
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15749 void addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15750                                                         uint32_t extensionFlags)
15751 {
15752     const struct
15753     {
15754         const VkFormat *const compatibleFormats;
15755         const bool onlyNearest;
15756     } colorImageFormatsToTestBlit[] = {
15757         {compatibleFormatsUInts, true},
15758         {compatibleFormatsSInts, true},
15759         {compatibleFormatsFloats, false},
15760         {compatibleFormatsSrgb, false},
15761     };
15762 
15763     const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
15764 
15765     const int layerCountsToTest[] = {1, 6};
15766 
15767     TestParams params;
15768     params.src.image.imageType = VK_IMAGE_TYPE_2D;
15769     params.src.image.extent    = defaultExtent;
15770     params.src.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15771     params.dst.image.imageType = VK_IMAGE_TYPE_2D;
15772     params.dst.image.extent    = defaultExtent;
15773     params.dst.image.tiling    = VK_IMAGE_TILING_OPTIMAL;
15774     params.allocationKind      = allocationKind;
15775     params.extensionFlags      = extensionFlags;
15776     params.mipLevels           = deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
15777     params.singleCommand       = false;
15778 
15779     CopyRegion region;
15780     for (uint32_t mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
15781     {
15782         VkImageSubresourceLayers srcLayer  = defaultSourceLayer;
15783         VkImageSubresourceLayers destLayer = defaultSourceLayer;
15784 
15785         srcLayer.mipLevel  = mipLevelNdx - 1u;
15786         destLayer.mipLevel = mipLevelNdx;
15787 
15788         const VkImageBlit imageBlit = {
15789             srcLayer, // VkImageSubresourceLayers srcSubresource;
15790             {{0, 0, 0},
15791              {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}}, // VkOffset3D srcOffsets[2];
15792 
15793             destLayer, // VkImageSubresourceLayers dstSubresource;
15794             {{0, 0, 0}, {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}} // VkOffset3D dstOffset[2];
15795         };
15796         region.imageBlit = imageBlit;
15797         params.regions.push_back(region);
15798     }
15799 
15800     if (allocationKind == ALLOCATION_KIND_DEDICATED)
15801     {
15802         const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
15803         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter;
15804              ++compatibleFormatsIndex)
15805             dedicatedAllocationBlittingFormatsToTestSet.insert(
15806                 dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
15807     }
15808 
15809     for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
15810     {
15811         const int layerCount             = layerCountsToTest[layerCountIndex];
15812         const std::string layerGroupName = "layercount_" + de::toString(layerCount);
15813 
15814         de::MovePtr<tcu::TestCaseGroup> layerCountGroup(
15815             new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str()));
15816 
15817         for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest;
15818              ++compatibleFormatsIndex)
15819         {
15820             const VkFormat *compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
15821             const bool onlyNearest            = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
15822 
15823             for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
15824             {
15825                 params.src.image.format = compatibleFormats[srcFormatIndex];
15826                 params.dst.image.format = compatibleFormats[srcFormatIndex];
15827 
15828                 if (!isSupportedByFramework(params.src.image.format))
15829                     continue;
15830 
15831                 const bool onlyNearestAndLinear =
15832                     de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
15833 
15834                 BlitColorTestParams testParams;
15835                 testParams.params            = params;
15836                 testParams.compatibleFormats = compatibleFormats;
15837                 testParams.testFilters       = makeFilterMask(onlyNearest, onlyNearestAndLinear);
15838 
15839                 testParams.params.src.image.extent.depth = layerCount;
15840                 testParams.params.dst.image.extent.depth = layerCount;
15841 
15842                 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15843                 {
15844                     testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15845                     testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15846                 }
15847 
15848                 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format),
15849                              addBlittingImageAllFormatsMipmapFormatTests, testParams);
15850             }
15851         }
15852         group->addChild(layerCountGroup.release());
15853     }
15854 
15855     for (int multiLayer = 0; multiLayer < 2; multiLayer++)
15856     {
15857         const int layerCount = multiLayer ? 6 : 1;
15858 
15859         for (int barrierCount = 1; barrierCount < 4; barrierCount++)
15860         {
15861             if (layerCount != 1 || barrierCount != 1)
15862             {
15863                 const std::string barrierGroupName =
15864                     (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
15865 
15866                 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(
15867                     new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str()));
15868 
15869                 params.barrierCount = barrierCount;
15870 
15871                 // Only go through a few common formats
15872                 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
15873                 {
15874                     params.src.image.format = compatibleFormatsUInts[srcFormatIndex];
15875                     params.dst.image.format = compatibleFormatsUInts[srcFormatIndex];
15876 
15877                     if (!isSupportedByFramework(params.src.image.format))
15878                         continue;
15879 
15880                     BlitColorTestParams testParams;
15881                     testParams.params            = params;
15882                     testParams.compatibleFormats = compatibleFormatsUInts;
15883                     testParams.testFilters       = FILTER_MASK_NEAREST;
15884 
15885                     testParams.params.src.image.extent.depth = layerCount;
15886                     testParams.params.dst.image.extent.depth = layerCount;
15887 
15888                     for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
15889                     {
15890                         testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
15891                         testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
15892                     }
15893 
15894                     addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format),
15895                                  addBlittingImageAllFormatsMipmapFormatTests, testParams);
15896                 }
15897                 group->addChild(barrierCountGroup.release());
15898             }
15899         }
15900     }
15901 }
15902 
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15903 void addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
15904                                            uint32_t extensionFlags)
15905 {
15906     addTestGroup(group, "from_base_level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind,
15907                  extensionFlags);
15908     addTestGroup(group, "from_previous_level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind,
15909                  extensionFlags);
15910 }
15911 
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15912 void addBlittingImageAllFormatsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15913 {
15914     addTestGroup(group, "color", addBlittingImageAllFormatsColorTests, allocationKind, extensionFlags);
15915     addTestGroup(group, "depth_stencil", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionFlags);
15916     addTestGroup(group, "generate_mipmaps", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionFlags);
15917 }
15918 
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15919 void addBlittingImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15920 {
15921     addTestGroup(group, "simple_tests", addBlittingImageSimpleTests, allocationKind, extensionFlags);
15922     addTestGroup(group, "all_formats", addBlittingImageAllFormatsTests, allocationKind, extensionFlags);
15923 }
15924 
15925 const VkSampleCountFlagBits samples[] = {VK_SAMPLE_COUNT_2_BIT,  VK_SAMPLE_COUNT_4_BIT,  VK_SAMPLE_COUNT_8_BIT,
15926                                          VK_SAMPLE_COUNT_16_BIT, VK_SAMPLE_COUNT_32_BIT, VK_SAMPLE_COUNT_64_BIT};
15927 const VkExtent3D resolveExtent        = {256u, 256u, 1};
15928 
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15929 void addResolveImageWholeTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15930 {
15931     TestParams params;
15932     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
15933     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
15934     params.src.image.extent          = resolveExtent;
15935     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
15936     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
15937     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
15938     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
15939     params.dst.image.extent          = resolveExtent;
15940     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
15941     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
15942     params.allocationKind            = allocationKind;
15943     params.extensionFlags            = extensionFlags;
15944 
15945     {
15946         const VkImageSubresourceLayers sourceLayer = {
15947             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
15948             0u,                        // uint32_t mipLevel;
15949             0u,                        // uint32_t baseArrayLayer;
15950             1u                         // uint32_t layerCount;
15951         };
15952         const VkImageResolve testResolve = {
15953             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
15954             {0, 0, 0},     // VkOffset3D srcOffset;
15955             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
15956             {0, 0, 0},     // VkOffset3D dstOffset;
15957             resolveExtent, // VkExtent3D extent;
15958         };
15959 
15960         CopyRegion imageResolve;
15961         imageResolve.imageResolve = testResolve;
15962         params.regions.push_back(imageResolve);
15963     }
15964 
15965     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
15966     {
15967         params.imageOffset = false;
15968         params.samples     = samples[samplesIndex];
15969         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
15970                                                         getSampleCountCaseName(samples[samplesIndex]), params));
15971         params.imageOffset = true;
15972         if (allocationKind != ALLOCATION_KIND_DEDICATED)
15973         {
15974             group->addChild(new ResolveImageToImageTestCase(
15975                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params));
15976         }
15977     }
15978 }
15979 
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)15980 void addResolveImagePartialTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
15981 {
15982     TestParams params;
15983     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
15984     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
15985     params.src.image.extent          = resolveExtent;
15986     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
15987     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
15988     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
15989     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
15990     params.dst.image.extent          = resolveExtent;
15991     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
15992     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
15993     params.allocationKind            = allocationKind;
15994     params.extensionFlags            = extensionFlags;
15995 
15996     {
15997         const VkImageSubresourceLayers sourceLayer = {
15998             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
15999             0u,                        // uint32_t mipLevel;
16000             0u,                        // uint32_t baseArrayLayer;
16001             1u                         // uint32_t layerCount;
16002         };
16003         const VkImageResolve testResolve = {
16004             sourceLayer,      // VkImageSubresourceLayers srcSubresource;
16005             {0, 0, 0},        // VkOffset3D srcOffset;
16006             sourceLayer,      // VkImageSubresourceLayers dstSubresource;
16007             {64u, 64u, 0},    // VkOffset3D dstOffset;
16008             {128u, 128u, 1u}, // VkExtent3D extent;
16009         };
16010 
16011         CopyRegion imageResolve;
16012         imageResolve.imageResolve = testResolve;
16013         params.regions.push_back(imageResolve);
16014     }
16015 
16016     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16017     {
16018         params.samples     = samples[samplesIndex];
16019         params.imageOffset = false;
16020         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16021                                                         getSampleCountCaseName(samples[samplesIndex]), params));
16022         params.imageOffset = true;
16023         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16024         {
16025             group->addChild(new ResolveImageToImageTestCase(
16026                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params));
16027         }
16028     }
16029 }
16030 
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16031 void addResolveImageWithRegionsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16032 {
16033     TestParams params;
16034     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16035     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16036     params.src.image.extent          = resolveExtent;
16037     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16038     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16039     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16040     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16041     params.dst.image.extent          = resolveExtent;
16042     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16043     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16044     params.allocationKind            = allocationKind;
16045     params.extensionFlags            = extensionFlags;
16046     params.imageOffset               = allocationKind != ALLOCATION_KIND_DEDICATED;
16047 
16048     {
16049         const VkImageSubresourceLayers sourceLayer = {
16050             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16051             0u,                        // uint32_t mipLevel;
16052             0u,                        // uint32_t baseArrayLayer;
16053             1u                         // uint32_t layerCount;
16054         };
16055 
16056         for (int i = 0; i < 256; i += 64)
16057         {
16058             const VkImageResolve testResolve = {
16059                 sourceLayer,    // VkImageSubresourceLayers srcSubresource;
16060                 {i, i, 0},      // VkOffset3D srcOffset;
16061                 sourceLayer,    // VkImageSubresourceLayers dstSubresource;
16062                 {i, 0, 0},      // VkOffset3D dstOffset;
16063                 {64u, 64u, 1u}, // VkExtent3D extent;
16064             };
16065 
16066             CopyRegion imageResolve;
16067             imageResolve.imageResolve = testResolve;
16068             params.regions.push_back(imageResolve);
16069         }
16070     }
16071 
16072     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16073     {
16074         params.samples = samples[samplesIndex];
16075         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16076                                                         getSampleCountCaseName(samples[samplesIndex]), params));
16077     }
16078 }
16079 
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16080 void addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16081                                                   uint32_t extensionFlags)
16082 {
16083     TestParams params;
16084     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16085     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16086     params.src.image.extent          = defaultExtent;
16087     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16088     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16089     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16090     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16091     params.dst.image.extent          = defaultExtent;
16092     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16093     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16094     params.allocationKind            = allocationKind;
16095     params.extensionFlags            = extensionFlags;
16096 
16097     {
16098         const VkImageSubresourceLayers sourceLayer = {
16099             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16100             0u,                        // uint32_t mipLevel;
16101             0u,                        // uint32_t baseArrayLayer;
16102             1u                         // uint32_t layerCount;
16103         };
16104 
16105         const VkImageResolve testResolve = {
16106             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16107             {0, 0, 0},     // VkOffset3D srcOffset;
16108             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16109             {0, 0, 0},     // VkOffset3D dstOffset;
16110             defaultExtent, // VkExtent3D extent;
16111         };
16112 
16113         CopyRegion imageResolve;
16114         imageResolve.imageResolve = testResolve;
16115         params.regions.push_back(imageResolve);
16116     }
16117 
16118     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16119     {
16120         params.samples     = samples[samplesIndex];
16121         params.imageOffset = false;
16122         group->addChild(new ResolveImageToImageTestCase(
16123             group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), params, COPY_MS_IMAGE_TO_MS_IMAGE));
16124         params.imageOffset = true;
16125         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16126         {
16127             group->addChild(new ResolveImageToImageTestCase(
16128                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16129                 COPY_MS_IMAGE_TO_MS_IMAGE));
16130         }
16131     }
16132 }
16133 
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16134 void addComputeAndTransferQueueTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16135 {
16136     de::MovePtr<tcu::TestCaseGroup> computeGroup(
16137         new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_compute"));
16138     de::MovePtr<tcu::TestCaseGroup> transferGroup(
16139         new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_transfer"));
16140 
16141     TestParams params;
16142     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16143     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16144     params.src.image.extent          = defaultExtent;
16145     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16146     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16147     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16148     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16149     params.dst.image.extent          = defaultExtent;
16150     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16151     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16152     params.allocationKind            = allocationKind;
16153     params.extensionFlags            = extensionFlags;
16154 
16155     {
16156         const VkImageSubresourceLayers sourceLayer = {
16157             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16158             0u,                        // uint32_t mipLevel;
16159             0u,                        // uint32_t baseArrayLayer;
16160             1u                         // uint32_t layerCount;
16161         };
16162 
16163         const VkImageResolve testResolve = {
16164             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16165             {0, 0, 0},     // VkOffset3D srcOffset;
16166             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16167             {0, 0, 0},     // VkOffset3D dstOffset;
16168             defaultExtent, // VkExtent3D extent;
16169         };
16170 
16171         CopyRegion imageResolve;
16172         imageResolve.imageResolve = testResolve;
16173         params.regions.push_back(imageResolve);
16174     }
16175 
16176     for (const auto &sample : samples)
16177     {
16178         params.samples = sample;
16179 
16180         params.queueSelection = QueueSelectionOptions::ComputeOnly;
16181         computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample),
16182                                                                params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
16183 
16184         params.queueSelection = QueueSelectionOptions::TransferOnly;
16185         transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample),
16186                                                                 params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
16187     }
16188 
16189     group->addChild(computeGroup.release());
16190     group->addChild(transferGroup.release());
16191 }
16192 
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16193 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16194                                                             uint32_t extensionFlags)
16195 {
16196     TestParams params;
16197     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16198     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16199     params.src.image.extent          = defaultExtent;
16200     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16201     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16202     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16203     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16204     params.dst.image.extent          = defaultExtent;
16205     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16206     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16207     params.allocationKind            = allocationKind;
16208     params.extensionFlags            = extensionFlags;
16209 
16210     {
16211         const VkImageSubresourceLayers sourceLayer = {
16212             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16213             0u,                        // uint32_t mipLevel;
16214             0u,                        // uint32_t baseArrayLayer;
16215             1u                         // uint32_t layerCount;
16216         };
16217 
16218         const VkImageResolve testResolve = {
16219             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16220             {0, 0, 0},     // VkOffset3D srcOffset;
16221             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16222             {0, 0, 0},     // VkOffset3D dstOffset;
16223             defaultExtent, // VkExtent3D extent;
16224         };
16225 
16226         CopyRegion imageResolve;
16227         imageResolve.imageResolve = testResolve;
16228         params.regions.push_back(imageResolve);
16229     }
16230 
16231     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16232     {
16233         params.samples     = samples[samplesIndex];
16234         params.imageOffset = false;
16235         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16236                                                         getSampleCountCaseName(samples[samplesIndex]), params,
16237                                                         COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
16238         params.imageOffset = true;
16239         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16240         {
16241             group->addChild(new ResolveImageToImageTestCase(
16242                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16243                 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
16244         }
16245     }
16246 }
16247 
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16248 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16249                                                              uint32_t extensionFlags)
16250 {
16251     TestParams params;
16252     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16253     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16254     params.src.image.extent          = defaultExtent;
16255     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16256     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16257     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16258     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16259     params.dst.image.extent          = defaultExtent;
16260     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16261     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16262     params.allocationKind            = allocationKind;
16263     params.extensionFlags            = extensionFlags;
16264 
16265     {
16266         const VkImageSubresourceLayers sourceLayer = {
16267             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16268             0u,                        // uint32_t mipLevel;
16269             0u,                        // uint32_t baseArrayLayer;
16270             1u                         // uint32_t layerCount;
16271         };
16272 
16273         const VkImageResolve testResolve = {
16274             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16275             {0, 0, 0},     // VkOffset3D srcOffset;
16276             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16277             {0, 0, 0},     // VkOffset3D dstOffset;
16278             defaultExtent, // VkExtent3D extent;
16279         };
16280 
16281         CopyRegion imageResolve;
16282         imageResolve.imageResolve = testResolve;
16283         params.regions.push_back(imageResolve);
16284     }
16285 
16286     const struct
16287     {
16288         VkImageLayout layout;
16289         std::string name;
16290     } imageLayouts[] = {{VK_IMAGE_LAYOUT_GENERAL, "general"},
16291                         {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal"},
16292                         {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal"}};
16293 
16294     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16295         for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
16296             for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
16297             {
16298                 params.src.image.operationLayout = imageLayouts[srcLayoutIndex].layout;
16299                 params.dst.image.operationLayout = imageLayouts[dstLayoutIndex].layout;
16300                 if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
16301                     params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
16302                     continue;
16303                 params.samples       = samples[samplesIndex];
16304                 std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" +
16305                                        imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
16306                 params.imageOffset = false;
16307                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, params,
16308                                                                 COPY_MS_IMAGE_TO_MS_IMAGE));
16309                 params.imageOffset = true;
16310                 if (allocationKind != ALLOCATION_KIND_DEDICATED)
16311                 {
16312                     group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset",
16313                                                                     params, COPY_MS_IMAGE_TO_MS_IMAGE));
16314                 }
16315             }
16316 }
16317 
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16318 void addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16319                                                   uint32_t extensionFlags)
16320 {
16321     TestParams params;
16322     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16323     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16324     params.src.image.extent          = defaultExtent;
16325     params.src.image.extent.depth    = 5u;
16326     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16327     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16328     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16329     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16330     params.dst.image.extent          = defaultExtent;
16331     params.dst.image.extent.depth    = 5u;
16332     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16333     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16334     params.allocationKind            = allocationKind;
16335     params.extensionFlags            = extensionFlags;
16336 
16337     for (uint32_t layerNdx = 0; layerNdx < params.src.image.extent.depth; ++layerNdx)
16338     {
16339         const VkImageSubresourceLayers sourceLayer = {
16340             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16341             0u,                        // uint32_t mipLevel;
16342             layerNdx,                  // uint32_t baseArrayLayer;
16343             1u                         // uint32_t layerCount;
16344         };
16345 
16346         const VkImageResolve testResolve = {
16347             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16348             {0, 0, 0},     // VkOffset3D srcOffset;
16349             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16350             {0, 0, 0},     // VkOffset3D dstOffset;
16351             defaultExtent, // VkExtent3D extent;
16352         };
16353 
16354         CopyRegion imageResolve;
16355         imageResolve.imageResolve = testResolve;
16356         params.regions.push_back(imageResolve);
16357     }
16358 
16359     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16360     {
16361         params.samples     = samples[samplesIndex];
16362         params.imageOffset = false;
16363         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16364                                                         getSampleCountCaseName(samples[samplesIndex]), params,
16365                                                         COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
16366         params.imageOffset = true;
16367         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16368         {
16369             group->addChild(new ResolveImageToImageTestCase(
16370                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16371                 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
16372         }
16373     }
16374 }
16375 
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16376 void addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16377                                          uint32_t extensionFlags)
16378 {
16379     TestParams params;
16380     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16381     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16382     params.src.image.extent          = resolveExtent;
16383     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16384     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16385     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16386     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16387     params.dst.image.extent          = resolveExtent;
16388     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16389     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16390     params.allocationKind            = allocationKind;
16391     params.extensionFlags            = extensionFlags;
16392 
16393     int32_t imageHalfWidth     = getExtent3D(params.src.image).width / 2;
16394     int32_t imageHalfHeight    = getExtent3D(params.src.image).height / 2;
16395     VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
16396 
16397     // Lower right corner to lower left corner.
16398     {
16399         const VkImageSubresourceLayers sourceLayer = {
16400             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16401             0u,                        // uint32_t mipLevel;
16402             0u,                        // uint32_t baseArrayLayer;
16403             1u                         // uint32_t layerCount;
16404         };
16405 
16406         const VkImageResolve testResolve = {
16407             sourceLayer,                          // VkImageSubresourceLayers srcSubresource;
16408             {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
16409             sourceLayer,                          // VkImageSubresourceLayers dstSubresource;
16410             {0, imageHalfHeight, 0},              // VkOffset3D dstOffset;
16411             halfImageExtent,                      // VkExtent3D extent;
16412         };
16413 
16414         CopyRegion imageResolve;
16415         imageResolve.imageResolve = testResolve;
16416         params.regions.push_back(imageResolve);
16417     }
16418 
16419     // Upper right corner to lower right corner.
16420     {
16421         const VkImageSubresourceLayers sourceLayer = {
16422             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16423             0u,                        // uint32_t mipLevel;
16424             0u,                        // uint32_t baseArrayLayer;
16425             1u                         // uint32_t layerCount;
16426         };
16427 
16428         const VkImageResolve testResolve = {
16429             sourceLayer,                          // VkImageSubresourceLayers srcSubresource;
16430             {imageHalfWidth, 0, 0},               // VkOffset3D srcOffset;
16431             sourceLayer,                          // VkImageSubresourceLayers dstSubresource;
16432             {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
16433             halfImageExtent,                      // VkExtent3D extent;
16434         };
16435 
16436         CopyRegion imageResolve;
16437         imageResolve.imageResolve = testResolve;
16438         params.regions.push_back(imageResolve);
16439     }
16440 
16441     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16442     {
16443         params.samples     = samples[samplesIndex];
16444         params.imageOffset = false;
16445         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16446                                                         getSampleCountCaseName(samples[samplesIndex]), params,
16447                                                         COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
16448         params.imageOffset = true;
16449         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16450         {
16451             group->addChild(new ResolveImageToImageTestCase(
16452                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16453                 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
16454         }
16455     }
16456 }
16457 
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16458 void addResolveImageWholeArrayImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16459                                          uint32_t extensionFlags)
16460 {
16461     TestParams params;
16462     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16463     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16464     params.src.image.extent          = defaultExtent;
16465     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16466     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16467     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16468     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16469     params.dst.image.extent          = defaultExtent;
16470     params.dst.image.extent.depth    = 5u;
16471     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16472     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16473     params.allocationKind            = allocationKind;
16474     params.extensionFlags            = extensionFlags;
16475 
16476     for (uint32_t layerNdx = 0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
16477     {
16478         const VkImageSubresourceLayers sourceLayer = {
16479             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16480             0u,                        // uint32_t mipLevel;
16481             layerNdx,                  // uint32_t baseArrayLayer;
16482             1u                         // uint32_t layerCount;
16483         };
16484 
16485         const VkImageResolve testResolve = {
16486             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16487             {0, 0, 0},     // VkOffset3D srcOffset;
16488             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16489             {0, 0, 0},     // VkOffset3D dstOffset;
16490             defaultExtent, // VkExtent3D extent;
16491         };
16492 
16493         CopyRegion imageResolve;
16494         imageResolve.imageResolve = testResolve;
16495         params.regions.push_back(imageResolve);
16496     }
16497 
16498     for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16499     {
16500         params.samples     = samples[samplesIndex];
16501         params.imageOffset = false;
16502         group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16503                                                         getSampleCountCaseName(samples[samplesIndex]), params,
16504                                                         COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16505         params.imageOffset = true;
16506         if (allocationKind != ALLOCATION_KIND_DEDICATED)
16507         {
16508             group->addChild(new ResolveImageToImageTestCase(
16509                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16510                 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16511         }
16512     }
16513 }
16514 
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16515 void addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16516                                                      uint32_t extensionFlags)
16517 {
16518     {
16519         TestParams params;
16520         const uint32_t layerCount        = 5u;
16521         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16522         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16523         params.src.image.extent          = defaultExtent;
16524         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16525         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16526         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16527         params.dst.image.extent          = defaultExtent;
16528         params.dst.image.extent.depth    = layerCount;
16529         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16530         params.allocationKind            = allocationKind;
16531         params.extensionFlags            = extensionFlags;
16532 
16533         const VkImageSubresourceLayers sourceLayer = {
16534             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16535             0u,                        // uint32_t mipLevel;
16536             0,                         // uint32_t baseArrayLayer;
16537             layerCount                 // uint32_t layerCount;
16538         };
16539 
16540         const VkImageResolve testResolve = {
16541             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16542             {0, 0, 0},     // VkOffset3D srcOffset;
16543             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16544             {0, 0, 0},     // VkOffset3D dstOffset;
16545             defaultExtent, // VkExtent3D extent;
16546         };
16547 
16548         CopyRegion imageResolve;
16549         imageResolve.imageResolve = testResolve;
16550         params.regions.push_back(imageResolve);
16551 
16552         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16553         {
16554             params.samples     = samples[samplesIndex];
16555             params.imageOffset = false;
16556             group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16557                                                             getSampleCountCaseName(samples[samplesIndex]), params,
16558                                                             COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16559             params.imageOffset = true;
16560             if (allocationKind != ALLOCATION_KIND_DEDICATED)
16561             {
16562                 group->addChild(new ResolveImageToImageTestCase(
16563                     group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", params,
16564                     COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16565             }
16566         }
16567     }
16568 
16569     {
16570         TestParams params;
16571         const uint32_t baseLayer         = 0u;
16572         const uint32_t layerCount        = 5u;
16573         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16574         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16575         params.src.image.extent          = defaultExtent;
16576         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16577         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16578         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16579         params.dst.image.extent          = defaultExtent;
16580         params.dst.image.extent.depth    = layerCount;
16581         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16582         params.allocationKind            = allocationKind;
16583         params.extensionFlags            = extensionFlags;
16584         params.extensionFlags |= MAINTENANCE_5;
16585 
16586         const VkImageSubresourceLayers sourceLayer = {
16587             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16588             0u,                        // uint32_t mipLevel;
16589             baseLayer,                 // uint32_t baseArrayLayer;
16590             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
16591         };
16592 
16593         const VkImageResolve testResolve = {
16594             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16595             {0, 0, 0},     // VkOffset3D srcOffset;
16596             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16597             {0, 0, 0},     // VkOffset3D dstOffset;
16598             defaultExtent, // VkExtent3D extent;
16599         };
16600 
16601         CopyRegion imageResolve;
16602         imageResolve.imageResolve = testResolve;
16603         params.regions.push_back(imageResolve);
16604 
16605         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16606         {
16607             params.samples     = samples[samplesIndex];
16608             params.imageOffset = false;
16609             group->addChild(new ResolveImageToImageTestCase(
16610                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_all_remaining_layers",
16611                 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16612             params.imageOffset = true;
16613             if (allocationKind != ALLOCATION_KIND_DEDICATED)
16614             {
16615                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16616                                                                 getSampleCountCaseName(samples[samplesIndex]) +
16617                                                                     "_all_remaining_layers_bind_offset",
16618                                                                 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16619             }
16620         }
16621     }
16622 
16623     {
16624         TestParams params;
16625         const uint32_t baseLayer         = 2u;
16626         const uint32_t layerCount        = 5u;
16627         params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16628         params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16629         params.src.image.extent          = defaultExtent;
16630         params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16631         params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16632         params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16633         params.dst.image.extent          = defaultExtent;
16634         params.dst.image.extent.depth    = layerCount;
16635         params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16636         params.allocationKind            = allocationKind;
16637         params.extensionFlags            = extensionFlags;
16638         params.extensionFlags |= MAINTENANCE_5;
16639 
16640         const VkImageSubresourceLayers sourceLayer = {
16641             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16642             0u,                        // uint32_t mipLevel;
16643             baseLayer,                 // uint32_t baseArrayLayer;
16644             VK_REMAINING_ARRAY_LAYERS  // uint32_t layerCount;
16645         };
16646 
16647         const VkImageResolve testResolve = {
16648             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16649             {0, 0, 0},     // VkOffset3D srcOffset;
16650             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16651             {0, 0, 0},     // VkOffset3D dstOffset;
16652             defaultExtent, // VkExtent3D extent;
16653         };
16654 
16655         CopyRegion imageResolve;
16656         imageResolve.imageResolve = testResolve;
16657         params.regions.push_back(imageResolve);
16658 
16659         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16660         {
16661             params.samples     = samples[samplesIndex];
16662             params.imageOffset = false;
16663             group->addChild(new ResolveImageToImageTestCase(
16664                 group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_not_all_remaining_layers",
16665                 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16666             params.imageOffset = true;
16667             if (allocationKind != ALLOCATION_KIND_DEDICATED)
16668             {
16669                 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(),
16670                                                                 getSampleCountCaseName(samples[samplesIndex]) +
16671                                                                     "_not_all_remaining_layers_bind_offset",
16672                                                                 params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
16673             }
16674         }
16675     }
16676 }
16677 
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16678 void addResolveImageDiffImageSizeTests(tcu::TestCaseGroup *group, AllocationKind allocationKind,
16679                                        uint32_t extensionFlags)
16680 {
16681     tcu::TestContext &testCtx = group->getTestContext();
16682     TestParams params;
16683     params.src.image.imageType       = VK_IMAGE_TYPE_2D;
16684     params.src.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16685     params.src.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16686     params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
16687     params.dst.image.imageType       = VK_IMAGE_TYPE_2D;
16688     params.dst.image.format          = VK_FORMAT_R8G8B8A8_UNORM;
16689     params.dst.image.tiling          = VK_IMAGE_TILING_OPTIMAL;
16690     params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
16691     params.allocationKind            = allocationKind;
16692     params.extensionFlags            = extensionFlags;
16693 
16694     {
16695         const VkImageSubresourceLayers sourceLayer = {
16696             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
16697             0u,                        // uint32_t mipLevel;
16698             0u,                        // uint32_t baseArrayLayer;
16699             1u                         // uint32_t layerCount;
16700         };
16701         const VkImageResolve testResolve = {
16702             sourceLayer,   // VkImageSubresourceLayers srcSubresource;
16703             {0, 0, 0},     // VkOffset3D srcOffset;
16704             sourceLayer,   // VkImageSubresourceLayers dstSubresource;
16705             {0, 0, 0},     // VkOffset3D dstOffset;
16706             resolveExtent, // VkExtent3D extent;
16707         };
16708         CopyRegion imageResolve;
16709         imageResolve.imageResolve = testResolve;
16710         params.regions.push_back(imageResolve);
16711     }
16712 
16713     const VkExtent3D imageExtents[] = {{resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth},
16714                                        {resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth},
16715                                        {resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10}};
16716 
16717     for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
16718     {
16719         const VkExtent3D &srcImageSize = imageExtents[srcImageExtentIndex];
16720         params.src.image.extent        = srcImageSize;
16721         params.dst.image.extent        = resolveExtent;
16722         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16723         {
16724             params.samples = samples[samplesIndex];
16725             std::ostringstream testName;
16726             testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_"
16727                      << getSampleCountCaseName(samples[samplesIndex]);
16728             std::ostringstream description;
16729             group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), params));
16730         }
16731     }
16732     for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
16733     {
16734         const VkExtent3D &dstImageSize = imageExtents[dstImageExtentIndex];
16735         params.src.image.extent        = resolveExtent;
16736         params.dst.image.extent        = dstImageSize;
16737         for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
16738         {
16739             params.samples = samples[samplesIndex];
16740             std::ostringstream testName;
16741             testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_"
16742                      << getSampleCountCaseName(samples[samplesIndex]);
16743             std::ostringstream description;
16744             params.imageOffset = false;
16745             group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), params));
16746             params.imageOffset = true;
16747             if (allocationKind != ALLOCATION_KIND_DEDICATED)
16748             {
16749                 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", params));
16750             }
16751         }
16752     }
16753 }
16754 
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)16755 void addDepthStencilCopyMSAATest(tcu::TestCaseGroup *group, DepthStencilMSAA::TestParameters testCreateParams)
16756 {
16757     // Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
16758     const struct
16759     {
16760         const std::string name;
16761         const VkFormat vkFormat;
16762     } depthAndStencilFormats[] = {
16763         {"d32_sfloat", VK_FORMAT_D32_SFLOAT},
16764         {"s8_uint", VK_FORMAT_S8_UINT},
16765         {"d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT},
16766         {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
16767     };
16768 
16769     // Both image layouts will be tested only with full image copy tests to limit the number of tests.
16770     const VkImageLayout srcImageLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
16771     const VkImageLayout dstImageLayouts[] = {VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL};
16772 
16773     for (const auto &srcLayout : srcImageLayouts)
16774     {
16775         for (const auto &dstLayout : dstImageLayouts)
16776         {
16777             testCreateParams.srcImageLayout = srcLayout;
16778             testCreateParams.dstImageLayout = dstLayout;
16779             for (const auto &format : depthAndStencilFormats)
16780             {
16781                 testCreateParams.imageFormat = format.vkFormat;
16782                 const auto textureFormat     = mapVkFormat(format.vkFormat);
16783                 bool hasDepth                = tcu::hasDepthComponent(textureFormat.order);
16784                 bool hasStencil              = tcu::hasStencilComponent(textureFormat.order);
16785                 std::string testNameBase =
16786                     format.name + "_" +
16787                     (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ?
16788                          getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_" :
16789                          "");
16790 
16791                 if (hasDepth)
16792                 {
16793                     testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
16794                     for (auto sample : samples)
16795                     {
16796                         testCreateParams.samples     = sample;
16797                         testCreateParams.imageOffset = false;
16798                         group->addChild(new DepthStencilMSAATestCase(
16799                             group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample),
16800                             testCreateParams));
16801                         testCreateParams.imageOffset = true;
16802                         if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED)
16803                         {
16804                             group->addChild(new DepthStencilMSAATestCase(
16805                                 group->getTestContext(),
16806                                 testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset",
16807                                 testCreateParams));
16808                         }
16809                     }
16810                 }
16811 
16812                 if (hasStencil)
16813                 {
16814                     testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
16815                     for (auto sample : samples)
16816                     {
16817                         testCreateParams.samples     = sample;
16818                         testCreateParams.imageOffset = false;
16819                         group->addChild(new DepthStencilMSAATestCase(
16820                             group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample),
16821                             testCreateParams));
16822                         testCreateParams.imageOffset = true;
16823                         if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED)
16824                         {
16825                             group->addChild(new DepthStencilMSAATestCase(
16826                                 group->getTestContext(),
16827                                 testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset",
16828                                 testCreateParams));
16829                         }
16830                     }
16831                 }
16832             }
16833             if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
16834                 break;
16835         }
16836         if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
16837             break;
16838     }
16839 }
16840 
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16841 void addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16842 {
16843     // Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
16844     DepthStencilMSAA::TestParameters testParams = {};
16845     testParams.allocationKind                   = allocationKind;
16846     testParams.extensionFlags                   = extensionFlags;
16847 
16848     testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
16849     addTestGroup(group, "whole", addDepthStencilCopyMSAATest, testParams);
16850 
16851     testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
16852     addTestGroup(group, "partial", addDepthStencilCopyMSAATest, testParams);
16853 
16854     testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
16855     addTestGroup(group, "array_to_array", addDepthStencilCopyMSAATest, testParams);
16856 }
16857 
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)16858 void addBufferCopyOffsetTests(tcu::TestCaseGroup *group)
16859 {
16860     de::MovePtr<tcu::TestCaseGroup> subGroup(
16861         new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset"));
16862 
16863     for (uint32_t srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
16864         for (uint32_t dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
16865         {
16866             BufferOffsetParams params{srcOffset, dstOffset};
16867             addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), bufferOffsetTest,
16868                             params);
16869         }
16870 
16871     group->addChild(subGroup.release());
16872 }
16873 
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16874 void addResolveImageTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16875 {
16876     addTestGroup(group, "whole", addResolveImageWholeTests, allocationKind, extensionFlags);
16877     addTestGroup(group, "partial", addResolveImagePartialTests, allocationKind, extensionFlags);
16878     addTestGroup(group, "with_regions", addResolveImageWithRegionsTests, allocationKind, extensionFlags);
16879     addTestGroup(group, "whole_copy_before_resolving", addResolveImageWholeCopyBeforeResolvingTests, allocationKind,
16880                  extensionFlags);
16881     addTestGroup(group, "whole_copy_before_resolving_no_cab", addResolveImageWholeCopyWithoutCabBeforeResolvingTests,
16882                  allocationKind, extensionFlags);
16883     addComputeAndTransferQueueTests(group, allocationKind, extensionFlags);
16884     addTestGroup(group, "diff_layout_copy_before_resolving", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests,
16885                  allocationKind, extensionFlags);
16886     addTestGroup(group, "layer_copy_before_resolving", addResolveImageLayerCopyBeforeResolvingTests, allocationKind,
16887                  extensionFlags);
16888     addTestGroup(group, "copy_with_regions_before_resolving", addResolveCopyImageWithRegionsTests, allocationKind,
16889                  extensionFlags);
16890     addTestGroup(group, "whole_array_image", addResolveImageWholeArrayImageTests, allocationKind, extensionFlags);
16891     addTestGroup(group, "whole_array_image_one_region", addResolveImageWholeArrayImageSingleRegionTests, allocationKind,
16892                  extensionFlags);
16893     addTestGroup(group, "diff_image_size", addResolveImageDiffImageSizeTests, allocationKind, extensionFlags);
16894 }
16895 
addSparseCopyTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16896 void addSparseCopyTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16897 {
16898     DE_ASSERT((extensionFlags & COPY_COMMANDS_2) && (extensionFlags & SPARSE_BINDING));
16899 
16900     {
16901         TestGroupParamsPtr universalGroupParams(new TestGroupParams{
16902             allocationKind,
16903             extensionFlags,
16904             QueueSelectionOptions::Universal,
16905             false,
16906             true,
16907         });
16908         addTestGroup(group, "image_to_image", addImageToImageTests, universalGroupParams);
16909     }
16910 }
16911 
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,uint32_t extensionFlags)16912 void addCopiesAndBlittingTests(tcu::TestCaseGroup *group, AllocationKind allocationKind, uint32_t extensionFlags)
16913 {
16914     TestGroupParamsPtr universalGroupParams(new TestGroupParams{
16915         allocationKind,
16916         extensionFlags,
16917         QueueSelectionOptions::Universal,
16918         false,
16919         false,
16920     });
16921 
16922     addTestGroup(group, "image_to_image", addImageToImageTests, universalGroupParams);
16923     addTestGroup(group, "image_to_buffer", addImageToBufferTests, universalGroupParams);
16924     addTestGroup(group, "buffer_to_image", addBufferToImageTests, universalGroupParams);
16925     addTestGroup(group, "buffer_to_depthstencil", addBufferToDepthStencilTests, allocationKind, extensionFlags);
16926     addTestGroup(group, "buffer_to_buffer", addBufferToBufferTests, universalGroupParams);
16927     addTestGroup(group, "blit_image", addBlittingImageTests, allocationKind, extensionFlags);
16928     addTestGroup(group, "resolve_image", addResolveImageTests, allocationKind, extensionFlags);
16929     addTestGroup(group, "depth_stencil_msaa_copy", addDepthStencilCopyMSAATestGroup, allocationKind, extensionFlags);
16930 
16931     if (extensionFlags == COPY_COMMANDS_2)
16932     {
16933         TestGroupParamsPtr transferOnlyGroup(new TestGroupParams{
16934             allocationKind,
16935             extensionFlags,
16936             QueueSelectionOptions::TransferOnly,
16937             false,
16938             false,
16939         });
16940         addTestGroup(group, "image_to_image_transfer_queue", addImageToImageTests, transferOnlyGroup);
16941         addTestGroup(group, "image_to_buffer_transfer_queue", addImageToBufferTests, transferOnlyGroup);
16942         addTestGroup(group, "buffer_to_image_transfer_queue", addBufferToImageTests, transferOnlyGroup);
16943         addTestGroup(group, "buffer_to_buffer_transfer_queue", addBufferToBufferTests, transferOnlyGroup);
16944 
16945         TestGroupParamsPtr transferWithSecondaryBuffer(new TestGroupParams{
16946             allocationKind,
16947             extensionFlags,
16948             QueueSelectionOptions::TransferOnly,
16949             true,
16950             false,
16951         });
16952         addTestGroup(group, "image_to_image_transfer_queue_secondary", addImageToImageTestsSimpleOnly,
16953                      transferWithSecondaryBuffer);
16954 
16955         TestGroupParamsPtr transferWithSparse(new TestGroupParams{
16956             allocationKind,
16957             extensionFlags | SPARSE_BINDING,
16958             QueueSelectionOptions::TransferOnly,
16959             false,
16960             true,
16961         });
16962         addTestGroup(group, "image_to_image_transfer_sparse", addImageToImageTestsSimpleOnly, transferWithSparse);
16963     }
16964 }
16965 
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)16966 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup *group)
16967 {
16968     uint32_t extensionFlags = 0;
16969     addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, extensionFlags);
16970     addBufferCopyOffsetTests(group);
16971 }
16972 
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)16973 void addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup *group)
16974 {
16975     uint32_t extensionFlags = 0;
16976     addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, extensionFlags);
16977 }
16978 
cleanupGroup(tcu::TestCaseGroup *)16979 static void cleanupGroup(tcu::TestCaseGroup *)
16980 {
16981 }
16982 
16983 } // namespace
16984 
createCopiesAndBlittingTests(tcu::TestContext & testCtx)16985 tcu::TestCaseGroup *createCopiesAndBlittingTests(tcu::TestContext &testCtx)
16986 {
16987     de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit"));
16988 
16989     copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", addCoreCopiesAndBlittingTests, cleanupGroup));
16990     copiesAndBlittingTests->addChild(
16991         createTestGroup(testCtx, "dedicated_allocation", addDedicatedAllocationCopiesAndBlittingTests, cleanupGroup));
16992     copiesAndBlittingTests->addChild(createTestGroup(
16993         testCtx, "copy_commands2",
16994         [](tcu::TestCaseGroup *group) { addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, COPY_COMMANDS_2); },
16995         cleanupGroup));
16996     copiesAndBlittingTests->addChild(createTestGroup(
16997         testCtx, "sparse",
16998         [](tcu::TestCaseGroup *group)
16999         { addSparseCopyTests(group, ALLOCATION_KIND_DEDICATED, COPY_COMMANDS_2 | SPARSE_BINDING); },
17000         cleanupGroup));
17001 
17002     return copiesAndBlittingTests.release();
17003 }
17004 
17005 } // namespace api
17006 } // namespace vkt
17007