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