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