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