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