Merge gerrit/vulkan-cts-1.0.1 into gerrit/vulkan-cts-1.0-dev
[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 #include "deMath.h"
30
31 #include "tcuImageCompare.hpp"
32 #include "tcuTexture.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "tcuVectorType.hpp"
35 #include "tcuVectorUtil.hpp"
36
37 #include "vkImageUtil.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkRefUtil.hpp"
42 #include "vktTestCase.hpp"
43 #include "vktTestCaseUtil.hpp"
44 #include "vkTypeUtil.hpp"
45
46 namespace vkt
47 {
48
49 namespace api
50 {
51
52 namespace
53 {
54 enum MirrorMode
55 {
56         MIRROR_MODE_NONE = 0,
57         MIRROR_MODE_X = (1<<0),
58         MIRROR_MODE_Y = (1<<1),
59         MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
60
61         MIRROR_MODE_LAST
62 };
63
64 }
65
66 using namespace vk;
67
68 namespace
69 {
70
71 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
72 {
73         VkImageAspectFlags      aspectFlag      = 0;
74         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
75         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
76
77         if (!aspectFlag)
78                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
79
80         return aspectFlag;
81 }
82
83 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
84 // except that it supports some formats that are not mappable to VkFormat.
85 // When we are checking combined depth and stencil formats, each aspect is
86 // checked separately, and in some cases we construct PBA with a format that
87 // is not mappable to VkFormat.
88 bool isFloatFormat (tcu::TextureFormat format)
89 {
90         return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
91 }
92
93 union CopyRegion
94 {
95         VkBufferCopy            bufferCopy;
96         VkImageCopy                     imageCopy;
97         VkBufferImageCopy       bufferImageCopy;
98         VkImageBlit                     imageBlit;
99         VkImageResolve          imageResolve;
100 };
101
102 struct ImageParms
103 {
104         VkImageType             imageType;
105         VkFormat                format;
106         VkExtent3D              extent;
107 };
108
109 struct TestParams
110 {
111         union
112         {
113                 struct
114                 {
115                         VkDeviceSize    size;
116                 } buffer;
117
118                 ImageParms      image;
119         } src, dst;
120
121         std::vector<CopyRegion> regions;
122
123         union
124         {
125                 VkFilter                                filter;
126                 VkSampleCountFlagBits   samples;
127         };
128 };
129
130 inline deUint32 getArraySize(const ImageParms& parms)
131 {
132         return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
133 }
134
135 inline VkExtent3D getExtent3D(const ImageParms& parms)
136 {
137         const VkExtent3D                extent                                  =
138         {
139                 parms.extent.width,
140                 parms.extent.height,
141                 (parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
142         };
143         return extent;
144 }
145
146 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
147 {
148         tcu::TextureFormat format;
149         switch (combinedFormat.type)
150         {
151                 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
152                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
153                         break;
154                 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
155                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
156                         break;
157                 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
158                         format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
159                         break;
160                 default:
161                         DE_ASSERT(false);
162                         break;
163         }
164         return format;
165 }
166
167 class CopiesAndBlittingTestInstance : public vkt::TestInstance
168 {
169 public:
170                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
171                                                                                                                                                          TestParams     testParams);
172         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
173
174         enum FillMode
175         {
176                 FILL_MODE_GRADIENT = 0,
177                 FILL_MODE_WHITE,
178                 FILL_MODE_RED,
179                 FILL_MODE_MULTISAMPLE,
180
181                 FILL_MODE_LAST
182         };
183
184 protected:
185         const TestParams                                        m_params;
186
187         Move<VkCommandPool>                                     m_cmdPool;
188         Move<VkCommandBuffer>                           m_cmdBuffer;
189         Move<VkFence>                                           m_fence;
190         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
191         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
192         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel;
193
194         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
195
196         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
197         virtual void                                            generateExpectedResult                          (void);
198         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
199         void                                                            uploadImage                                                     (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms);
200         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
201         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
202         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
203                                                                                 {
204                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
205                                                                                 }
206
207         de::MovePtr<tcu::TextureLevel>          readImage                                                       (vk::VkImage                            image,
208                                                                                                                                                          const ImageParms&                      imageParms);
209         void                                                            submitCommandsAndWait                           (const DeviceInterface&         vk,
210                                                                                                                                                         const VkDevice                          device,
211                                                                                                                                                         const VkQueue                           queue,
212                                                                                                                                                         const VkCommandBuffer&          cmdBuffer);
213
214 private:
215         void                                                            uploadImageAspect                                       (const tcu::ConstPixelBufferAccess&     src,
216                                                                                                                                                          const VkImage&                                         dst,
217                                                                                                                                                          const ImageParms&                                      parms);
218         void                                                            readImageAspect                                         (vk::VkImage                                            src,
219                                                                                                                                                          const tcu::PixelBufferAccess&          dst,
220                                                                                                                                                          const ImageParms&                                      parms);
221 };
222
223 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
224         : vkt::TestInstance     (context)
225         , m_params                      (testParams)
226 {
227         const DeviceInterface&          vk                                      = context.getDeviceInterface();
228         const VkDevice                          vkDevice                        = context.getDevice();
229         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
230
231         // Create command pool
232         {
233                 const VkCommandPoolCreateInfo           cmdPoolParams                   =
234                 {
235                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
236                         DE_NULL,                                                                                // const void*                  pNext;
237                         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,// VkCmdPoolCreateFlags flags;
238                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
239                 };
240
241                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
242         }
243
244         // Create command buffer
245         {
246                 const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
247                 {
248                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
249                         DE_NULL,                                                                                // const void*                          pNext;
250                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
251                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
252                         1u                                                                                              // deUint32                                     bufferCount;
253                 };
254
255                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
256         }
257
258         // Create fence
259         {
260                 const VkFenceCreateInfo                         fenceParams                             =
261                 {
262                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
263                         DE_NULL,                                                                // const void*                  pNext;
264                         0u                                                                              // VkFenceCreateFlags   flags;
265                 };
266
267                 m_fence = createFence(vk, vkDevice, &fenceParams);
268         }
269 }
270
271 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
272 {
273         if (mode == FILL_MODE_GRADIENT)
274         {
275                 tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
276                 return;
277         }
278
279         const tcu::Vec4         redColor        (1.0, 0.0, 0.0, 1.0);
280         const tcu::Vec4         greenColor      (0.0, 1.0, 0.0, 1.0);
281         const tcu::Vec4         blueColor       (0.0, 0.0, 1.0, 1.0);
282         const tcu::Vec4         whiteColor      (1.0, 1.0, 1.0, 1.0);
283
284         for (int z = 0; z < depth; z++)
285         {
286                 for (int y = 0; y < height; y++)
287                 {
288                         for (int x = 0; x < width; x++)
289                         {
290                                 switch (mode)
291                                 {
292                                         case FILL_MODE_WHITE:
293                                                 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
294                                                 {
295                                                         buffer.setPixDepth(1.0f, x, y, z);
296                                                         if (tcu::hasStencilComponent(buffer.getFormat().order))
297                                                                 buffer.setPixStencil(255, x, y, z);
298                                                 }
299                                                 else
300                                                         buffer.setPixel(whiteColor, x, y, z);
301                                                 break;
302                                         case FILL_MODE_RED:
303                                                 DE_ASSERT(!tcu::isCombinedDepthStencilType(buffer.getFormat().type)); // combined types cannot be accessed directly
304                                                 buffer.setPixel(redColor, x, y, z);
305                                                 break;
306                                         case FILL_MODE_MULTISAMPLE:
307                                                 buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z);
308                                                 break;
309                                         default:
310                                                 break;
311                                 }
312                         }
313                 }
314         }
315 }
316
317 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
318 {
319         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
320         const VkDevice                          vkDevice        = m_context.getDevice();
321         const deUint32                          bufferSize      = calculateSize(bufferAccess);
322
323         // Write buffer data
324         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
325         flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
326 }
327
328 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms)
329 {
330         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
331         const VkDevice                          vkDevice                        = m_context.getDevice();
332         const VkQueue                           queue                           = m_context.getUniversalQueue();
333         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
334         Allocator&                                      memAlloc                        = m_context.getDefaultAllocator();
335
336         Move<VkBuffer>                          buffer;
337         const deUint32                          bufferSize                      = calculateSize(imageAccess);
338         de::MovePtr<Allocation>         bufferAlloc;
339         const deUint32                          arraySize                       = getArraySize(parms);
340         const VkExtent3D                        imageExtent                     = getExtent3D(parms);
341
342         // Create source buffer
343         {
344                 const VkBufferCreateInfo                        bufferParams                    =
345                 {
346                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
347                         DE_NULL,                                                                        // const void*                  pNext;
348                         0u,                                                                                     // VkBufferCreateFlags  flags;
349                         bufferSize,                                                                     // VkDeviceSize                 size;
350                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
351                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
352                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
353                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
354                 };
355
356                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
357                 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
358                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
359         }
360
361         // Barriers for copying buffer to image
362         const VkBufferMemoryBarrier                             preBufferBarrier                =
363         {
364                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
365                 DE_NULL,                                                                                // const void*          pNext;
366                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
367                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
368                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
369                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
370                 *buffer,                                                                                // VkBuffer                     buffer;
371                 0u,                                                                                             // VkDeviceSize         offset;
372                 bufferSize                                                                              // VkDeviceSize         size;
373         };
374
375         const VkImageAspectFlags                                aspect                                  = getAspectFlags(imageAccess.getFormat());
376         const VkImageMemoryBarrier                              preImageBarrier                 =
377         {
378                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
379                 DE_NULL,                                                                                // const void*                          pNext;
380                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
381                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
382                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
383                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
384                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
385                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
386                 image,                                                                                  // VkImage                                      image;
387                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
388                         aspect,                 // VkImageAspectFlags   aspect;
389                         0u,                             // deUint32                             baseMipLevel;
390                         1u,                             // deUint32                             mipLevels;
391                         0u,                             // deUint32                             baseArraySlice;
392                         arraySize,              // deUint32                             arraySize;
393                 }
394         };
395
396         const VkImageMemoryBarrier                              postImageBarrier                =
397         {
398                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
399                 DE_NULL,                                                                                // const void*                          pNext;
400                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
401                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        dstAccessMask;
402                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
403                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
404                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
405                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
406                 image,                                                                                  // VkImage                                      image;
407                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
408                         aspect,                                         // VkImageAspectFlags   aspect;
409                         0u,                                                     // deUint32                             baseMipLevel;
410                         1u,                                                     // deUint32                             mipLevels;
411                         0u,                                                     // deUint32                             baseArraySlice;
412                         arraySize,                                      // deUint32                             arraySize;
413                 }
414         };
415
416         const VkBufferImageCopy         copyRegion              =
417         {
418                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
419                 (deUint32)imageAccess.getWidth(),                               // deUint32                                     bufferRowLength;
420                 (deUint32)imageAccess.getHeight(),                              // deUint32                                     bufferImageHeight;
421                 {
422                         getAspectFlags(imageAccess.getFormat()),                // VkImageAspectFlags   aspect;
423                         0u,                                                                                             // deUint32                             mipLevel;
424                         0u,                                                                                             // deUint32                             baseArrayLayer;
425                         arraySize,                                                                              // deUint32                             layerCount;
426                 },                                                                                              // VkImageSubresourceLayers     imageSubresource;
427                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
428                 imageExtent                                                                             // VkExtent3D                           imageExtent;
429         };
430
431         // Write buffer data
432         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
433         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
434
435         // Copy buffer to image
436         const VkCommandBufferBeginInfo                  cmdBufferBeginInfo              =
437         {
438                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
439                 DE_NULL,                                                                                                // const void*                                          pNext;
440                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
441                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
442         };
443
444         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
445         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
446         vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
447         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);
448         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
449
450         submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
451 }
452
453 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms)
454 {
455         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
456         {
457                 if (tcu::hasDepthComponent(src.getFormat().order))
458                 {
459                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
460                         tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
461                         uploadImageAspect(depthTexture.getAccess(), dst, parms);
462                 }
463
464                 if (tcu::hasStencilComponent(src.getFormat().order))
465                 {
466                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
467                         tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
468                         uploadImageAspect(stencilTexture.getAccess(), dst, parms);
469                 }
470         }
471         else
472                 uploadImageAspect(src, dst, parms);
473 }
474
475 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
476 {
477         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel->getAccess();
478
479         if (isFloatFormat(result.getFormat()))
480         {
481                 const tcu::Vec4 threshold (0.0f);
482                 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
483                         return tcu::TestStatus::fail("CopiesAndBlitting test");
484         }
485         else
486         {
487                 const tcu::UVec4 threshold (0u);
488                 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
489                         return tcu::TestStatus::fail("CopiesAndBlitting test");
490         }
491
492         return tcu::TestStatus::pass("CopiesAndBlitting test");
493 }
494
495 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
496 {
497         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
498         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
499
500         m_expectedTextureLevel  = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
501         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
502
503         for (deUint32 i = 0; i < m_params.regions.size(); i++)
504                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
505 }
506
507 class CopiesAndBlittingTestCase : public vkt::TestCase
508 {
509 public:
510                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
511                                                                                                                  const std::string&                     name,
512                                                                                                                  const std::string&                     description)
513                                                                 : vkt::TestCase (testCtx, name, description)
514                                                         {}
515
516         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
517 };
518
519 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage                                        image,
520                                                                                                          const tcu::PixelBufferAccess&  dst,
521                                                                                                          const ImageParms&                              imageParms)
522 {
523         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
524         const VkDevice                          device                          = m_context.getDevice();
525         const VkQueue                           queue                           = m_context.getUniversalQueue();
526         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
527
528         Move<VkBuffer>                          buffer;
529         de::MovePtr<Allocation>         bufferAlloc;
530         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
531         const VkDeviceSize                      pixelDataSize           = calculateSize(dst);
532         const VkExtent3D                        imageExtent                     = getExtent3D(imageParms);
533
534         // Create destination buffer
535         {
536                 const VkBufferCreateInfo                        bufferParams                    =
537                 {
538                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
539                         DE_NULL,                                                                        // const void*                  pNext;
540                         0u,                                                                                     // VkBufferCreateFlags  flags;
541                         pixelDataSize,                                                          // VkDeviceSize                 size;
542                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
543                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
544                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
545                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
546                 };
547
548                 buffer          = createBuffer(vk, device, &bufferParams);
549                 bufferAlloc     = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
550                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
551
552                 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
553                 flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
554         }
555
556         // Barriers for copying image to buffer
557         const VkImageAspectFlags                                aspect                                  = getAspectFlags(dst.getFormat());
558         const VkImageMemoryBarrier                              imageBarrier                    =
559         {
560                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
561                 DE_NULL,                                                                        // const void*                          pNext;
562                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
563                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
564                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
565                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
566                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
567                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
568                 image,                                                                          // VkImage                                      image;
569                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
570                         aspect,                                 // VkImageAspectFlags   aspectMask;
571                         0u,                                             // deUint32                             baseMipLevel;
572                         1u,                                             // deUint32                             mipLevels;
573                         0u,                                             // deUint32                             baseArraySlice;
574                         getArraySize(imageParms)// deUint32                             arraySize;
575                 }
576         };
577
578         const VkBufferMemoryBarrier                             bufferBarrier                   =
579         {
580                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
581                 DE_NULL,                                                                        // const void*          pNext;
582                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
583                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
584                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
585                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
586                 *buffer,                                                                        // VkBuffer                     buffer;
587                 0u,                                                                                     // VkDeviceSize         offset;
588                 pixelDataSize                                                           // VkDeviceSize         size;
589         };
590
591         // Copy image to buffer
592         const VkBufferImageCopy         copyRegion              =
593         {
594                 0u,                                                                     // VkDeviceSize                         bufferOffset;
595                 (deUint32)dst.getWidth(),                       // deUint32                                     bufferRowLength;
596                 (deUint32)dst.getHeight(),                      // deUint32                                     bufferImageHeight;
597                 {
598                         aspect,                                                         // VkImageAspectFlags           aspect;
599                         0u,                                                                     // deUint32                                     mipLevel;
600                         0u,                                                                     // deUint32                                     baseArrayLayer;
601                         getArraySize(imageParms),                       // deUint32                                     layerCount;
602                 },                                                                      // VkImageSubresourceLayers     imageSubresource;
603                 { 0, 0, 0 },                                            // VkOffset3D                           imageOffset;
604                 imageExtent                                                     // VkExtent3D                           imageExtent;
605         };
606
607         const VkCommandBufferBeginInfo                  cmdBufferBeginInfo              =
608         {
609                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
610                 DE_NULL,                                                                                                // const void*                                          pNext;
611                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
612                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
613         };
614
615         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
616         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);
617         vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
618         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);
619         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
620
621         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
622
623         // Read buffer data
624         invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
625         tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
626 }
627
628 void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
629 {
630         const VkSubmitInfo                                              submitInfo                              =
631         {
632                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
633                 DE_NULL,                                                // const void*                          pNext;
634                 0u,                                                             // deUint32                                     waitSemaphoreCount;
635                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
636                 (const VkPipelineStageFlags*)DE_NULL,
637                 1u,                                                             // deUint32                                     commandBufferCount;
638                 &cmdBuffer,                                             // const VkCommandBuffer*       pCommandBuffers;
639                 0u,                                                             // deUint32                                     signalSemaphoreCount;
640                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
641         };
642
643         VK_CHECK(vk.resetFences(device, 1, &m_fence.get()));
644         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
645         VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
646 }
647
648 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage            image,
649                                                                                                                                                  const ImageParms&      parms)
650 {
651         const tcu::TextureFormat                imageFormat     = mapVkFormat(parms.format);
652         de::MovePtr<tcu::TextureLevel>  resultLevel     (new tcu::TextureLevel(imageFormat, parms.extent.width, parms.extent.height, parms.extent.depth));
653
654         if (tcu::isCombinedDepthStencilType(imageFormat.type))
655         {
656                 if (tcu::hasDepthComponent(imageFormat.order))
657                 {
658                         tcu::TextureLevel       depthTexture    (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
659                         readImageAspect(image, depthTexture.getAccess(), parms);
660                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
661                 }
662
663                 if (tcu::hasStencilComponent(imageFormat.order))
664                 {
665                         tcu::TextureLevel       stencilTexture  (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
666                         readImageAspect(image, stencilTexture.getAccess(), parms);
667                         tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
668                 }
669         }
670         else
671                 readImageAspect(image, resultLevel->getAccess(), parms);
672
673         return resultLevel;
674 }
675
676 // Copy from image to image.
677
678 class CopyImageToImage : public CopiesAndBlittingTestInstance
679 {
680 public:
681                                                                                 CopyImageToImage                        (Context&       context,
682                                                                                                                                          TestParams params);
683         virtual tcu::TestStatus                         iterate                                         (void);
684 private:
685         Move<VkImage>                                           m_source;
686         de::MovePtr<Allocation>                         m_sourceImageAlloc;
687         Move<VkImage>                                           m_destination;
688         de::MovePtr<Allocation>                         m_destinationImageAlloc;
689
690         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
691 };
692
693 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
694         : CopiesAndBlittingTestInstance(context, params)
695 {
696         const DeviceInterface&          vk                                      = context.getDeviceInterface();
697         const VkDevice                          vkDevice                        = context.getDevice();
698         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
699         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
700
701         VkImageFormatProperties properties;
702         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
703                                                                                                                                                                 m_params.src.image.format,
704                                                                                                                                                                 VK_IMAGE_TYPE_2D,
705                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
706                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
707                                                                                                                                                                 0,
708                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
709                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
710                                                                                                                                                                 m_params.dst.image.format,
711                                                                                                                                                                 VK_IMAGE_TYPE_2D,
712                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
713                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
714                                                                                                                                                                 0,
715                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
716         {
717                 TCU_THROW(NotSupportedError, "Format not supported");
718         }
719
720         // Create source image
721         {
722                 const VkImageCreateInfo sourceImageParams               =
723                 {
724                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
725                         DE_NULL,                                                                // const void*                  pNext;
726                         0u,                                                                             // VkImageCreateFlags   flags;
727                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
728                         m_params.src.image.format,                              // VkFormat                             format;
729                         m_params.src.image.extent,                              // VkExtent3D                   extent;
730                         1u,                                                                             // deUint32                             mipLevels;
731                         1u,                                                                             // deUint32                             arraySize;
732                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
733                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
734                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
735                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
736                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
737                         1u,                                                                             // deUint32                             queueFamilyCount;
738                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
739                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
740                 };
741
742                 m_source                                = createImage(vk, vkDevice, &sourceImageParams);
743                 m_sourceImageAlloc              = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
744                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
745         }
746
747         // Create destination image
748         {
749                 const VkImageCreateInfo destinationImageParams  =
750                 {
751                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
752                         DE_NULL,                                                                // const void*                  pNext;
753                         0u,                                                                             // VkImageCreateFlags   flags;
754                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
755                         m_params.dst.image.format,                              // VkFormat                             format;
756                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
757                         1u,                                                                             // deUint32                             mipLevels;
758                         1u,                                                                             // deUint32                             arraySize;
759                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
760                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
761                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
762                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
763                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
764                         1u,                                                                             // deUint32                             queueFamilyCount;
765                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
766                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
767                 };
768
769                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
770                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
771                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
772         }
773 }
774
775 tcu::TestStatus CopyImageToImage::iterate (void)
776 {
777         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
778         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
779         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
780                                                                                                                                                                 m_params.src.image.extent.width,
781                                                                                                                                                                 m_params.src.image.extent.height,
782                                                                                                                                                                 m_params.src.image.extent.depth));
783         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_WHITE);
784         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
785                                                                                                                                                                          (int)m_params.dst.image.extent.width,
786                                                                                                                                                                          (int)m_params.dst.image.extent.height,
787                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
788         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);
789         generateExpectedResult();
790
791         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
792         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
793
794         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
795         const VkDevice                          vkDevice                        = m_context.getDevice();
796         const VkQueue                           queue                           = m_context.getUniversalQueue();
797
798         std::vector<VkImageCopy>        imageCopies;
799         for (deUint32 i = 0; i < m_params.regions.size(); i++)
800                 imageCopies.push_back(m_params.regions[i].imageCopy);
801
802         const VkImageMemoryBarrier      imageBarriers[]         =
803         {
804                 // source image
805                 {
806                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
807                         DE_NULL,                                                                        // const void*                          pNext;
808                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
809                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
810                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
811                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
812                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
813                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
814                         m_source.get(),                                                         // VkImage                                      image;
815                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
816                                 getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
817                                 0u,                                                             // deUint32                             baseMipLevel;
818                                 1u,                                                             // deUint32                             mipLevels;
819                                 0u,                                                             // deUint32                             baseArraySlice;
820                                 1u                                                              // deUint32                             arraySize;
821                         }
822                 },
823                 // destination image
824                 {
825                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
826                         DE_NULL,                                                                        // const void*                          pNext;
827                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
828                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
829                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
830                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
831                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
832                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
833                         m_destination.get(),                                            // VkImage                                      image;
834                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
835                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
836                                 0u,                                                             // deUint32                             baseMipLevel;
837                                 1u,                                                             // deUint32                             mipLevels;
838                                 0u,                                                             // deUint32                             baseArraySlice;
839                                 1u                                                              // deUint32                             arraySize;
840                         }
841                 },
842         };
843
844         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
845         {
846                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
847                 DE_NULL,                                                                                                // const void*                                          pNext;
848                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
849                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
850         };
851
852         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
853         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);
854         vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageCopies.data());
855         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
856
857         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
858
859         de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
860
861         return checkTestResult(resultTextureLevel->getAccess());
862 }
863
864 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
865 {
866         VkOffset3D srcOffset    = region.imageCopy.srcOffset;
867         VkOffset3D dstOffset    = region.imageCopy.dstOffset;
868         VkExtent3D extent               = region.imageCopy.extent;
869
870         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
871         {
872                 DE_ASSERT(src.getFormat() == dst.getFormat());
873                 // Copy depth.
874                 {
875                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
876                         const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
877                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
878
879                         tcu::copy(dstSubRegion, srcSubRegion);
880                 }
881
882                 // Copy stencil.
883                 if (tcu::hasStencilComponent(src.getFormat().order))
884                 {
885                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
886                         const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
887                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
888
889                         tcu::copy(dstSubRegion, srcSubRegion);
890                 }
891         }
892         else
893         {
894                 const tcu::ConstPixelBufferAccess       srcSubRegion            = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
895                 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
896                 const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
897                 const tcu::PixelBufferAccess            dstSubRegion            = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
898
899                 tcu::copy(dstSubRegion, srcSubRegion);
900         }
901 }
902
903 class CopyImageToImageTestCase : public vkt::TestCase
904 {
905 public:
906                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
907                                                                                                                  const std::string&                             name,
908                                                                                                                  const std::string&                             description,
909                                                                                                                  const TestParams                               params)
910                                                                 : vkt::TestCase (testCtx, name, description)
911                                                                 , m_params              (params)
912                                                         {}
913
914         virtual TestInstance*   createInstance                          (Context&                                               context) const
915                                                         {
916                                                                 return new CopyImageToImage(context, m_params);
917                                                         }
918 private:
919         TestParams                              m_params;
920 };
921
922 // Copy from buffer to buffer.
923
924 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
925 {
926 public:
927                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
928         virtual tcu::TestStatus         iterate                                         (void);
929 private:
930         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
931         Move<VkBuffer>                          m_source;
932         de::MovePtr<Allocation>         m_sourceBufferAlloc;
933         Move<VkBuffer>                          m_destination;
934         de::MovePtr<Allocation>         m_destinationBufferAlloc;
935 };
936
937 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
938         : CopiesAndBlittingTestInstance (context, params)
939 {
940         const DeviceInterface&          vk                                      = context.getDeviceInterface();
941         const VkDevice                          vkDevice                        = context.getDevice();
942         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
943         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
944
945         // Create source buffer
946         {
947                 const VkBufferCreateInfo        sourceBufferParams              =
948                 {
949                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
950                         DE_NULL,                                                                        // const void*                  pNext;
951                         0u,                                                                                     // VkBufferCreateFlags  flags;
952                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
953                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
954                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
955                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
956                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
957                 };
958
959                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
960                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
961                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
962         }
963
964         // Create destination buffer
965         {
966                 const VkBufferCreateInfo        destinationBufferParams =
967                 {
968                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
969                         DE_NULL,                                                                        // const void*                  pNext;
970                         0u,                                                                                     // VkBufferCreateFlags  flags;
971                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
972                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
973                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
974                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
975                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
976                 };
977
978                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
979                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
980                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
981         }
982 }
983
984 tcu::TestStatus CopyBufferToBuffer::iterate (void)
985 {
986         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
987         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
988         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
989
990         const int dstLevelWidth         = (int)(m_params.dst.buffer.size/4);
991         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
992         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
993
994         generateExpectedResult();
995
996         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
997         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
998
999         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1000         const VkDevice                          vkDevice        = m_context.getDevice();
1001         const VkQueue                           queue           = m_context.getUniversalQueue();
1002
1003         const VkBufferMemoryBarrier             srcBufferBarrier        =
1004         {
1005                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1006                 DE_NULL,                                                                        // const void*          pNext;
1007                 VK_ACCESS_HOST_WRITE_BIT,                                       // VkAccessFlags        srcAccessMask;
1008                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags        dstAccessMask;
1009                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1010                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1011                 *m_source,                                                                      // VkBuffer                     buffer;
1012                 0u,                                                                                     // VkDeviceSize         offset;
1013                 m_params.src.buffer.size                                        // VkDeviceSize         size;
1014         };
1015
1016         const VkBufferMemoryBarrier             dstBufferBarrier        =
1017         {
1018                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1019                 DE_NULL,                                                                        // const void*          pNext;
1020                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1021                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1022                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1023                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1024                 *m_destination,                                                         // VkBuffer                     buffer;
1025                 0u,                                                                                     // VkDeviceSize         offset;
1026                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
1027         };
1028
1029         std::vector<VkBufferCopy>               bufferCopies;
1030         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1031                 bufferCopies.push_back(m_params.regions[i].bufferCopy);
1032
1033         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1034         {
1035                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1036                 DE_NULL,                                                                                                // const void*                                          pNext;
1037                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1038                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1039         };
1040
1041         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1042         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);
1043         vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
1044         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);
1045         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1046
1047         const VkSubmitInfo                              submitInfo                      =
1048         {
1049                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1050                 DE_NULL,                                                // const void*                          pNext;
1051                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1052                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1053                 (const VkPipelineStageFlags*)DE_NULL,
1054                 1u,                                                             // deUint32                                     commandBufferCount;
1055                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1056                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1057                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1058         };
1059
1060         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1061         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1062         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1063
1064         // Read buffer data
1065         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1066         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
1067         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1068
1069         return checkTestResult(resultLevel->getAccess());
1070 }
1071
1072 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1073 {
1074         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
1075                          (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
1076                          (size_t)region.bufferCopy.size);
1077 }
1078
1079 class BufferToBufferTestCase : public vkt::TestCase
1080 {
1081 public:
1082                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
1083                                                                                                          const std::string&     name,
1084                                                                                                          const std::string&     description,
1085                                                                                                          const TestParams       params)
1086                                                                 : vkt::TestCase (testCtx, name, description)
1087                                                                 , m_params              (params)
1088                                                         {}
1089
1090         virtual TestInstance*   createInstance                  (Context& context) const
1091                                                         {
1092                                                                 return new CopyBufferToBuffer(context, m_params);
1093                                                         }
1094 private:
1095         TestParams                              m_params;
1096 };
1097
1098 // Copy from image to buffer.
1099
1100 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1101 {
1102 public:
1103                                                                 CopyImageToBuffer                       (Context&       context,
1104                                                                                                                          TestParams     testParams);
1105         virtual tcu::TestStatus         iterate                                         (void);
1106 private:
1107         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1108
1109         tcu::TextureFormat                      m_textureFormat;
1110         VkDeviceSize                            m_bufferSize;
1111
1112         Move<VkImage>                           m_source;
1113         de::MovePtr<Allocation>         m_sourceImageAlloc;
1114         Move<VkBuffer>                          m_destination;
1115         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1116 };
1117
1118 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1119         : CopiesAndBlittingTestInstance(context, testParams)
1120         , m_textureFormat(mapVkFormat(testParams.src.image.format))
1121         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1122 {
1123         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1124         const VkDevice                          vkDevice                        = context.getDevice();
1125         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1126         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1127
1128         // Create source image
1129         {
1130                 const VkImageCreateInfo         sourceImageParams               =
1131                 {
1132                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1133                         DE_NULL,                                                                // const void*                  pNext;
1134                         0u,                                                                             // VkImageCreateFlags   flags;
1135                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1136                         m_params.src.image.format,                              // VkFormat                             format;
1137                         m_params.src.image.extent,                              // VkExtent3D                   extent;
1138                         1u,                                                                             // deUint32                             mipLevels;
1139                         1u,                                                                             // deUint32                             arraySize;
1140                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1141                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1142                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1143                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1144                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1145                         1u,                                                                             // deUint32                             queueFamilyCount;
1146                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1147                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1148                 };
1149
1150                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
1151                 m_sourceImageAlloc      = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1152                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1153         }
1154
1155         // Create destination buffer
1156         {
1157                 const VkBufferCreateInfo        destinationBufferParams =
1158                 {
1159                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1160                         DE_NULL,                                                                        // const void*                  pNext;
1161                         0u,                                                                                     // VkBufferCreateFlags  flags;
1162                         m_bufferSize,                                                           // VkDeviceSize                 size;
1163                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1164                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1165                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1166                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1167                 };
1168
1169                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1170                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1171                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1172         }
1173 }
1174
1175 tcu::TestStatus CopyImageToBuffer::iterate (void)
1176 {
1177         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1178                                                                                                                                                                 m_params.src.image.extent.width,
1179                                                                                                                                                                 m_params.src.image.extent.height,
1180                                                                                                                                                                 m_params.src.image.extent.depth));
1181         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1182         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1183         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1184
1185         generateExpectedResult();
1186
1187         uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
1188         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1189
1190         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1191         const VkDevice                          vkDevice        = m_context.getDevice();
1192         const VkQueue                           queue           = m_context.getUniversalQueue();
1193
1194         // Barriers for copying image to buffer
1195         const VkImageMemoryBarrier              imageBarrier            =
1196         {
1197                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1198                 DE_NULL,                                                                        // const void*                          pNext;
1199                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1200                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1201                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1202                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1203                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1204                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1205                 *m_source,                                                                      // VkImage                                      image;
1206                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1207                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
1208                         0u,                                                             // deUint32                             baseMipLevel;
1209                         1u,                                                             // deUint32                             mipLevels;
1210                         0u,                                                             // deUint32                             baseArraySlice;
1211                         1u                                                              // deUint32                             arraySize;
1212                 }
1213         };
1214
1215         const VkBufferMemoryBarrier             bufferBarrier           =
1216         {
1217                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1218                 DE_NULL,                                                                        // const void*          pNext;
1219                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1220                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1221                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1222                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1223                 *m_destination,                                                         // VkBuffer                     buffer;
1224                 0u,                                                                                     // VkDeviceSize         offset;
1225                 m_bufferSize                                                            // VkDeviceSize         size;
1226         };
1227
1228         // Copy from image to buffer
1229         std::vector<VkBufferImageCopy>  bufferImageCopies;
1230         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1231                 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1232
1233         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1234         {
1235                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1236                 DE_NULL,                                                                                                // const void*                                          pNext;
1237                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1238                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1239         };
1240
1241         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1242         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);
1243         vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
1244         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);
1245         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1246
1247         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1248
1249         // Read buffer data
1250         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1251         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1252         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1253
1254         return checkTestResult(resultLevel->getAccess());
1255 }
1256
1257 class CopyImageToBufferTestCase : public vkt::TestCase
1258 {
1259 public:
1260                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
1261                                                                                                                  const std::string&             name,
1262                                                                                                                  const std::string&             description,
1263                                                                                                                  const TestParams               params)
1264                                                                 : vkt::TestCase (testCtx, name, description)
1265                                                                 , m_params              (params)
1266                                                         {}
1267
1268         virtual TestInstance*   createInstance                          (Context&                               context) const
1269                                                         {
1270                                                                 return new CopyImageToBuffer(context, m_params);
1271                                                         }
1272 private:
1273         TestParams                              m_params;
1274 };
1275
1276 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1277 {
1278         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
1279         if (!rowLength)
1280                 rowLength = region.bufferImageCopy.imageExtent.width;
1281
1282         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
1283         if (!imageHeight)
1284                 imageHeight = region.bufferImageCopy.imageExtent.height;
1285
1286         const int                       texelSize       = src.getFormat().getPixelSize();
1287         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1288         const VkOffset3D        srcOffset       = region.bufferImageCopy.imageOffset;
1289         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1290
1291         for (deUint32 z = 0; z < extent.depth; z++)
1292         {
1293                 for (deUint32 y = 0; y < extent.height; y++)
1294                 {
1295                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
1296                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1297                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1298                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1299                         tcu::copy(dstSubRegion, srcSubRegion);
1300                 }
1301         }
1302 }
1303
1304 // Copy from buffer to image.
1305
1306 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1307 {
1308 public:
1309                                                                 CopyBufferToImage                       (Context&       context,
1310                                                                                                                          TestParams     testParams);
1311         virtual tcu::TestStatus         iterate                                         (void);
1312 private:
1313         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1314
1315         tcu::TextureFormat                      m_textureFormat;
1316         VkDeviceSize                            m_bufferSize;
1317
1318         Move<VkBuffer>                          m_source;
1319         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1320         Move<VkImage>                           m_destination;
1321         de::MovePtr<Allocation>         m_destinationImageAlloc;
1322 };
1323
1324 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1325         : CopiesAndBlittingTestInstance(context, testParams)
1326         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1327         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1328 {
1329         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1330         const VkDevice                          vkDevice                        = context.getDevice();
1331         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1332         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1333
1334         // Create source buffer
1335         {
1336                 const VkBufferCreateInfo        sourceBufferParams              =
1337                 {
1338                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1339                         DE_NULL,                                                                        // const void*                  pNext;
1340                         0u,                                                                                     // VkBufferCreateFlags  flags;
1341                         m_bufferSize,                                                           // VkDeviceSize                 size;
1342                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1343                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1344                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1345                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1346                 };
1347
1348                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1349                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1350                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1351         }
1352
1353         // Create destination image
1354         {
1355                 const VkImageCreateInfo         destinationImageParams  =
1356                 {
1357                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1358                         DE_NULL,                                                                // const void*                  pNext;
1359                         0u,                                                                             // VkImageCreateFlags   flags;
1360                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1361                         m_params.dst.image.format,                              // VkFormat                             format;
1362                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
1363                         1u,                                                                             // deUint32                             mipLevels;
1364                         1u,                                                                             // deUint32                             arraySize;
1365                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1366                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1367                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1368                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1369                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1370                         1u,                                                                             // deUint32                             queueFamilyCount;
1371                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1372                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1373                 };
1374
1375                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1376                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1377                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1378         }
1379 }
1380
1381 tcu::TestStatus CopyBufferToImage::iterate (void)
1382 {
1383         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1384         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
1385         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1386                                                                                                                                                                         m_params.dst.image.extent.width,
1387                                                                                                                                                                         m_params.dst.image.extent.height,
1388                                                                                                                                                                         m_params.dst.image.extent.depth));
1389
1390         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
1391
1392         generateExpectedResult();
1393
1394         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1395         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
1396
1397         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1398         const VkDevice                          vkDevice        = m_context.getDevice();
1399         const VkQueue                           queue           = m_context.getUniversalQueue();
1400
1401         const VkImageMemoryBarrier      imageBarrier    =
1402         {
1403                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1404                 DE_NULL,                                                                        // const void*                          pNext;
1405                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1406                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1407                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1408                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
1409                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1410                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1411                 *m_destination,                                                         // VkImage                                      image;
1412                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1413                         getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
1414                         0u,                                                             // deUint32                             baseMipLevel;
1415                         1u,                                                             // deUint32                             mipLevels;
1416                         0u,                                                             // deUint32                             baseArraySlice;
1417                         1u                                                              // deUint32                             arraySize;
1418                 }
1419         };
1420
1421         // Copy from buffer to image
1422         std::vector<VkBufferImageCopy>          bufferImageCopies;
1423         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1424                 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1425
1426         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1427         {
1428                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1429                 DE_NULL,                                                                                                // const void*                                          pNext;
1430                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1431                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1432         };
1433
1434         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1435         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);
1436         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
1437         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1438
1439         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1440
1441         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(*m_destination, m_params.dst.image);
1442
1443         return checkTestResult(resultLevel->getAccess());
1444 }
1445
1446 class CopyBufferToImageTestCase : public vkt::TestCase
1447 {
1448 public:
1449                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
1450                                                                                                                  const std::string&             name,
1451                                                                                                                  const std::string&             description,
1452                                                                                                                  const TestParams               params)
1453                                                                 : vkt::TestCase (testCtx, name, description)
1454                                                                 , m_params              (params)
1455                                                         {}
1456
1457         virtual                                 ~CopyBufferToImageTestCase      (void) {}
1458
1459         virtual TestInstance*   createInstance                          (Context&                               context) const
1460                                                         {
1461                                                                 return new CopyBufferToImage(context, m_params);
1462                                                         }
1463 private:
1464         TestParams                              m_params;
1465 };
1466
1467 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1468 {
1469         deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
1470         if (!rowLength)
1471                 rowLength = region.bufferImageCopy.imageExtent.width;
1472
1473         deUint32                        imageHeight     = region.bufferImageCopy.bufferImageHeight;
1474         if (!imageHeight)
1475                 imageHeight = region.bufferImageCopy.imageExtent.height;
1476
1477         const int                       texelSize       = dst.getFormat().getPixelSize();
1478         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1479         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
1480         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1481
1482         for (deUint32 z = 0; z < extent.depth; z++)
1483         {
1484                 for (deUint32 y = 0; y < extent.height; y++)
1485                 {
1486                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) * rowLength;
1487                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1488                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1489                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1490                         tcu::copy(dstSubRegion, srcSubRegion);
1491                 }
1492         }
1493 }
1494
1495 // Copy from image to image with scaling.
1496
1497 class BlittingImages : public CopiesAndBlittingTestInstance
1498 {
1499 public:
1500                                                                                 BlittingImages                                  (Context&       context,
1501                                                                                                                                                  TestParams params);
1502         virtual tcu::TestStatus                         iterate                                                 (void);
1503 protected:
1504         virtual tcu::TestStatus                         checkTestResult                                 (tcu::ConstPixelBufferAccess result);
1505         virtual void                                            copyRegionToTextureLevel                (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1506         virtual void                                            generateExpectedResult                  (void);
1507 private:
1508         bool                                                            checkClampedAndUnclampedResult  (const tcu::ConstPixelBufferAccess&     result,
1509                                                                                                                                                  const tcu::ConstPixelBufferAccess&     clampedReference,
1510                                                                                                                                                  const tcu::ConstPixelBufferAccess&     unclampedReference,
1511                                                                                                                                                  VkImageAspectFlagBits                          aspect);
1512         Move<VkImage>                                           m_source;
1513         de::MovePtr<Allocation>                         m_sourceImageAlloc;
1514         Move<VkImage>                                           m_destination;
1515         de::MovePtr<Allocation>                         m_destinationImageAlloc;
1516
1517         de::MovePtr<tcu::TextureLevel>          m_unclampedExpectedTextureLevel;
1518 };
1519
1520 BlittingImages::BlittingImages (Context& context, TestParams params)
1521         : CopiesAndBlittingTestInstance(context, params)
1522 {
1523         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1524         const VkDevice                          vkDevice                        = context.getDevice();
1525         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1526         Allocator&                                      memAlloc                        = context.getDefaultAllocator();
1527
1528         VkImageFormatProperties properties;
1529         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1530                                                                                                                                                                 m_params.src.image.format,
1531                                                                                                                                                                 VK_IMAGE_TYPE_2D,
1532                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
1533                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1534                                                                                                                                                                 0,
1535                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1536                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1537                                                                                                                                                                 m_params.dst.image.format,
1538                                                                                                                                                                 VK_IMAGE_TYPE_2D,
1539                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
1540                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1541                                                                                                                                                                 0,
1542                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1543         {
1544                 TCU_THROW(NotSupportedError, "Format not supported");
1545         }
1546
1547         VkFormatProperties srcFormatProperties;
1548         context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
1549         if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
1550         {
1551                 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
1552         }
1553
1554         VkFormatProperties dstFormatProperties;
1555         context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
1556         if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
1557         {
1558                 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
1559         }
1560
1561         if (m_params.filter == VK_FILTER_LINEAR)
1562         {
1563                 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1564                         TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
1565                 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1566                         TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported");
1567         }
1568
1569         // Create source image
1570         {
1571                 const VkImageCreateInfo         sourceImageParams               =
1572                 {
1573                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1574                         DE_NULL,                                                                // const void*                  pNext;
1575                         0u,                                                                             // VkImageCreateFlags   flags;
1576                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1577                         m_params.src.image.format,                              // VkFormat                             format;
1578                         m_params.src.image.extent,                              // VkExtent3D                   extent;
1579                         1u,                                                                             // deUint32                             mipLevels;
1580                         1u,                                                                             // deUint32                             arraySize;
1581                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1582                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1583                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1584                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1585                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1586                         1u,                                                                             // deUint32                             queueFamilyCount;
1587                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1588                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1589                 };
1590
1591                 m_source = createImage(vk, vkDevice, &sourceImageParams);
1592                 m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1593                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1594         }
1595
1596         // Create destination image
1597         {
1598                 const VkImageCreateInfo         destinationImageParams  =
1599                 {
1600                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1601                         DE_NULL,                                                                // const void*                  pNext;
1602                         0u,                                                                             // VkImageCreateFlags   flags;
1603                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1604                         m_params.dst.image.format,                              // VkFormat                             format;
1605                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
1606                         1u,                                                                             // deUint32                             mipLevels;
1607                         1u,                                                                             // deUint32                             arraySize;
1608                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1609                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1610                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1611                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1612                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1613                         1u,                                                                             // deUint32                             queueFamilyCount;
1614                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1615                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1616                 };
1617
1618                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1619                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1620                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1621         }
1622 }
1623
1624 tcu::TestStatus BlittingImages::iterate (void)
1625 {
1626         const tcu::TextureFormat        srcTcuFormat            = mapVkFormat(m_params.src.image.format);
1627         const tcu::TextureFormat        dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
1628         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1629                                                                                                                                                                 m_params.src.image.extent.width,
1630                                                                                                                                                                 m_params.src.image.extent.height,
1631                                                                                                                                                                 m_params.src.image.extent.depth));
1632         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);
1633         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1634                                                                                                                                                                          (int)m_params.dst.image.extent.width,
1635                                                                                                                                                                          (int)m_params.dst.image.extent.height,
1636                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
1637         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);
1638         generateExpectedResult();
1639
1640         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1641         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1642
1643         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
1644         const VkDevice                          vkDevice                        = m_context.getDevice();
1645         const VkQueue                           queue                           = m_context.getUniversalQueue();
1646
1647         std::vector<VkImageBlit>        regions;
1648         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1649                 regions.push_back(m_params.regions[i].imageBlit);
1650
1651         // Barriers for copying image to buffer
1652         const VkImageMemoryBarrier              srcImageBarrier         =
1653         {
1654                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1655                 DE_NULL,                                                                        // const void*                          pNext;
1656                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1657                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1658                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1659                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1660                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1661                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1662                 m_source.get(),                                                         // VkImage                                      image;
1663                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1664                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
1665                         0u,                                                             // deUint32                             baseMipLevel;
1666                         1u,                                                             // deUint32                             mipLevels;
1667                         0u,                                                             // deUint32                             baseArraySlice;
1668                         1u                                                              // deUint32                             arraySize;
1669                 }
1670         };
1671
1672         const VkImageMemoryBarrier              dstImageBarrier         =
1673         {
1674                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1675                 DE_NULL,                                                                        // const void*                          pNext;
1676                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1677                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
1678                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
1679                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
1680                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1681                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1682                 m_destination.get(),                                            // VkImage                                      image;
1683                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1684                         getAspectFlags(dstTcuFormat),   // VkImageAspectFlags   aspectMask;
1685                         0u,                                                             // deUint32                             baseMipLevel;
1686                         1u,                                                             // deUint32                             mipLevels;
1687                         0u,                                                             // deUint32                             baseArraySlice;
1688                         1u                                                              // deUint32                             arraySize;
1689                 }
1690         };
1691
1692         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
1693         {
1694                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1695                 DE_NULL,                                                                                                // const void*                                          pNext;
1696                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1697                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1698         };
1699
1700         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1701         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);
1702         vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
1703         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
1704         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1705
1706         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1707
1708         de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1709
1710         return checkTestResult(resultTextureLevel->getAccess());
1711 }
1712
1713 static float calculateFloatConversionError (int srcBits)
1714 {
1715         if (srcBits > 0)
1716         {
1717                 const int       clampedBits     = de::clamp<int>(srcBits, 0, 32);
1718                 const float     srcMaxValue     = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
1719                 const float     error           = 1.0f / srcMaxValue;
1720
1721                 return de::clamp<float>(error, 0.0f, 1.0f);
1722         }
1723         else
1724                 return 1.0f;
1725 }
1726
1727 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
1728 {
1729         tcu::Vec4 threshold(0.01f);
1730
1731         switch (format.type)
1732         {
1733         case tcu::TextureFormat::HALF_FLOAT:
1734                 threshold = tcu::Vec4(0.005f);
1735                 break;
1736
1737         case tcu::TextureFormat::FLOAT:
1738         case tcu::TextureFormat::FLOAT64:
1739                 threshold = tcu::Vec4(0.001f);
1740                 break;
1741
1742         case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
1743                 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
1744                 break;
1745
1746         case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
1747                 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
1748                 break;
1749
1750         default:
1751                 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
1752                 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
1753                                       calculateFloatConversionError(bits.y()),
1754                                       calculateFloatConversionError(bits.z()),
1755                                       calculateFloatConversionError(bits.w()));
1756         }
1757
1758         // Return value matching the channel order specified by the format
1759         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
1760                 return threshold.swizzle(2, 1, 0, 3);
1761         else
1762                 return threshold;
1763 }
1764
1765 tcu::TextureFormat getFormatAspect (VkFormat format, VkImageAspectFlagBits aspect)
1766 {
1767         const tcu::TextureFormat        baseFormat      = mapVkFormat(format);
1768
1769         if (isCombinedDepthStencilType(baseFormat.type))
1770         {
1771                 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1772                         return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_DEPTH);
1773                 else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1774                         return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_STENCIL);
1775                 else
1776                         DE_FATAL("Invalid aspect");
1777         }
1778
1779         return baseFormat;
1780 }
1781
1782 bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBufferAccess& result,
1783                                                                                                          const tcu::ConstPixelBufferAccess& clampedExpected,
1784                                                                                                          const tcu::ConstPixelBufferAccess& unclampedExpected,
1785                                                                                                          VkImageAspectFlagBits                          aspect)
1786 {
1787         tcu::TestLog&                           log                     (m_context.getTestContext().getLog());
1788         const bool                                      isLinear        = m_params.filter == VK_FILTER_LINEAR;
1789         const tcu::TextureFormat        srcFormat       = getFormatAspect(m_params.src.image.format, aspect);
1790         const tcu::TextureFormat        dstFormat       = result.getFormat();
1791         bool                                            isOk            = false;
1792
1793         DE_ASSERT(dstFormat == getFormatAspect(m_params.dst.image.format, aspect));
1794
1795         if (isLinear)
1796                 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
1797
1798         if (isFloatFormat(dstFormat))
1799         {
1800                 const bool              srcIsSRGB       = tcu::isSRGB(srcFormat);
1801                 const tcu::Vec4 srcMaxDiff      = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
1802                 const tcu::Vec4 dstMaxDiff      = getFormatThreshold(dstFormat);
1803                 const tcu::Vec4 threshold       = tcu::max(srcMaxDiff, dstMaxDiff);
1804
1805                 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1806
1807                 if (isLinear)
1808                         log << tcu::TestLog::EndSection;
1809
1810                 if (!isOk && isLinear)
1811                 {
1812                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
1813                         isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1814                         log << tcu::TestLog::EndSection;
1815                 }
1816         }
1817         else
1818         {
1819                 tcu::UVec4      threshold;
1820                 // Calculate threshold depending on channel width of destination format.
1821                 const tcu::IVec4        bitDepth        = tcu::getTextureFormatBitDepth(dstFormat);
1822                 for (deUint32 i = 0; i < 4; ++i)
1823                         threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
1824
1825                 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1826
1827                 if (isLinear)
1828                         log << tcu::TestLog::EndSection;
1829
1830                 if (!isOk && isLinear)
1831                 {
1832                         log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
1833                         isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1834                         log << tcu::TestLog::EndSection;
1835                 }
1836         }
1837         return isOk;
1838 }
1839
1840 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
1841 {
1842         DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
1843
1844         if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1845         {
1846                 if (tcu::hasDepthComponent(result.getFormat().order))
1847                 {
1848                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_DEPTH;
1849                         const tcu::ConstPixelBufferAccess               depthResult                     = tcu::getEffectiveDepthStencilAccess(result, mode);
1850                         const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1851                         const tcu::ConstPixelBufferAccess               unclampedExpected       = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
1852
1853                         if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT))
1854                         {
1855                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1856                         }
1857                 }
1858
1859                 if (tcu::hasStencilComponent(result.getFormat().order))
1860                 {
1861                         const tcu::Sampler::DepthStencilMode    mode                            = tcu::Sampler::MODE_STENCIL;
1862                         const tcu::ConstPixelBufferAccess               stencilResult           = tcu::getEffectiveDepthStencilAccess(result, mode);
1863                         const tcu::ConstPixelBufferAccess               clampedExpected         = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1864                         const tcu::ConstPixelBufferAccess               unclampedExpected       = m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
1865
1866                         if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT))
1867                         {
1868                                 return tcu::TestStatus::fail("CopiesAndBlitting test");
1869                         }
1870                 }
1871         }
1872         else
1873         {
1874                 if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT))
1875                 {
1876                         return tcu::TestStatus::fail("CopiesAndBlitting test");
1877                 }
1878         }
1879
1880         return tcu::TestStatus::pass("CopiesAndBlitting test");
1881 }
1882
1883 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
1884 {
1885         return isSRGB(format) ? linearToSRGB(color) : color;
1886 }
1887
1888 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
1889 {
1890         DE_ASSERT(filter == tcu::Sampler::LINEAR);
1891         DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
1892
1893         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
1894                                         filter, filter, 0.0f, false);
1895
1896         float sX = (float)regionExtent.x / (float)dst.getWidth();
1897         float sY = (float)regionExtent.y / (float)dst.getHeight();
1898
1899         for (int y = 0; y < dst.getHeight(); y++)
1900         for (int x = 0; x < dst.getWidth(); x++)
1901                 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);
1902 }
1903
1904 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
1905 {
1906         DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
1907
1908         tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
1909                                                  filter, filter, 0.0f, false);
1910
1911         const float sX = (float)src.getWidth() / (float)dst.getWidth();
1912         const float sY = (float)src.getHeight() / (float)dst.getHeight();
1913         const float sZ = (float)src.getDepth() / (float)dst.getDepth();
1914
1915         tcu::Mat2 rotMatrix;
1916         rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
1917         rotMatrix(0,1) = 0.0f;
1918         rotMatrix(1,0) = 0.0f;
1919         rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
1920
1921         const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
1922         const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
1923
1924         if (dst.getDepth() == 1 && src.getDepth() == 1)
1925         {
1926                 for (int y = 0; y < dst.getHeight(); ++y)
1927                 for (int x = 0; x < dst.getWidth(); ++x)
1928                 {
1929                         const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
1930                         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);
1931                 }
1932         }
1933         else
1934         {
1935                 for (int z = 0; z < dst.getDepth(); ++z)
1936                 for (int y = 0; y < dst.getHeight(); ++y)
1937                 for (int x = 0; x < dst.getWidth(); ++x)
1938                 {
1939                         const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
1940                         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);
1941                 }
1942         }
1943 }
1944
1945 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
1946 {
1947         const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
1948         const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
1949         const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
1950         const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
1951
1952         if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
1953         {
1954                 //sourceRegion
1955                 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
1956                 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
1957
1958                 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
1959                 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
1960
1961                 //destinationRegion
1962                 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
1963                 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
1964
1965                 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
1966                 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
1967         }
1968 }
1969
1970 MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
1971 {
1972         if (x1.x >= x2.x && x1.y >= x2.y)
1973         {
1974                 return MIRROR_MODE_XY;
1975         }
1976         else if (x1.x <= x2.x && x1.y <= x2.y)
1977         {
1978                 return MIRROR_MODE_NONE;
1979         }
1980         else if (x1.x <= x2.x && x1.y >= x2.y)
1981         {
1982                 return MIRROR_MODE_Y;
1983         }
1984         else if (x1.x >= x2.x && x1.y <= x2.y)
1985         {
1986                 return MIRROR_MODE_X;
1987         }
1988         return MIRROR_MODE_LAST;
1989 }
1990
1991 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
1992 {
1993         const MirrorMode source          = getMirrorMode(s1, s2);
1994         const MirrorMode destination = getMirrorMode(d1, d2);
1995
1996         if (source == destination)
1997         {
1998                 return MIRROR_MODE_NONE;
1999         }
2000         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
2001                          (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
2002         {
2003                 return MIRROR_MODE_Y;
2004         }
2005         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)       || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
2006                          (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
2007         {
2008                 return MIRROR_MODE_X;
2009         }
2010         else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
2011         {
2012                 return MIRROR_MODE_XY;
2013         }
2014         return MIRROR_MODE_LAST;
2015 }
2016
2017 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
2018 {
2019         const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
2020                                                                                                 region.imageBlit.srcOffsets[1],
2021                                                                                                 region.imageBlit.dstOffsets[0],
2022                                                                                                 region.imageBlit.dstOffsets[1]);
2023
2024         flipCoordinates(region, mirrorMode);
2025
2026         const VkOffset3D                                        srcOffset               = region.imageBlit.srcOffsets[0];
2027         const VkOffset3D                                        srcExtent               =
2028         {
2029                 region.imageBlit.srcOffsets[1].x - srcOffset.x,
2030                 region.imageBlit.srcOffsets[1].y - srcOffset.y,
2031                 region.imageBlit.srcOffsets[1].z - srcOffset.z
2032         };
2033         const VkOffset3D                                        dstOffset               = region.imageBlit.dstOffsets[0];
2034         const VkOffset3D                                        dstExtent               =
2035         {
2036                 region.imageBlit.dstOffsets[1].x - dstOffset.x,
2037                 region.imageBlit.dstOffsets[1].y - dstOffset.y,
2038                 region.imageBlit.dstOffsets[1].z - dstOffset.z
2039         };
2040         const tcu::Sampler::FilterMode          filter                  = (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
2041
2042         if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2043         {
2044                 DE_ASSERT(src.getFormat() == dst.getFormat());
2045                 // Scale depth.
2046                 if (tcu::hasDepthComponent(src.getFormat().order))
2047                 {
2048                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
2049                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2050                         tcu::scale(dstSubRegion, srcSubRegion, filter);
2051
2052                         if (filter == tcu::Sampler::LINEAR)
2053                         {
2054                                 const tcu::ConstPixelBufferAccess       depthSrc                        = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
2055                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2056                                 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
2057                         }
2058                 }
2059
2060                 // Scale stencil.
2061                 if (tcu::hasStencilComponent(src.getFormat().order))
2062                 {
2063                         const tcu::ConstPixelBufferAccess       srcSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
2064                         const tcu::PixelBufferAccess            dstSubRegion    = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2065                         blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2066
2067                         if (filter == tcu::Sampler::LINEAR)
2068                         {
2069                                 const tcu::ConstPixelBufferAccess       stencilSrc                      = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
2070                                 const tcu::PixelBufferAccess            unclampedSubRegion      = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2071                                 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
2072                         }
2073                 }
2074         }
2075         else
2076         {
2077                 const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
2078                 const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2079                 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2080
2081                 if (filter == tcu::Sampler::LINEAR)
2082                 {
2083                         const tcu::PixelBufferAccess    unclampedSubRegion      = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2084                         scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter);
2085                 }
2086         }
2087 }
2088
2089 void BlittingImages::generateExpectedResult (void)
2090 {
2091         const tcu::ConstPixelBufferAccess       src     = m_sourceTextureLevel->getAccess();
2092         const tcu::ConstPixelBufferAccess       dst     = m_destinationTextureLevel->getAccess();
2093
2094         m_expectedTextureLevel                  = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2095         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
2096
2097         if (m_params.filter == VK_FILTER_LINEAR)
2098         {
2099                 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2100                 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
2101         }
2102
2103         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2104         {
2105                 CopyRegion region = m_params.regions[i];
2106                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), region);
2107         }
2108 }
2109
2110 class BlittingTestCase : public vkt::TestCase
2111 {
2112 public:
2113                                                         BlittingTestCase                (tcu::TestContext&                              testCtx,
2114                                                                                                          const std::string&                             name,
2115                                                                                                          const std::string&                             description,
2116                                                                                                          const TestParams                               params)
2117                                                                 : vkt::TestCase (testCtx, name, description)
2118                                                                 , m_params              (params)
2119                                                         {}
2120
2121         virtual TestInstance*   createInstance                  (Context&                                               context) const
2122                                                         {
2123                                                                 return new BlittingImages(context, m_params);
2124                                                         }
2125 private:
2126         TestParams                              m_params;
2127 };
2128
2129 // Resolve image to image.
2130
2131 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
2132 class ResolveImageToImage : public CopiesAndBlittingTestInstance
2133 {
2134 public:
2135                                                                                                 ResolveImageToImage                     (Context&                                                       context,
2136                                                                                                                                                          TestParams                                                     params,
2137                                                                                                                                                          const ResolveImageToImageOptions       options);
2138         virtual tcu::TestStatus                                         iterate                                         (void);
2139 protected:
2140         virtual tcu::TestStatus                                         checkTestResult                         (tcu::ConstPixelBufferAccess result);
2141         void                                                                            copyMSImageToMSImage            (void);
2142 private:
2143         Move<VkImage>                                                           m_multisampledImage;
2144         de::MovePtr<Allocation>                                         m_multisampledImageAlloc;
2145
2146         Move<VkImage>                                                           m_destination;
2147         de::MovePtr<Allocation>                                         m_destinationImageAlloc;
2148
2149         Move<VkImage>                                                           m_multisampledCopyImage;
2150         de::MovePtr<Allocation>                                         m_multisampledCopyImageAlloc;
2151
2152         const ResolveImageToImageOptions                        m_options;
2153
2154         virtual void                                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess    src,
2155                                                                                                                                                          tcu::PixelBufferAccess                 dst,
2156                                                                                                                                                          CopyRegion                                             region);
2157 };
2158
2159 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
2160         : CopiesAndBlittingTestInstance (context, params)
2161         , m_options                                             (options)
2162 {
2163         const VkSampleCountFlagBits     rasterizationSamples    = m_params.samples;
2164
2165         if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
2166                 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2167
2168         const DeviceInterface&          vk                                              = context.getDeviceInterface();
2169         const VkDevice                          vkDevice                                = context.getDevice();
2170         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
2171         Allocator&                                      memAlloc                                = m_context.getDefaultAllocator();
2172
2173         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2174         Move<VkRenderPass>                      renderPass;
2175
2176         Move<VkShaderModule>            vertexShaderModule              = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2177         Move<VkShaderModule>            fragmentShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2178         std::vector<tcu::Vec4>          vertices;
2179
2180         Move<VkBuffer>                          vertexBuffer;
2181         de::MovePtr<Allocation>         vertexBufferAlloc;
2182
2183         Move<VkPipelineLayout>          pipelineLayout;
2184         Move<VkPipeline>                        graphicsPipeline;
2185
2186         VkImageFormatProperties properties;
2187         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2188                                                                                                                                                                 m_params.src.image.format,
2189                                                                                                                                                                 m_params.src.image.imageType,
2190                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
2191                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2192                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2193                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2194                                                                                                                                                                 m_params.dst.image.format,
2195                                                                                                                                                                 m_params.dst.image.imageType,
2196                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
2197                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
2198                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2199         {
2200                 TCU_THROW(NotSupportedError, "Format not supported");
2201         }
2202
2203         // Create color image.
2204         {
2205                 VkImageCreateInfo       colorImageParams        =
2206                 {
2207                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                    // VkStructureType                      sType;
2208                         DE_NULL,                                                                                                                                // const void*                          pNext;
2209                         0u,                                                                                                                                             // VkImageCreateFlags           flags;
2210                         m_params.src.image.imageType,                                                                                   // VkImageType                          imageType;
2211                         m_params.src.image.format,                                                                                              // VkFormat                                     format;
2212                         getExtent3D(m_params.src.image),                                                                                // VkExtent3D                           extent;
2213                         1u,                                                                                                                                             // deUint32                                     mipLevels;
2214                         getArraySize(m_params.src.image),                                                                               // deUint32                                     arrayLayers;
2215                         rasterizationSamples,                                                                                                   // VkSampleCountFlagBits        samples;
2216                         VK_IMAGE_TILING_OPTIMAL,                                                                                                // VkImageTiling                        tiling;
2217                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,  // VkImageUsageFlags            usage;
2218                         VK_SHARING_MODE_EXCLUSIVE,                                                                                              // VkSharingMode                        sharingMode;
2219                         1u,                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
2220                         &queueFamilyIndex,                                                                                                              // const deUint32*                      pQueueFamilyIndices;
2221                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout                        initialLayout;
2222                 };
2223
2224                 m_multisampledImage                             = createImage(vk, vkDevice, &colorImageParams);
2225
2226                 // Allocate and bind color image memory.
2227                 m_multisampledImageAlloc                = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage), MemoryRequirement::Any);
2228                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
2229
2230                 switch (m_options)
2231                 {
2232                         case COPY_MS_IMAGE_TO_MS_IMAGE:
2233                         {
2234                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2235                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
2236                                 // Allocate and bind color image memory.
2237                                 m_multisampledCopyImageAlloc    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
2238                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2239                                 break;
2240                         }
2241
2242                         case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
2243                         {
2244                                 colorImageParams.usage                  = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2245                                 colorImageParams.arrayLayers    = getArraySize(m_params.dst.image);
2246                                 m_multisampledCopyImage                 = createImage(vk, vkDevice, &colorImageParams);
2247                                 // Allocate and bind color image memory.
2248                                 m_multisampledCopyImageAlloc    = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
2249                                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2250                                 break;
2251                         }
2252
2253                         default :
2254                                 break;
2255                 }
2256         }
2257
2258         // Create destination image.
2259         {
2260                 const VkImageCreateInfo destinationImageParams  =
2261                 {
2262                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
2263                         DE_NULL,                                                                // const void*                  pNext;
2264                         0u,                                                                             // VkImageCreateFlags   flags;
2265                         m_params.dst.image.imageType,                   // VkImageType                  imageType;
2266                         m_params.dst.image.format,                              // VkFormat                             format;
2267                         getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
2268                         1u,                                                                             // deUint32                             mipLevels;
2269                         getArraySize(m_params.dst.image),               // deUint32                             arraySize;
2270                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
2271                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
2272                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2273                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
2274                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
2275                         1u,                                                                             // deUint32                             queueFamilyCount;
2276                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
2277                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
2278                 };
2279
2280                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
2281                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
2282                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2283         }
2284
2285         // Barriers for copying image to buffer
2286         VkImageMemoryBarrier            srcImageBarrier         =
2287         {
2288                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2289                 DE_NULL,                                                                        // const void*                          pNext;
2290                 0u,                                                                                     // VkAccessFlags                        srcAccessMask;
2291                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
2292                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
2293                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
2294                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2295                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2296                 m_multisampledImage.get(),                                      // VkImage                                      image;
2297                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2298                         VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask;
2299                         0u,                                                                     // deUint32                             baseMipLevel;
2300                         1u,                                                                     // deUint32                             mipLevels;
2301                         0u,                                                                     // deUint32                             baseArraySlice;
2302                         getArraySize(m_params.src.image)        // deUint32                             arraySize;
2303                 }
2304         };
2305
2306                 // Create render pass.
2307         {
2308                 const VkAttachmentDescription   attachmentDescriptions[1]       =
2309                 {
2310                         {
2311                                 0u,                                                                                     // VkAttachmentDescriptionFlags         flags;
2312                                 m_params.src.image.format,                                      // VkFormat                                                     format;
2313                                 rasterizationSamples,                                           // VkSampleCountFlagBits                        samples;
2314                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
2315                                 VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
2316                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
2317                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
2318                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
2319                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
2320                         },
2321                 };
2322
2323                 const VkAttachmentReference             colorAttachmentReference        =
2324                 {
2325                         0u,                                                                                                     // deUint32                     attachment;
2326                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
2327                 };
2328
2329                 const VkSubpassDescription              subpassDescription                      =
2330                 {
2331                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
2332                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
2333                         0u,                                                                     // deUint32                                             inputAttachmentCount;
2334                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
2335                         1u,                                                                     // deUint32                                             colorAttachmentCount;
2336                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
2337                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
2338                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
2339                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
2340                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
2341                 };
2342
2343                 const VkRenderPassCreateInfo    renderPassParams                        =
2344                 {
2345                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
2346                         DE_NULL,                                                                        // const void*                                          pNext;
2347                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
2348                         1u,                                                                                     // deUint32                                                     attachmentCount;
2349                         attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments;
2350                         1u,                                                                                     // deUint32                                                     subpassCount;
2351                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
2352                         0u,                                                                                     // deUint32                                                     dependencyCount;
2353                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
2354                 };
2355
2356                 renderPass      = createRenderPass(vk, vkDevice, &renderPassParams);
2357         }
2358
2359         // Create pipeline layout
2360         {
2361                 const VkPipelineLayoutCreateInfo        pipelineLayoutParams    =
2362                 {
2363                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
2364                         DE_NULL,                                                                                        // const void*                                          pNext;
2365                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
2366                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
2367                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
2368                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
2369                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
2370                 };
2371
2372                 pipelineLayout  = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2373         }
2374
2375         {
2376                 const tcu::Vec4 a       (-1.0, -1.0, 0.0, 1.0);
2377                 const tcu::Vec4 b       (1.0, -1.0, 0.0, 1.0);
2378                 const tcu::Vec4 c       (1.0, 1.0, 0.0, 1.0);
2379                 // Add triangle.
2380                 vertices.push_back(a);
2381                 vertices.push_back(c);
2382                 vertices.push_back(b);
2383         }
2384
2385         // Create vertex buffer.
2386         {
2387                 const VkDeviceSize                      vertexDataSize          = vertices.size() * sizeof(tcu::Vec4);
2388                 const VkBufferCreateInfo        vertexBufferParams      =
2389                 {
2390                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
2391                         DE_NULL,                                                                        // const void*                  pNext;
2392                         0u,                                                                                     // VkBufferCreateFlags  flags;
2393                         vertexDataSize,                                                         // VkDeviceSize                 size;
2394                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
2395                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
2396                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
2397                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
2398                 };
2399
2400                 vertexBuffer            = createBuffer(vk, vkDevice, &vertexBufferParams);
2401                 vertexBufferAlloc       = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
2402
2403                 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
2404
2405                 // Load vertices into vertex buffer.
2406                 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
2407                 flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize);
2408         }
2409
2410         {
2411                 Move<VkFramebuffer>             framebuffer;
2412                 Move<VkImageView>               sourceAttachmentView;
2413                 const VkExtent3D                extent3D = getExtent3D(m_params.src.image);
2414
2415                 // Create color attachment view.
2416                 {
2417                         const VkImageViewCreateInfo     colorAttachmentViewParams       =
2418                         {
2419                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType;
2420                                 DE_NULL,                                                                                                // const void*                          pNext;
2421                                 0u,                                                                                                             // VkImageViewCreateFlags       flags;
2422                                 *m_multisampledImage,                                                                   // VkImage                                      image;
2423                                 VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType;
2424                                 m_params.src.image.format,                                                              // VkFormat                                     format;
2425                                 componentMappingRGBA,                                                                   // VkComponentMapping           components;
2426                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
2427                         };
2428                         sourceAttachmentView    = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2429                 }
2430
2431                 // Create framebuffer
2432                 {
2433                         const VkImageView                               attachments[1]          =
2434                         {
2435                                 *sourceAttachmentView,
2436                         };
2437
2438                         const VkFramebufferCreateInfo   framebufferParams       =
2439                         {
2440                                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                              sType;
2441                                 DE_NULL,                                                                        // const void*                                  pNext;
2442                                 0u,                                                                                     // VkFramebufferCreateFlags             flags;
2443                                 *renderPass,                                                            // VkRenderPass                                 renderPass;
2444                                 1u,                                                                                     // deUint32                                             attachmentCount;
2445                                 attachments,                                                            // const VkImageView*                   pAttachments;
2446                                 extent3D.width,                                                         // deUint32                                             width;
2447                                 extent3D.height,                                                        // deUint32                                             height;
2448                                 1u                                                                                      // deUint32                                             layers;
2449                         };
2450
2451                         framebuffer     = createFramebuffer(vk, vkDevice, &framebufferParams);
2452                 }
2453
2454                 // Create pipeline
2455                 {
2456                         const VkPipelineShaderStageCreateInfo                   shaderStageParams[2]                            =
2457                         {
2458                                 {
2459                                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2460                                         DE_NULL,                                                                                                        // const void*                                                  pNext;
2461                                         0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
2462                                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
2463                                         *vertexShaderModule,                                                                            // VkShaderModule                                               module;
2464                                         "main",                                                                                                         // const char*                                                  pName;
2465                                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2466                                 },
2467                                 {
2468                                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
2469                                         DE_NULL,                                                                                                        // const void*                                                  pNext;
2470                                         0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
2471                                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
2472                                         *fragmentShaderModule,                                                                          // VkShaderModule                                               module;
2473                                         "main",                                                                                                         // const char*                                                  pName;
2474                                         DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
2475                                 }
2476                         };
2477
2478                         const VkVertexInputBindingDescription                   vertexInputBindingDescription           =
2479                         {
2480                                 0u,                                                                     // deUint32                             binding;
2481                                 sizeof(tcu::Vec4),                                      // deUint32                             stride;
2482                                 VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
2483                         };
2484
2485                         const VkVertexInputAttributeDescription                 vertexInputAttributeDescriptions[1]     =
2486                         {
2487                                 {
2488                                         0u,                                                                     // deUint32     location;
2489                                         0u,                                                                     // deUint32     binding;
2490                                         VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
2491                                         0u                                                                      // deUint32     offset;
2492                                 }
2493                         };
2494
2495                         const VkPipelineVertexInputStateCreateInfo              vertexInputStateParams                          =
2496                         {
2497                                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
2498                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2499                                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
2500                                 1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
2501                                 &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
2502                                 1u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
2503                                 vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
2504                         };
2505
2506                         const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams                        =
2507                         {
2508                                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
2509                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2510                                 0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
2511                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
2512                                 false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
2513                         };
2514
2515                         const VkViewport        viewport        =
2516                         {
2517                                 0.0f,                                                   // float        x;
2518                                 0.0f,                                                   // float        y;
2519                                 (float)extent3D.width,  // float        width;
2520                                 (float)extent3D.height, // float        height;
2521                                 0.0f,                                                   // float        minDepth;
2522                                 1.0f                                                    // float        maxDepth;
2523                         };
2524
2525                         const VkRect2D          scissor         =
2526                         {
2527                                 { 0, 0 },                                                                               // VkOffset2D   offset;
2528                                 { extent3D.width, extent3D.height }     // VkExtent2D   extent;
2529                         };
2530
2531                         const VkPipelineViewportStateCreateInfo                 viewportStateParams             =
2532                         {
2533                                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
2534                                 DE_NULL,                                                                                                                // const void*                                                  pNext;
2535                                 0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
2536                                 1u,                                                                                                                             // deUint32                                                             viewportCount;
2537                                 &viewport,                                                                                                              // const VkViewport*                                    pViewports;
2538                                 1u,                                                                                                                             // deUint32                                                             scissorCount;
2539                                 &scissor                                                                                                                // const VkRect2D*                                              pScissors;
2540                         };
2541
2542                         const VkPipelineRasterizationStateCreateInfo    rasterStateParams               =
2543                         {
2544                                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
2545                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2546                                 0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
2547                                 false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
2548                                 false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
2549                                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
2550                                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
2551                                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
2552                                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
2553                                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
2554                                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
2555                                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
2556                                 1.0f                                                                                                                    // float                                                                        lineWidth;
2557                         };
2558
2559                         const VkPipelineMultisampleStateCreateInfo      multisampleStateParams          =
2560                         {
2561                                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
2562                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2563                                 0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
2564                                 rasterizationSamples,                                                                                   // VkSampleCountFlagBits                                        rasterizationSamples;
2565                                 VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
2566                                 0.0f,                                                                                                                   // float                                                                        minSampleShading;
2567                                 DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
2568                                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
2569                                 VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
2570                         };
2571
2572                         const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState       =
2573                         {
2574                                 false,                                                                                                          // VkBool32                     blendEnable;
2575                                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendColor;
2576                                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendColor;
2577                                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpColor;
2578                                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendAlpha;
2579                                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendAlpha;
2580                                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpAlpha;
2581                                 (VK_COLOR_COMPONENT_R_BIT |
2582                                  VK_COLOR_COMPONENT_G_BIT |
2583                                  VK_COLOR_COMPONENT_B_BIT |
2584                                  VK_COLOR_COMPONENT_A_BIT)                                                                      // VkChannelFlags       channelWriteMask;
2585                         };
2586
2587                         const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams   =
2588                         {
2589                                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
2590                                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
2591                                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
2592                                 false,                                                                                                          // VkBool32                                                                             logicOpEnable;
2593                                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
2594                                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
2595                                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
2596                                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
2597                         };
2598
2599                         const VkGraphicsPipelineCreateInfo                      graphicsPipelineParams  =
2600                         {
2601                                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
2602                                 DE_NULL,                                                                                        // const void*                                                                          pNext;
2603                                 0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
2604                                 2u,                                                                                                     // deUint32                                                                                     stageCount;
2605                                 shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
2606                                 &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
2607                                 &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
2608                                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
2609                                 &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
2610                                 &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
2611                                 &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
2612                                 DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
2613                                 &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
2614                                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
2615                                 *pipelineLayout,                                                                        // VkPipelineLayout                                                                     layout;
2616                                 *renderPass,                                                                            // VkRenderPass                                                                         renderPass;
2617                                 0u,                                                                                                     // deUint32                                                                                     subpass;
2618                                 0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
2619                                 0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
2620                         };
2621
2622                         graphicsPipeline        = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2623                 }
2624
2625                 // Create command buffer
2626                 {
2627                         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2628                         {
2629                                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
2630                                 DE_NULL,                                                                                // const void*                                          pNext;
2631                                 0u,                                                                                             // VkCommandBufferUsageFlags            flags;
2632                                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2633                         };
2634
2635                         const VkClearValue clearValues[1] =
2636                         {
2637                                 makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
2638                         };
2639
2640                         const VkRenderPassBeginInfo renderPassBeginInfo =
2641                         {
2642                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2643                                 DE_NULL,                                                                                                // const void*                  pNext;
2644                                 *renderPass,                                                                                    // VkRenderPass                 renderPass;
2645                                 *framebuffer,                                                                                   // VkFramebuffer                framebuffer;
2646                                 {
2647                                         { 0, 0 },
2648                                         { extent3D.width, extent3D.height }
2649                                 },                                                                                                              // VkRect2D                             renderArea;
2650                                 1u,                                                                                                             // deUint32                             clearValueCount;
2651                                 clearValues                                                                                             // const VkClearValue*  pClearValues;
2652                         };
2653
2654                         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2655                         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);
2656                         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2657                         const VkDeviceSize      vertexBufferOffset      = 0u;
2658
2659                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2660                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
2661                                 vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
2662
2663                         vk.cmdEndRenderPass(*m_cmdBuffer);
2664                         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2665                 }
2666
2667                 // Queue submit.
2668                 {
2669                         const VkQueue   queue   = m_context.getUniversalQueue();
2670                         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2671                 }
2672         }
2673 }
2674
2675 tcu::TestStatus ResolveImageToImage::iterate (void)
2676 {
2677         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
2678         const tcu::TextureFormat                dstTcuFormat            = mapVkFormat(m_params.dst.image.format);
2679
2680         // upload the destination image
2681                 m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
2682                                                                                                                                                                 (int)m_params.dst.image.extent.width,
2683                                                                                                                                                                 (int)m_params.dst.image.extent.height,
2684                                                                                                                                                                 (int)m_params.dst.image.extent.depth));
2685                 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2686                 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
2687
2688                 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
2689                                                                                                                                                 (int)m_params.src.image.extent.width,
2690                                                                                                                                                 (int)m_params.src.image.extent.height,
2691                                                                                                                                                 (int)m_params.dst.image.extent.depth));
2692
2693                 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);
2694                 generateExpectedResult();
2695
2696         switch (m_options)
2697         {
2698                 case COPY_MS_IMAGE_TO_MS_IMAGE:
2699                 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
2700                         copyMSImageToMSImage();
2701                         break;
2702                 default:
2703                         break;
2704         }
2705
2706         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
2707         const VkDevice                                  vkDevice                        = m_context.getDevice();
2708         const VkQueue                                   queue                           = m_context.getUniversalQueue();
2709
2710         std::vector<VkImageResolve>             imageResolves;
2711         for (deUint32 i = 0; i < m_params.regions.size(); i++)
2712                 imageResolves.push_back(m_params.regions[i].imageResolve);
2713
2714         const VkImageMemoryBarrier      imageBarriers[]         =
2715         {
2716                 // source image
2717                 {
2718                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2719                         DE_NULL,                                                                        // const void*                          pNext;
2720                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
2721                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
2722                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
2723                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
2724                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2725                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2726                         m_multisampledImage.get(),                                      // VkImage                                      image;
2727                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
2728                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
2729                                 0u,                                                                     // deUint32                             baseMipLevel;
2730                                 1u,                                                                     // deUint32                             mipLevels;
2731                                 0u,                                                                     // deUint32                             baseArraySlice;
2732                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
2733                         }
2734                 },
2735                 // destination image
2736                 {
2737                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2738                         DE_NULL,                                                                        // const void*                          pNext;
2739                         0u,                                                                                     // VkAccessFlags                        srcAccessMask;
2740                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2741                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
2742                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2743                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2744                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2745                         m_destination.get(),                                            // VkImage                                      image;
2746                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
2747                                 getAspectFlags(dstTcuFormat),           // VkImageAspectFlags   aspectMask;
2748                                 0u,                                                                     // deUint32                             baseMipLevel;
2749                                 1u,                                                                     // deUint32                             mipLevels;
2750                                 0u,                                                                     // deUint32                             baseArraySlice;
2751                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
2752                         }
2753                 },
2754         };
2755
2756         const VkImageMemoryBarrier postImageBarrier =
2757         {
2758                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
2759                 DE_NULL,                                                                // const void*                          pNext;
2760                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask;
2761                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
2762                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        oldLayout;
2763                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
2764                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
2765                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
2766                 m_destination.get(),                                    // VkImage                                      image;
2767                         {                                                                       // VkImageSubresourceRange      subresourceRange;
2768                                 getAspectFlags(dstTcuFormat),   // VkImageAspectFlags           aspectMask;
2769                                 0u,                                                             // deUint32                                     baseMipLevel;
2770                                 1u,                                                             // deUint32                                     mipLevels;
2771                                 0u,                                                             // deUint32                                     baseArraySlice;
2772                                 getArraySize(m_params.dst.image)// deUint32                                     arraySize;
2773                         }
2774         };
2775
2776         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
2777         {
2778                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
2779                 DE_NULL,                                                                                                // const void*                                          pNext;
2780                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
2781                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2782         };
2783
2784         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2785         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);
2786         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());
2787         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);
2788         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2789
2790         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2791
2792         // check the result of resolving image
2793         {
2794                 de::MovePtr<tcu::TextureLevel>  resultTextureLevel      = readImage(*m_destination, m_params.dst.image);
2795
2796                 if (QP_TEST_RESULT_PASS != checkTestResult(resultTextureLevel->getAccess()).getCode())
2797                         return tcu::TestStatus::fail("CopiesAndBlitting test");
2798         }
2799         return tcu::TestStatus::pass("CopiesAndBlitting test");
2800 }
2801
2802 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
2803 {
2804         const tcu::ConstPixelBufferAccess       expected                = m_expectedTextureLevel->getAccess();
2805         const float                                                     fuzzyThreshold  = 0.01f;
2806
2807         for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
2808         {
2809                 const tcu::ConstPixelBufferAccess       expectedSub     = getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
2810                 const tcu::ConstPixelBufferAccess       resultSub       = getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
2811                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
2812                         return tcu::TestStatus::fail("CopiesAndBlitting test");
2813         }
2814
2815         return tcu::TestStatus::pass("CopiesAndBlitting test");
2816 }
2817
2818 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
2819 {
2820         VkOffset3D srcOffset    = region.imageResolve.srcOffset;
2821                         srcOffset.z             = region.imageResolve.srcSubresource.baseArrayLayer;
2822         VkOffset3D dstOffset    = region.imageResolve.dstOffset;
2823                         dstOffset.z             = region.imageResolve.dstSubresource.baseArrayLayer;
2824         VkExtent3D extent               = region.imageResolve.extent;
2825
2826         const tcu::ConstPixelBufferAccess       srcSubRegion            = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
2827         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
2828         const tcu::PixelBufferAccess            dstWithSrcFormat        (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
2829         const tcu::PixelBufferAccess            dstSubRegion            = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
2830
2831         tcu::copy(dstSubRegion, srcSubRegion);
2832 }
2833
2834 void ResolveImageToImage::copyMSImageToMSImage (void)
2835 {
2836         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
2837         const VkDevice                                  vkDevice                        = m_context.getDevice();
2838         const VkQueue                                   queue                           = m_context.getUniversalQueue();
2839         const tcu::TextureFormat                srcTcuFormat            = mapVkFormat(m_params.src.image.format);
2840         std::vector<VkImageCopy>                imageCopies;
2841
2842         for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx)
2843         {
2844                 const VkImageSubresourceLayers  sourceSubresourceLayers =
2845                 {
2846                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;
2847                         0u,                                                             // uint32_t                             mipLevel;
2848                         0u,                                                             // uint32_t                             baseArrayLayer;
2849                         1u                                                              // uint32_t                             layerCount;
2850                 };
2851
2852                 const VkImageSubresourceLayers  destinationSubresourceLayers    =
2853                 {
2854                         getAspectFlags(srcTcuFormat),   // VkImageAspectFlags   aspectMask;//getAspectFlags(dstTcuFormat)
2855                         0u,                                                             // uint32_t                             mipLevel;
2856                         layerNdx,                                               // uint32_t                             baseArrayLayer;
2857                         1u                                                              // uint32_t                             layerCount;
2858                 };
2859
2860                 const VkImageCopy                               imageCopy       =
2861                 {
2862                         sourceSubresourceLayers,                        // VkImageSubresourceLayers     srcSubresource;
2863                         {0, 0, 0},                                                      // VkOffset3D                           srcOffset;
2864                         destinationSubresourceLayers,           // VkImageSubresourceLayers     dstSubresource;
2865                         {0, 0, 0},                                                      // VkOffset3D                           dstOffset;
2866                          getExtent3D(m_params.src.image),       // VkExtent3D                           extent;
2867                 };
2868                 imageCopies.push_back(imageCopy);
2869         }
2870
2871         const VkImageMemoryBarrier              imageBarriers[]         =
2872         {
2873                 //// source image
2874                 {
2875                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2876                         DE_NULL,                                                                        // const void*                          pNext;
2877                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        srcAccessMask;
2878                         VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
2879                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        oldLayout;
2880                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
2881                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2882                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2883                         m_multisampledImage.get(),                                      // VkImage                                      image;
2884                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
2885                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
2886                                 0u,                                                                     // deUint32                             baseMipLevel;
2887                                 1u,                                                                     // deUint32                             mipLevels;
2888                                 0u,                                                                     // deUint32                             baseArraySlice;
2889                                 getArraySize(m_params.src.image)        // deUint32                             arraySize;
2890                         }
2891                 },
2892                 // destination image
2893                 {
2894                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2895                         DE_NULL,                                                                        // const void*                          pNext;
2896                         0,                                                                                      // VkAccessFlags                        srcAccessMask;
2897                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
2898                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                        oldLayout;
2899                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
2900                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2901                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2902                         m_multisampledCopyImage.get(),                          // VkImage                                      image;
2903                         {                                                                                       // VkImageSubresourceRange      subresourceRange;
2904                                 getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
2905                                 0u,                                                                     // deUint32                             baseMipLevel;
2906                                 1u,                                                                     // deUint32                             mipLevels;
2907                                 0u,                                                                     // deUint32                             baseArraySlice;
2908                                 getArraySize(m_params.dst.image)        // deUint32                             arraySize;
2909                         }
2910                 },
2911         };
2912
2913         const VkImageMemoryBarrier      postImageBarriers               =
2914         // source image
2915         {
2916                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
2917                 DE_NULL,                                                                        // const void*                          pNext;
2918                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
2919                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
2920                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
2921                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
2922                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
2923                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
2924                 m_multisampledCopyImage.get(),                          // VkImage                                      image;
2925                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
2926                         getAspectFlags(srcTcuFormat),           // VkImageAspectFlags   aspectMask;
2927                         0u,                                                                     // deUint32                             baseMipLevel;
2928                         1u,                                                                     // deUint32                             mipLevels;
2929                         0u,                                                                     // deUint32                             baseArraySlice;
2930                         getArraySize(m_params.dst.image)        // deUint32                             arraySize;
2931                 }
2932         };
2933
2934         const VkCommandBufferBeginInfo  cmdBufferBeginInfo      =
2935         {
2936                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
2937                 DE_NULL,                                                                                                // const void*                                          pNext;
2938                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
2939                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
2940         };
2941
2942         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2943         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);
2944         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());
2945         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);
2946         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2947
2948         submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2949
2950         m_multisampledImage = m_multisampledCopyImage;
2951 }
2952
2953 class ResolveImageToImageTestCase : public vkt::TestCase
2954 {
2955 public:
2956                                                         ResolveImageToImageTestCase     (tcu::TestContext&                                      testCtx,
2957                                                                                                                  const std::string&                                     name,
2958                                                                                                                  const std::string&                                     description,
2959                                                                                                                  const TestParams                                       params,
2960                                                                                                                  const ResolveImageToImageOptions       options = NO_OPTIONAL_OPERATION)
2961                                                                 : vkt::TestCase (testCtx, name, description)
2962                                                                 , m_params              (params)
2963                                                                 , m_options             (options)
2964                                                         {}
2965         virtual void                    initPrograms                            (SourceCollections&             programCollection) const;
2966
2967         virtual TestInstance*   createInstance                          (Context&                               context) const
2968                                                         {
2969                                                                 return new ResolveImageToImage(context, m_params, m_options);
2970                                                         }
2971 private:
2972         TestParams                                                      m_params;
2973         const ResolveImageToImageOptions        m_options;
2974 };
2975
2976 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
2977 {
2978         programCollection.glslSources.add("vert") << glu::VertexSource(
2979                 "#version 310 es\n"
2980                 "layout (location = 0) in highp vec4 a_position;\n"
2981                 "void main()\n"
2982                 "{\n"
2983                 "       gl_Position = a_position;\n"
2984                 "}\n");
2985
2986         programCollection.glslSources.add("frag") << glu::FragmentSource(
2987                 "#version 310 es\n"
2988                 "layout (location = 0) out highp vec4 o_color;\n"
2989                 "void main()\n"
2990                 "{\n"
2991                 "       o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2992                 "}\n");
2993 }
2994
2995 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
2996 {
2997         return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
2998 }
2999
3000 std::string getFormatCaseName (VkFormat format)
3001 {
3002         return de::toLower(de::toString(getFormatStr(format)).substr(10));
3003 }
3004
3005 void addCopyImageTestsAllFormats (tcu::TestCaseGroup*   testCaseGroup,
3006                                                                   tcu::TestContext&             testCtx,
3007                                                                   TestParams&                   params)
3008 {
3009         const VkFormat  compatibleFormats8Bit[]                 =
3010         {
3011                 VK_FORMAT_R4G4_UNORM_PACK8,
3012                 VK_FORMAT_R8_UNORM,
3013                 VK_FORMAT_R8_SNORM,
3014                 VK_FORMAT_R8_USCALED,
3015                 VK_FORMAT_R8_SSCALED,
3016                 VK_FORMAT_R8_UINT,
3017                 VK_FORMAT_R8_SINT,
3018                 VK_FORMAT_R8_SRGB,
3019
3020                 VK_FORMAT_UNDEFINED
3021         };
3022         const VkFormat  compatibleFormats16Bit[]                =
3023         {
3024                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3025                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3026                 VK_FORMAT_R5G6B5_UNORM_PACK16,
3027                 VK_FORMAT_B5G6R5_UNORM_PACK16,
3028                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3029                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3030                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3031                 VK_FORMAT_R8G8_UNORM,
3032                 VK_FORMAT_R8G8_SNORM,
3033                 VK_FORMAT_R8G8_USCALED,
3034                 VK_FORMAT_R8G8_SSCALED,
3035                 VK_FORMAT_R8G8_UINT,
3036                 VK_FORMAT_R8G8_SINT,
3037                 VK_FORMAT_R8G8_SRGB,
3038                 VK_FORMAT_R16_UNORM,
3039                 VK_FORMAT_R16_SNORM,
3040                 VK_FORMAT_R16_USCALED,
3041                 VK_FORMAT_R16_SSCALED,
3042                 VK_FORMAT_R16_UINT,
3043                 VK_FORMAT_R16_SINT,
3044                 VK_FORMAT_R16_SFLOAT,
3045
3046                 VK_FORMAT_UNDEFINED
3047          };
3048         const VkFormat  compatibleFormats24Bit[]                =
3049         {
3050                 VK_FORMAT_R8G8B8_UNORM,
3051                 VK_FORMAT_R8G8B8_SNORM,
3052                 VK_FORMAT_R8G8B8_USCALED,
3053                 VK_FORMAT_R8G8B8_SSCALED,
3054                 VK_FORMAT_R8G8B8_UINT,
3055                 VK_FORMAT_R8G8B8_SINT,
3056                 VK_FORMAT_R8G8B8_SRGB,
3057                 VK_FORMAT_B8G8R8_UNORM,
3058                 VK_FORMAT_B8G8R8_SNORM,
3059                 VK_FORMAT_B8G8R8_USCALED,
3060                 VK_FORMAT_B8G8R8_SSCALED,
3061                 VK_FORMAT_B8G8R8_UINT,
3062                 VK_FORMAT_B8G8R8_SINT,
3063                 VK_FORMAT_B8G8R8_SRGB,
3064
3065                 VK_FORMAT_UNDEFINED
3066          };
3067         const VkFormat  compatibleFormats32Bit[]                =
3068         {
3069                 VK_FORMAT_R8G8B8A8_UNORM,
3070                 VK_FORMAT_R8G8B8A8_SNORM,
3071                 VK_FORMAT_R8G8B8A8_USCALED,
3072                 VK_FORMAT_R8G8B8A8_SSCALED,
3073                 VK_FORMAT_R8G8B8A8_UINT,
3074                 VK_FORMAT_R8G8B8A8_SINT,
3075                 VK_FORMAT_R8G8B8A8_SRGB,
3076                 VK_FORMAT_B8G8R8A8_UNORM,
3077                 VK_FORMAT_B8G8R8A8_SNORM,
3078                 VK_FORMAT_B8G8R8A8_USCALED,
3079                 VK_FORMAT_B8G8R8A8_SSCALED,
3080                 VK_FORMAT_B8G8R8A8_UINT,
3081                 VK_FORMAT_B8G8R8A8_SINT,
3082                 VK_FORMAT_B8G8R8A8_SRGB,
3083                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3084                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3085                 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
3086                 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
3087                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3088                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3089                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3090                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3091                 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
3092                 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
3093                 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
3094                 VK_FORMAT_A2R10G10B10_UINT_PACK32,
3095                 VK_FORMAT_A2R10G10B10_SINT_PACK32,
3096                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3097                 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
3098                 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
3099                 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
3100                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3101                 VK_FORMAT_A2B10G10R10_SINT_PACK32,
3102                 VK_FORMAT_R16G16_UNORM,
3103                 VK_FORMAT_R16G16_SNORM,
3104                 VK_FORMAT_R16G16_USCALED,
3105                 VK_FORMAT_R16G16_SSCALED,
3106                 VK_FORMAT_R16G16_UINT,
3107                 VK_FORMAT_R16G16_SINT,
3108                 VK_FORMAT_R16G16_SFLOAT,
3109                 VK_FORMAT_R32_UINT,
3110                 VK_FORMAT_R32_SINT,
3111                 VK_FORMAT_R32_SFLOAT,
3112
3113                 VK_FORMAT_UNDEFINED
3114          };
3115         const VkFormat  compatibleFormats48Bit[]                =
3116         {
3117                 VK_FORMAT_R16G16B16_UNORM,
3118                 VK_FORMAT_R16G16B16_SNORM,
3119                 VK_FORMAT_R16G16B16_USCALED,
3120                 VK_FORMAT_R16G16B16_SSCALED,
3121                 VK_FORMAT_R16G16B16_UINT,
3122                 VK_FORMAT_R16G16B16_SINT,
3123                 VK_FORMAT_R16G16B16_SFLOAT,
3124
3125                 VK_FORMAT_UNDEFINED
3126          };
3127         const VkFormat  compatibleFormats64Bit[]                =
3128         {
3129                 VK_FORMAT_R16G16B16A16_UNORM,
3130                 VK_FORMAT_R16G16B16A16_SNORM,
3131                 VK_FORMAT_R16G16B16A16_USCALED,
3132                 VK_FORMAT_R16G16B16A16_SSCALED,
3133                 VK_FORMAT_R16G16B16A16_UINT,
3134                 VK_FORMAT_R16G16B16A16_SINT,
3135                 VK_FORMAT_R16G16B16A16_SFLOAT,
3136                 VK_FORMAT_R32G32_UINT,
3137                 VK_FORMAT_R32G32_SINT,
3138                 VK_FORMAT_R32G32_SFLOAT,
3139                 VK_FORMAT_R64_UINT,
3140                 VK_FORMAT_R64_SINT,
3141                 VK_FORMAT_R64_SFLOAT,
3142
3143                 VK_FORMAT_UNDEFINED
3144          };
3145         const VkFormat  compatibleFormats96Bit[]                =
3146         {
3147                 VK_FORMAT_R32G32B32_UINT,
3148                 VK_FORMAT_R32G32B32_SINT,
3149                 VK_FORMAT_R32G32B32_SFLOAT,
3150
3151                 VK_FORMAT_UNDEFINED
3152          };
3153         const VkFormat  compatibleFormats128Bit[]               =
3154         {
3155                 VK_FORMAT_R32G32B32A32_UINT,
3156                 VK_FORMAT_R32G32B32A32_SINT,
3157                 VK_FORMAT_R32G32B32A32_SFLOAT,
3158                 VK_FORMAT_R64G64_UINT,
3159                 VK_FORMAT_R64G64_SINT,
3160                 VK_FORMAT_R64G64_SFLOAT,
3161
3162                 VK_FORMAT_UNDEFINED
3163          };
3164         const VkFormat  compatibleFormats192Bit[]               =
3165         {
3166                 VK_FORMAT_R64G64B64_UINT,
3167                 VK_FORMAT_R64G64B64_SINT,
3168                 VK_FORMAT_R64G64B64_SFLOAT,
3169
3170                 VK_FORMAT_UNDEFINED
3171          };
3172         const VkFormat  compatibleFormats256Bit[]               =
3173         {
3174                 VK_FORMAT_R64G64B64A64_UINT,
3175                 VK_FORMAT_R64G64B64A64_SINT,
3176                 VK_FORMAT_R64G64B64A64_SFLOAT,
3177
3178                 VK_FORMAT_UNDEFINED
3179         };
3180
3181         const VkFormat* colorImageFormatsToTest[]               =
3182         {
3183                 compatibleFormats8Bit,
3184                 compatibleFormats16Bit,
3185                 compatibleFormats24Bit,
3186                 compatibleFormats32Bit,
3187                 compatibleFormats48Bit,
3188                 compatibleFormats64Bit,
3189                 compatibleFormats96Bit,
3190                 compatibleFormats128Bit,
3191                 compatibleFormats192Bit,
3192                 compatibleFormats256Bit,
3193         };
3194         const size_t    numOfColorImageFormatsToTest    = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3195
3196         for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
3197         {
3198                 const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex];
3199                 for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
3200                 {
3201                         params.src.image.format = compatibleFormats[srcFormatIndex];
3202                         for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
3203                         {
3204                                 params.dst.image.format = compatibleFormats[dstFormatIndex];
3205
3206                                 if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
3207                                         continue;
3208
3209                                 std::ostringstream      testName;
3210                                 testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
3211                                 std::ostringstream      description;
3212                                 description << "Copy from src " << params.src.image.format << " to dst " << params.dst.image.format;
3213
3214                                 testCaseGroup->addChild(new CopyImageToImageTestCase(testCtx, testName.str(), description.str(), params));
3215                         }
3216                 }
3217         }
3218 }
3219
3220 void addBlittingTestsAllFormats (tcu::TestCaseGroup*    testCaseGroup,
3221                                                                  tcu::TestContext&              testCtx,
3222                                                                  TestParams&                    params)
3223 {
3224         // Test Image formats.
3225         const VkFormat  compatibleFormatsUInts[]                        =
3226         {
3227                 VK_FORMAT_R8_UINT,
3228                 VK_FORMAT_R8G8_UINT,
3229                 VK_FORMAT_R8G8B8_UINT,
3230                 VK_FORMAT_B8G8R8_UINT,
3231                 VK_FORMAT_R8G8B8A8_UINT,
3232                 VK_FORMAT_B8G8R8A8_UINT,
3233                 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3234                 VK_FORMAT_A2R10G10B10_UINT_PACK32,
3235                 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3236                 VK_FORMAT_R16_UINT,
3237                 VK_FORMAT_R16G16_UINT,
3238                 VK_FORMAT_R16G16B16_UINT,
3239                 VK_FORMAT_R16G16B16A16_UINT,
3240                 VK_FORMAT_R32_UINT,
3241                 VK_FORMAT_R32G32_UINT,
3242                 VK_FORMAT_R32G32B32_UINT,
3243                 VK_FORMAT_R32G32B32A32_UINT,
3244                 VK_FORMAT_R64_UINT,
3245                 VK_FORMAT_R64G64_UINT,
3246                 VK_FORMAT_R64G64B64_UINT,
3247                 VK_FORMAT_R64G64B64A64_UINT,
3248
3249                 VK_FORMAT_UNDEFINED
3250         };
3251         const VkFormat  compatibleFormatsSInts[]                        =
3252         {
3253                 VK_FORMAT_R8_SINT,
3254                 VK_FORMAT_R8G8_SINT,
3255                 VK_FORMAT_R8G8B8_SINT,
3256                 VK_FORMAT_B8G8R8_SINT,
3257                 VK_FORMAT_R8G8B8A8_SINT,
3258                 VK_FORMAT_B8G8R8A8_SINT,
3259                 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3260                 VK_FORMAT_A2R10G10B10_SINT_PACK32,
3261                 VK_FORMAT_A2B10G10R10_SINT_PACK32,
3262                 VK_FORMAT_R16_SINT,
3263                 VK_FORMAT_R16G16_SINT,
3264                 VK_FORMAT_R16G16B16_SINT,
3265                 VK_FORMAT_R16G16B16A16_SINT,
3266                 VK_FORMAT_R32_SINT,
3267                 VK_FORMAT_R32G32_SINT,
3268                 VK_FORMAT_R32G32B32_SINT,
3269                 VK_FORMAT_R32G32B32A32_SINT,
3270                 VK_FORMAT_R64_SINT,
3271                 VK_FORMAT_R64G64_SINT,
3272                 VK_FORMAT_R64G64B64_SINT,
3273                 VK_FORMAT_R64G64B64A64_SINT,
3274
3275                 VK_FORMAT_UNDEFINED
3276         };
3277         const VkFormat  compatibleFormatsFloats[]                       =
3278         {
3279                 VK_FORMAT_R4G4_UNORM_PACK8,
3280                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3281                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3282                 VK_FORMAT_R5G6B5_UNORM_PACK16,
3283                 VK_FORMAT_B5G6R5_UNORM_PACK16,
3284                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3285                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3286                 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3287                 VK_FORMAT_R8_UNORM,
3288                 VK_FORMAT_R8_SNORM,
3289                 VK_FORMAT_R8_USCALED,
3290                 VK_FORMAT_R8_SSCALED,
3291                 VK_FORMAT_R8G8_UNORM,
3292                 VK_FORMAT_R8G8_SNORM,
3293                 VK_FORMAT_R8G8_USCALED,
3294                 VK_FORMAT_R8G8_SSCALED,
3295                 VK_FORMAT_R8G8B8_UNORM,
3296                 VK_FORMAT_R8G8B8_SNORM,
3297                 VK_FORMAT_R8G8B8_USCALED,
3298                 VK_FORMAT_R8G8B8_SSCALED,
3299                 VK_FORMAT_B8G8R8_UNORM,
3300                 VK_FORMAT_B8G8R8_SNORM,
3301                 VK_FORMAT_B8G8R8_USCALED,
3302                 VK_FORMAT_B8G8R8_SSCALED,
3303                 VK_FORMAT_R8G8B8A8_UNORM,
3304                 VK_FORMAT_R8G8B8A8_SNORM,
3305                 VK_FORMAT_R8G8B8A8_USCALED,
3306                 VK_FORMAT_R8G8B8A8_SSCALED,
3307                 VK_FORMAT_B8G8R8A8_UNORM,
3308                 VK_FORMAT_B8G8R8A8_SNORM,
3309                 VK_FORMAT_B8G8R8A8_USCALED,
3310                 VK_FORMAT_B8G8R8A8_SSCALED,
3311                 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3312                 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3313                 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
3314                 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
3315                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3316                 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
3317                 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
3318                 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
3319                 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3320                 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
3321                 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
3322                 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
3323                 VK_FORMAT_R16_UNORM,
3324                 VK_FORMAT_R16_SNORM,
3325                 VK_FORMAT_R16_USCALED,
3326                 VK_FORMAT_R16_SSCALED,
3327                 VK_FORMAT_R16_SFLOAT,
3328                 VK_FORMAT_R16G16_UNORM,
3329                 VK_FORMAT_R16G16_SNORM,
3330                 VK_FORMAT_R16G16_USCALED,
3331                 VK_FORMAT_R16G16_SSCALED,
3332                 VK_FORMAT_R16G16_SFLOAT,
3333                 VK_FORMAT_R16G16B16_UNORM,
3334                 VK_FORMAT_R16G16B16_SNORM,
3335                 VK_FORMAT_R16G16B16_USCALED,
3336                 VK_FORMAT_R16G16B16_SSCALED,
3337                 VK_FORMAT_R16G16B16_SFLOAT,
3338                 VK_FORMAT_R16G16B16A16_UNORM,
3339                 VK_FORMAT_R16G16B16A16_SNORM,
3340                 VK_FORMAT_R16G16B16A16_USCALED,
3341                 VK_FORMAT_R16G16B16A16_SSCALED,
3342                 VK_FORMAT_R16G16B16A16_SFLOAT,
3343                 VK_FORMAT_R32_SFLOAT,
3344                 VK_FORMAT_R32G32_SFLOAT,
3345                 VK_FORMAT_R32G32B32_SFLOAT,
3346                 VK_FORMAT_R32G32B32A32_SFLOAT,
3347                 VK_FORMAT_R64_SFLOAT,
3348                 VK_FORMAT_R64G64_SFLOAT,
3349                 VK_FORMAT_R64G64B64_SFLOAT,
3350                 VK_FORMAT_R64G64B64A64_SFLOAT,
3351 //              VK_FORMAT_B10G11R11_UFLOAT_PACK32,
3352 //              VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
3353 //              VK_FORMAT_BC1_RGB_UNORM_BLOCK,
3354 //              VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
3355 //              VK_FORMAT_BC2_UNORM_BLOCK,
3356 //              VK_FORMAT_BC3_UNORM_BLOCK,
3357 //              VK_FORMAT_BC4_UNORM_BLOCK,
3358 //              VK_FORMAT_BC4_SNORM_BLOCK,
3359 //              VK_FORMAT_BC5_UNORM_BLOCK,
3360 //              VK_FORMAT_BC5_SNORM_BLOCK,
3361 //              VK_FORMAT_BC6H_UFLOAT_BLOCK,
3362 //              VK_FORMAT_BC6H_SFLOAT_BLOCK,
3363 //              VK_FORMAT_BC7_UNORM_BLOCK,
3364 //              VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
3365 //              VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
3366 //              VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
3367 //              VK_FORMAT_EAC_R11_UNORM_BLOCK,
3368 //              VK_FORMAT_EAC_R11_SNORM_BLOCK,
3369 //              VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
3370 //              VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
3371 //              VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
3372 //              VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
3373 //              VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
3374 //              VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
3375 //              VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
3376 //              VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
3377 //              VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
3378 //              VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
3379 //              VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
3380 //              VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
3381 //              VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
3382 //              VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
3383 //              VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
3384 //              VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
3385
3386                 VK_FORMAT_UNDEFINED
3387         };
3388         const VkFormat  compatibleFormatsSrgb[]                         =
3389         {
3390                 VK_FORMAT_R8_SRGB,
3391                 VK_FORMAT_R8G8_SRGB,
3392                 VK_FORMAT_R8G8B8_SRGB,
3393                 VK_FORMAT_B8G8R8_SRGB,
3394                 VK_FORMAT_R8G8B8A8_SRGB,
3395                 VK_FORMAT_B8G8R8A8_SRGB,
3396                 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3397 //              VK_FORMAT_BC1_RGB_SRGB_BLOCK,
3398 //              VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
3399 //              VK_FORMAT_BC2_SRGB_BLOCK,
3400 //              VK_FORMAT_BC3_SRGB_BLOCK,
3401 //              VK_FORMAT_BC7_SRGB_BLOCK,
3402 //              VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
3403 //              VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
3404 //              VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
3405 //              VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
3406 //              VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
3407 //              VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
3408 //              VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
3409 //              VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
3410 //              VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
3411 //              VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
3412 //              VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
3413 //              VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
3414 //              VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
3415 //              VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
3416 //              VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
3417 //              VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
3418 //              VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
3419
3420                 VK_FORMAT_UNDEFINED
3421         };
3422
3423         const struct {
3424                 const VkFormat* compatibleFormats;
3425                 const bool              onlyNearest;
3426         }       colorImageFormatsToTest[]                       =
3427         {
3428                 { compatibleFormatsUInts,       true    },
3429                 { compatibleFormatsSInts,       true    },
3430                 { compatibleFormatsFloats,      false   },
3431                 { compatibleFormatsSrgb,        false   },
3432         };
3433         const size_t    numOfColorImageFormatsToTest            = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3434
3435         for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
3436         {
3437                 const VkFormat* compatibleFormats       = colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats;
3438                 const bool              onlyNearest                     = colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest;
3439                 for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
3440                 {
3441                         params.src.image.format = compatibleFormats[srcFormatIndex];
3442                         for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
3443                         {
3444                                 params.dst.image.format = compatibleFormats[dstFormatIndex];
3445
3446                                 if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
3447                                         continue;
3448
3449                                 std::ostringstream      testName;
3450                                 testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
3451                                 std::ostringstream      description;
3452                                 description << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format;
3453
3454                                 params.filter                   = VK_FILTER_NEAREST;
3455                                 testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params));
3456
3457                                 if (!onlyNearest)
3458                                 {
3459                                         params.filter           = VK_FILTER_LINEAR;
3460                                         testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params));
3461                                 }
3462                         }
3463                 }
3464         }
3465 }
3466
3467 } // anonymous
3468
3469 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
3470 {
3471         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests  (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
3472
3473         de::MovePtr<tcu::TestCaseGroup> imageToImageTests               (new tcu::TestCaseGroup(testCtx, "image_to_image", "Copy from image to image"));
3474         de::MovePtr<tcu::TestCaseGroup> imgToImgSimpleTests             (new tcu::TestCaseGroup(testCtx, "simple_tests", "Copy from image to image simple tests"));
3475         de::MovePtr<tcu::TestCaseGroup> imgToImgAllFormatsTests (new tcu::TestCaseGroup(testCtx, "all_formats", "Copy from image to image with all compatible formats"));
3476
3477         de::MovePtr<tcu::TestCaseGroup> imageToBufferTests              (new tcu::TestCaseGroup(testCtx, "image_to_buffer", "Copy from image to buffer"));
3478         de::MovePtr<tcu::TestCaseGroup> bufferToImageTests              (new tcu::TestCaseGroup(testCtx, "buffer_to_image", "Copy from buffer to image"));
3479         de::MovePtr<tcu::TestCaseGroup> bufferToBufferTests             (new tcu::TestCaseGroup(testCtx, "buffer_to_buffer", "Copy from buffer to buffer"));
3480
3481         de::MovePtr<tcu::TestCaseGroup> blittingImageTests              (new tcu::TestCaseGroup(testCtx, "blit_image", "Blitting image"));
3482         de::MovePtr<tcu::TestCaseGroup> blitImgSimpleTests              (new tcu::TestCaseGroup(testCtx, "simple_tests", "Blitting image simple tests"));
3483         de::MovePtr<tcu::TestCaseGroup> blitImgAllFormatsTests  (new tcu::TestCaseGroup(testCtx, "all_formats", "Blitting image with all compatible formats"));
3484
3485         de::MovePtr<tcu::TestCaseGroup> resolveImageTests               (new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image"));
3486
3487         const deInt32                                   defaultSize                             = 64;
3488         const deInt32                                   defaultHalfSize                 = defaultSize / 2;
3489         const deInt32                                   defaultFourthSize               = defaultSize / 4;
3490         const VkExtent3D                                defaultExtent                   = {defaultSize, defaultSize, 1};
3491         const VkExtent3D                                defaultHalfExtent               = {defaultHalfSize, defaultHalfSize, 1};
3492
3493         const VkImageSubresourceLayers  defaultSourceLayer              =
3494         {
3495                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
3496                 0u,                                                     // uint32_t                             mipLevel;
3497                 0u,                                                     // uint32_t                             baseArrayLayer;
3498                 1u,                                                     // uint32_t                             layerCount;
3499         };
3500
3501         // Copy image to image testcases.
3502         {
3503                 TestParams                      params;
3504                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3505                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3506                 params.src.image.extent         = defaultExtent;
3507                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3508                 params.dst.image.extent         = defaultExtent;
3509
3510                 {
3511                         const VkImageCopy                               testCopy        =
3512                         {
3513                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3514                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
3515                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3516                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
3517                                 defaultExtent,          // VkExtent3D                           extent;
3518                         };
3519
3520                         CopyRegion      imageCopy;
3521                         imageCopy.imageCopy     = testCopy;
3522
3523                         params.regions.push_back(imageCopy);
3524                 }
3525
3526                 imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
3527         }
3528
3529         {
3530                 TestParams                      params;
3531                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3532                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3533                 params.src.image.extent         = defaultExtent;
3534                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3535                 params.dst.image.format         = VK_FORMAT_R32_UINT;
3536                 params.dst.image.extent         = defaultExtent;
3537
3538                 {
3539                         const VkImageCopy                               testCopy        =
3540                         {
3541                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3542                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
3543                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3544                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
3545                                 defaultExtent,          // VkExtent3D                           extent;
3546                         };
3547
3548                         CopyRegion      imageCopy;
3549                         imageCopy.imageCopy     = testCopy;
3550
3551                         params.regions.push_back(imageCopy);
3552                 }
3553
3554                 imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
3555         }
3556
3557         {
3558                 TestParams                      params;
3559                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3560                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3561                 params.src.image.extent         = defaultExtent;
3562                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3563                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3564                 params.dst.image.extent         = defaultExtent;
3565
3566                 {
3567                         const VkImageCopy                               testCopy        =
3568                         {
3569                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     srcSubresource;
3570                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3571                                 defaultSourceLayer,                                                                     // VkImageSubresourceLayers     dstSubresource;
3572                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3573                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3574                         };
3575
3576                         CopyRegion      imageCopy;
3577                         imageCopy.imageCopy     = testCopy;
3578
3579                         params.regions.push_back(imageCopy);
3580                 }
3581
3582                 imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
3583         }
3584
3585         {
3586                 TestParams                      params;
3587                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3588                 params.src.image.format         = VK_FORMAT_D32_SFLOAT;
3589                 params.src.image.extent         = defaultExtent;
3590                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3591                 params.dst.image.format         = VK_FORMAT_D32_SFLOAT;
3592                 params.dst.image.extent         = defaultExtent;
3593
3594                 {
3595                         const VkImageSubresourceLayers  sourceLayer =
3596                         {
3597                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
3598                                 0u,                                                     // uint32_t                             mipLevel;
3599                                 0u,                                                     // uint32_t                             baseArrayLayer;
3600                                 1u                                                      // uint32_t                             layerCount;
3601                         };
3602                         const VkImageCopy                               testCopy        =
3603                         {
3604                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
3605                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3606                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
3607                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3608                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3609                         };
3610
3611                         CopyRegion      imageCopy;
3612                         imageCopy.imageCopy     = testCopy;
3613
3614                         params.regions.push_back(imageCopy);
3615                 }
3616
3617                 imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
3618         }
3619
3620         {
3621                 TestParams                      params;
3622                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3623                 params.src.image.format         = VK_FORMAT_S8_UINT;
3624                 params.src.image.extent         = defaultExtent;
3625                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3626                 params.dst.image.format         = VK_FORMAT_S8_UINT;
3627                 params.dst.image.extent         = defaultExtent;
3628
3629                 {
3630                         const VkImageSubresourceLayers  sourceLayer =
3631                         {
3632                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
3633                                 0u,                                                             // uint32_t                             mipLevel;
3634                                 0u,                                                             // uint32_t                             baseArrayLayer;
3635                                 1u                                                              // uint32_t                             layerCount;
3636                         };
3637                         const VkImageCopy                               testCopy        =
3638                         {
3639                                 sourceLayer,                                                                            // VkImageSubresourceLayers     srcSubresource;
3640                                 {0, 0, 0},                                                                                      // VkOffset3D                           srcOffset;
3641                                 sourceLayer,                                                                            // VkImageSubresourceLayers     dstSubresource;
3642                                 {defaultFourthSize, defaultFourthSize / 2, 0},          // VkOffset3D                           dstOffset;
3643                                 {defaultFourthSize / 2, defaultFourthSize / 2, 1},      // VkExtent3D                           extent;
3644                         };
3645
3646                         CopyRegion      imageCopy;
3647                         imageCopy.imageCopy     = testCopy;
3648
3649                         params.regions.push_back(imageCopy);
3650                 }
3651
3652                 imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
3653         }
3654
3655         {
3656                 TestParams                      params;
3657                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3658                 params.src.image.extent         = defaultExtent;
3659                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3660                 params.dst.image.extent         = defaultExtent;
3661
3662                 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
3663                 {
3664                         const VkImageCopy                               testCopy        =
3665                         {
3666                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     srcSubresource;
3667                                 {0, 0, 0},                                                                              // VkOffset3D                           srcOffset;
3668                                 defaultSourceLayer,                                                             // VkImageSubresourceLayers     dstSubresource;
3669                                 {i, defaultSize - i - defaultFourthSize, 0},    // VkOffset3D                           dstOffset;
3670                                 {defaultFourthSize, defaultFourthSize, 1},              // VkExtent3D                           extent;
3671                         };
3672
3673                         CopyRegion      imageCopy;
3674                         imageCopy.imageCopy     = testCopy;
3675
3676                         params.regions.push_back(imageCopy);
3677                 }
3678
3679                 addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params);
3680         }
3681         imageToImageTests->addChild(imgToImgSimpleTests.release());
3682         imageToImageTests->addChild(imgToImgAllFormatsTests.release());
3683
3684         // Copy image to buffer testcases.
3685         {
3686                 TestParams      params;
3687                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3688                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3689                 params.src.image.extent         = defaultExtent;
3690                 params.dst.buffer.size          = defaultSize * defaultSize;
3691
3692                 const VkBufferImageCopy bufferImageCopy =
3693                 {
3694                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
3695                         0u,                                                                                     // uint32_t                                     bufferRowLength;
3696                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
3697                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
3698                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
3699                         defaultExtent                                                           // VkExtent3D                           imageExtent;
3700                 };
3701                 CopyRegion      copyRegion;
3702                 copyRegion.bufferImageCopy      = bufferImageCopy;
3703
3704                 params.regions.push_back(copyRegion);
3705
3706                 imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
3707         }
3708
3709         {
3710                 TestParams      params;
3711                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3712                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3713                 params.src.image.extent         = defaultExtent;
3714                 params.dst.buffer.size          = defaultSize * defaultSize;
3715
3716                 const VkBufferImageCopy bufferImageCopy =
3717                 {
3718                         defaultSize * defaultHalfSize,                          // VkDeviceSize                         bufferOffset;
3719                         0u,                                                                                     // uint32_t                                     bufferRowLength;
3720                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
3721                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
3722                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
3723                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
3724                 };
3725                 CopyRegion      copyRegion;
3726                 copyRegion.bufferImageCopy      = bufferImageCopy;
3727
3728                 params.regions.push_back(copyRegion);
3729
3730                 imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
3731         }
3732
3733         {
3734                 TestParams      params;
3735                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3736                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3737                 params.src.image.extent         = defaultExtent;
3738                 params.dst.buffer.size          = defaultSize * defaultSize;
3739
3740                 const int                       pixelSize       = tcu::getPixelSize(mapVkFormat(params.src.image.format));
3741                 const VkDeviceSize      bufferSize      = pixelSize * params.dst.buffer.size;
3742                 const VkDeviceSize      offsetSize      = pixelSize * defaultFourthSize * defaultFourthSize;
3743                 deUint32                        divisor         = 1;
3744                 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
3745                 {
3746                         const deUint32                  bufferRowLength         = defaultFourthSize;
3747                         const deUint32                  bufferImageHeight       = defaultFourthSize;
3748                         const VkExtent3D                imageExtent                     = {defaultFourthSize / divisor, defaultFourthSize, 1};
3749                         DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
3750                         DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
3751                         DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
3752
3753                         CopyRegion                              region;
3754                         const VkBufferImageCopy bufferImageCopy         =
3755                         {
3756                                 offset,                                         // VkDeviceSize                         bufferOffset;
3757                                 bufferRowLength,                        // uint32_t                                     bufferRowLength;
3758                                 bufferImageHeight,                      // uint32_t                                     bufferImageHeight;
3759                                 defaultSourceLayer,                     // VkImageSubresourceLayers     imageSubresource;
3760                                 {0, 0, 0},                                      // VkOffset3D                           imageOffset;
3761                                 imageExtent                                     // VkExtent3D                           imageExtent;
3762                         };
3763                         region.bufferImageCopy  = bufferImageCopy;
3764                         params.regions.push_back(region);
3765                 }
3766
3767                 imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
3768         }
3769
3770         // Copy buffer to image testcases.
3771         {
3772                 TestParams      params;
3773                 params.src.buffer.size          = defaultSize * defaultSize;
3774                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3775                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UINT;
3776                 params.dst.image.extent         = defaultExtent;
3777
3778                 const VkBufferImageCopy bufferImageCopy =
3779                 {
3780                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
3781                         0u,                                                                                     // uint32_t                                     bufferRowLength;
3782                         0u,                                                                                     // uint32_t                                     bufferImageHeight;
3783                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
3784                         {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
3785                         defaultExtent                                                           // VkExtent3D                           imageExtent;
3786                 };
3787                 CopyRegion      copyRegion;
3788                 copyRegion.bufferImageCopy      = bufferImageCopy;
3789
3790                 params.regions.push_back(copyRegion);
3791
3792                 bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
3793         }
3794
3795         {
3796                 TestParams      params;
3797                 params.src.buffer.size          = defaultSize * defaultSize;
3798                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3799                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3800                 params.dst.image.extent         = defaultExtent;
3801
3802                 CopyRegion      region;
3803                 deUint32        divisor = 1;
3804                 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
3805                 {
3806                         const VkBufferImageCopy bufferImageCopy =
3807                         {
3808                                 0u,                                                                                                                             // VkDeviceSize                         bufferOffset;
3809                                 0u,                                                                                                                             // uint32_t                                     bufferRowLength;
3810                                 0u,                                                                                                                             // uint32_t                                     bufferImageHeight;
3811                                 defaultSourceLayer,                                                                                             // VkImageSubresourceLayers     imageSubresource;
3812                                 {offset, defaultHalfSize, 0},                                                                   // VkOffset3D                           imageOffset;
3813                                 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1}   // VkExtent3D                           imageExtent;
3814                         };
3815                         region.bufferImageCopy  = bufferImageCopy;
3816                         params.regions.push_back(region);
3817                 }
3818
3819                 bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
3820         }
3821
3822         {
3823                 TestParams      params;
3824                 params.src.buffer.size          = defaultSize * defaultSize;
3825                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3826                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3827                 params.dst.image.extent         = defaultExtent;
3828
3829                 const VkBufferImageCopy bufferImageCopy =
3830                 {
3831                         defaultFourthSize,                                                      // VkDeviceSize                         bufferOffset;
3832                         defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferRowLength;
3833                         defaultHalfSize + defaultFourthSize,            // uint32_t                                     bufferImageHeight;
3834                         defaultSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
3835                         {defaultFourthSize, defaultFourthSize, 0},      // VkOffset3D                           imageOffset;
3836                         defaultHalfExtent                                                       // VkExtent3D                           imageExtent;
3837                 };
3838                 CopyRegion      copyRegion;
3839                 copyRegion.bufferImageCopy      = bufferImageCopy;
3840
3841                 params.regions.push_back(copyRegion);
3842
3843                 bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
3844         }
3845
3846         // Copy buffer to buffer testcases.
3847         {
3848                 TestParams                      params;
3849                 params.src.buffer.size  = defaultSize;
3850                 params.dst.buffer.size  = defaultSize;
3851
3852                 const VkBufferCopy      bufferCopy      =
3853                 {
3854                         0u,                             // VkDeviceSize srcOffset;
3855                         0u,                             // VkDeviceSize dstOffset;
3856                         defaultSize,    // VkDeviceSize size;
3857                 };
3858
3859                 CopyRegion      copyRegion;
3860                 copyRegion.bufferCopy   = bufferCopy;
3861                 params.regions.push_back(copyRegion);
3862
3863                 bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
3864         }
3865
3866         {
3867                 TestParams                      params;
3868                 params.src.buffer.size  = defaultFourthSize;
3869                 params.dst.buffer.size  = defaultFourthSize;
3870
3871                 const VkBufferCopy      bufferCopy      =
3872                 {
3873                         12u,    // VkDeviceSize srcOffset;
3874                         4u,             // VkDeviceSize dstOffset;
3875                         1u,             // VkDeviceSize size;
3876                 };
3877
3878                 CopyRegion      copyRegion;
3879                 copyRegion.bufferCopy = bufferCopy;
3880                 params.regions.push_back(copyRegion);
3881
3882                 bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
3883         }
3884
3885         {
3886                 const deUint32          size            = 16;
3887                 TestParams                      params;
3888                 params.src.buffer.size  = size;
3889                 params.dst.buffer.size  = size * (size + 1);
3890
3891                 // Copy region with size 1..size
3892                 for (unsigned int i = 1; i <= size; i++)
3893                 {
3894                         const VkBufferCopy      bufferCopy      =
3895                         {
3896                                 0,                      // VkDeviceSize srcOffset;
3897                                 i * size,       // VkDeviceSize dstOffset;
3898                                 i,                      // VkDeviceSize size;
3899                         };
3900
3901                         CopyRegion      copyRegion;
3902                         copyRegion.bufferCopy = bufferCopy;
3903                         params.regions.push_back(copyRegion);
3904                 }
3905
3906                 bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
3907         }
3908
3909         // Blitting testcases.
3910         {
3911                 const std::string       description     ("Blit without scaling (whole)");
3912                 const std::string       testName        ("whole");
3913
3914                 TestParams                      params;
3915                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3916                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3917                 params.src.image.extent         = defaultExtent;
3918                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3919                 params.dst.image.extent         = defaultExtent;
3920
3921                 {
3922                         const VkImageBlit                               imageBlit       =
3923                         {
3924                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3925                                 {
3926                                         {0, 0, 0},
3927                                         {defaultSize, defaultSize, 1}
3928                                 },                                      // VkOffset3D                           srcOffsets[2];
3929
3930                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3931                                 {
3932                                         {0, 0, 0},
3933                                         {defaultSize, defaultSize, 1}
3934                                 }                                       // VkOffset3D                           dstOffset[2];
3935                         };
3936
3937                         CopyRegion      region;
3938                         region.imageBlit = imageBlit;
3939                         params.regions.push_back(region);
3940                 }
3941
3942                 // Filter is VK_FILTER_NEAREST.
3943                 {
3944                         params.filter                   = VK_FILTER_NEAREST;
3945
3946                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
3947                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
3948
3949                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
3950                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
3951                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
3952
3953                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
3954                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
3955                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
3956                 }
3957
3958                 // Filter is VK_FILTER_LINEAR.
3959                 {
3960                         params.filter                   = VK_FILTER_LINEAR;
3961
3962                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
3963                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
3964
3965                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
3966                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
3967                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
3968
3969                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
3970                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
3971                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
3972                 }
3973         }
3974
3975         {
3976                 const std::string       description     ("Flipping x and y coordinates (whole)");
3977                 const std::string       testName        ("mirror_xy");
3978
3979                 TestParams                      params;
3980                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
3981                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
3982                 params.src.image.extent         = defaultExtent;
3983                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
3984                 params.dst.image.extent         = defaultExtent;
3985
3986                 {
3987                         const VkImageBlit                               imageBlit       =
3988                         {
3989                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
3990                                 {
3991                                         {0, 0, 0},
3992                                         {defaultSize, defaultSize, 1}
3993                                 },                                      // VkOffset3D                           srcOffsets[2];
3994
3995                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
3996                                 {
3997                                         {defaultSize, defaultSize, 1},
3998                                         {0, 0, 0}
3999                                 }                                       // VkOffset3D                           dstOffset[2];
4000                         };
4001
4002                         CopyRegion      region;
4003                         region.imageBlit = imageBlit;
4004                         params.regions.push_back(region);
4005                 }
4006
4007                 // Filter is VK_FILTER_NEAREST.
4008                 {
4009                         params.filter                   = VK_FILTER_NEAREST;
4010
4011                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4012                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4013
4014                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4015                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4016                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4017
4018                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4019                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4020                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" +  getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4021                 }
4022
4023                 // Filter is VK_FILTER_LINEAR.
4024                 {
4025                         params.filter                   = VK_FILTER_LINEAR;
4026
4027                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4028                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4029
4030                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4031                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4032                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4033
4034                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4035                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4036                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4037                 }
4038         }
4039
4040         {
4041                 const std::string       description     ("Flipping x coordinates (whole)");
4042                 const std::string       testName        ("mirror_x");
4043
4044                 TestParams                      params;
4045                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4046                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4047                 params.src.image.extent         = defaultExtent;
4048                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4049                 params.dst.image.extent         = defaultExtent;
4050
4051                 {
4052                         const VkImageBlit                               imageBlit       =
4053                         {
4054                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4055                                 {
4056                                         {0, 0, 0},
4057                                         {defaultSize, defaultSize, 1}
4058                                 },                                      // VkOffset3D                           srcOffsets[2];
4059
4060                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4061                                 {
4062                                         {defaultSize, 0, 0},
4063                                         {0, defaultSize, 1}
4064                                 }                                       // VkOffset3D                           dstOffset[2];
4065                         };
4066
4067                         CopyRegion      region;
4068                         region.imageBlit = imageBlit;
4069                         params.regions.push_back(region);
4070                 }
4071
4072                 // Filter is VK_FILTER_NEAREST.
4073                 {
4074                         params.filter                   = VK_FILTER_NEAREST;
4075
4076                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4077                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4078
4079                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4080                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4081                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4082
4083                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4084                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4085                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4086                 }
4087
4088                 // Filter is VK_FILTER_LINEAR.
4089                 {
4090                         params.filter                   = VK_FILTER_LINEAR;
4091
4092                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4093                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4094
4095                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4096                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4097                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4098
4099                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4100                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4101                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4102                 }
4103         }
4104
4105         {
4106                 const std::string       description     ("Flipping Y coordinates (whole)");
4107                 const std::string       testName        ("mirror_y");
4108
4109                 TestParams                      params;
4110                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4111                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4112                 params.src.image.extent         = defaultExtent;
4113                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4114                 params.dst.image.extent         = defaultExtent;
4115
4116                 {
4117                         const VkImageBlit                               imageBlit       =
4118                         {
4119                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4120                                 {
4121                                         {0, 0, 0},
4122                                         {defaultSize, defaultSize, 1}
4123                                 },                                      // VkOffset3D                           srcOffsets[2];
4124
4125                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4126                                 {
4127                                         {0, defaultSize, 1},
4128                                         {defaultSize, 0, 0}
4129                                 }                                       // VkOffset3D                           dstOffset[2];
4130                         };
4131
4132                         CopyRegion      region;
4133                         region.imageBlit = imageBlit;
4134                         params.regions.push_back(region);
4135                 }
4136
4137                 // Filter is VK_FILTER_NEAREST.
4138                 {
4139                         params.filter                   = VK_FILTER_NEAREST;
4140
4141                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4142                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4143
4144                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4145                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4146                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4147
4148                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4149                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4150                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4151                 }
4152
4153                 // Filter is VK_FILTER_LINEAR.
4154                 {
4155                         params.filter                   = VK_FILTER_LINEAR;
4156
4157                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4158                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4159
4160                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4161                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4162                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4163
4164                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4165                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4166                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4167                 }
4168         }
4169
4170         {
4171                 const std::string       description     ("Mirroring subregions in image (no flip ,y flip ,x flip, xy flip)");
4172                 const std::string       testName        ("mirror_subregions");
4173
4174                 TestParams                      params;
4175                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4176                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4177                 params.src.image.extent         = defaultExtent;
4178                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4179                 params.dst.image.extent         = defaultExtent;
4180
4181                 // No mirroring.
4182                 {
4183                         const VkImageBlit                               imageBlit       =
4184                         {
4185                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4186                                 {
4187                                         {0, 0, 0},
4188                                         {defaultHalfSize, defaultHalfSize, 1}
4189                                 },                                      // VkOffset3D                           srcOffsets[2];
4190
4191                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4192                                 {
4193                                         {0, 0, 0},
4194                                         {defaultHalfSize, defaultHalfSize, 1}
4195                                 }                                       // VkOffset3D                           dstOffset[2];
4196                         };
4197
4198                         CopyRegion      region;
4199                         region.imageBlit = imageBlit;
4200                         params.regions.push_back(region);
4201                 }
4202
4203                 // Flipping y coordinates.
4204                 {
4205                         const VkImageBlit                               imageBlit       =
4206                         {
4207                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4208                                 {
4209                                         {defaultHalfSize, 0, 0},
4210                                         {defaultSize, defaultHalfSize, 1}
4211                                 },                                      // VkOffset3D                           srcOffsets[2];
4212
4213                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4214                                 {
4215                                         {defaultHalfSize, defaultHalfSize, 0},
4216                                         {defaultSize, 0, 1}
4217                                 }                                       // VkOffset3D                           dstOffset[2];
4218                         };
4219
4220                         CopyRegion      region;
4221                         region.imageBlit = imageBlit;
4222                         params.regions.push_back(region);
4223                 }
4224
4225                 // Flipping x coordinates.
4226                 {
4227                         const VkImageBlit                               imageBlit       =
4228                         {
4229                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4230                                 {
4231                                         {0, defaultHalfSize, 0},
4232                                         {defaultHalfSize, defaultSize, 1}
4233                                 },                                      // VkOffset3D                           srcOffsets[2];
4234
4235                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4236                                 {
4237                                         {defaultHalfSize, defaultHalfSize, 0},
4238                                         {0, defaultSize, 1}
4239                                 }                                       // VkOffset3D                           dstOffset[2];
4240                         };
4241
4242                         CopyRegion      region;
4243                         region.imageBlit = imageBlit;
4244                         params.regions.push_back(region);
4245                 }
4246
4247                 // Flipping x and y coordinates.
4248                 {
4249                         const VkImageBlit                               imageBlit       =
4250                         {
4251                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4252                                 {
4253                                         {defaultHalfSize, defaultHalfSize, 0},
4254                                         {defaultSize, defaultSize, 1}
4255                                 },                                      // VkOffset3D                           srcOffsets[2];
4256
4257                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4258                                 {
4259                                         {defaultSize, defaultSize, 0},
4260                                         {defaultHalfSize, defaultHalfSize, 1}
4261                                 }                                       // VkOffset3D                           dstOffset[2];
4262                         };
4263
4264                         CopyRegion      region;
4265                         region.imageBlit = imageBlit;
4266                         params.regions.push_back(region);
4267                 }
4268
4269                 // Filter is VK_FILTER_NEAREST.
4270                 {
4271                         params.filter                   = VK_FILTER_NEAREST;
4272
4273                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4274                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4275
4276                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4277                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4278                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4279
4280                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4281                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4282                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4283                 }
4284
4285                 // Filter is VK_FILTER_LINEAR.
4286                 {
4287                         params.filter                   = VK_FILTER_LINEAR;
4288
4289                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4290                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4291
4292                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4293                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4294                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4295
4296                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4297                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4298                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4299                 }
4300         }
4301
4302         {
4303                 const std::string       description     ("Blit with scaling (whole, src extent bigger)");
4304                 const std::string       testName        ("scaling_whole1");
4305
4306                 TestParams                      params;
4307                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4308                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4309                 params.src.image.extent         = defaultExtent;
4310                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4311                 params.dst.image.extent         = defaultHalfExtent;
4312
4313                 {
4314                         const VkImageBlit                               imageBlit       =
4315                         {
4316                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4317                                 {
4318                                         {0, 0, 0},
4319                                         {defaultSize, defaultSize, 1}
4320                                 },                                      // VkOffset3D                                   srcOffsets[2];
4321
4322                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4323                                 {
4324                                         {0, 0, 0},
4325                                         {defaultHalfSize, defaultHalfSize, 1}
4326                                 }                                       // VkOffset3D                                   dstOffset[2];
4327                         };
4328
4329                         CopyRegion      region;
4330                         region.imageBlit        = imageBlit;
4331                         params.regions.push_back(region);
4332                 }
4333
4334                 // Filter is VK_FILTER_NEAREST.
4335                 {
4336                         params.filter                   = VK_FILTER_NEAREST;
4337
4338                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4339                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4340
4341                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4342                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4343                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4344
4345                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4346                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4347                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4348                 }
4349
4350                 // Filter is VK_FILTER_LINEAR.
4351                 {
4352                         params.filter                   = VK_FILTER_LINEAR;
4353
4354                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4355                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4356
4357                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4358                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4359                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4360
4361                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4362                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4363                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4364                 }
4365         }
4366
4367         {
4368                 const std::string       description     ("Blit with scaling (whole, dst extent bigger)");
4369                 const std::string       testName        ("scaling_whole2");
4370
4371                 TestParams                      params;
4372                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4373                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4374                 params.src.image.extent         = defaultHalfExtent;
4375                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4376                 params.dst.image.extent         = defaultExtent;
4377
4378                 {
4379                         const VkImageBlit                               imageBlit       =
4380                         {
4381                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4382                                 {
4383                                         {0, 0, 0},
4384                                         {defaultHalfSize, defaultHalfSize, 1}
4385                                 },                                      // VkOffset3D                                   srcOffsets[2];
4386
4387                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4388                                 {
4389                                         {0, 0, 0},
4390                                         {defaultSize, defaultSize, 1}
4391                                 }                                       // VkOffset3D                                   dstOffset[2];
4392                         };
4393
4394                         CopyRegion      region;
4395                         region.imageBlit        = imageBlit;
4396                         params.regions.push_back(region);
4397                 }
4398
4399                 // Filter is VK_FILTER_NEAREST.
4400                 {
4401                         params.filter                   = VK_FILTER_NEAREST;
4402
4403                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4404                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4405
4406                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4407                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4408                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4409
4410                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4411                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4412                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4413                 }
4414
4415                 // Filter is VK_FILTER_LINEAR.
4416                 {
4417                         params.filter                   = VK_FILTER_LINEAR;
4418
4419                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4420                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4421
4422                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4423                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4424                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4425
4426                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4427                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4428                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4429                 }
4430         }
4431
4432         {
4433                 const std::string       description     ("Blit with scaling and offset (whole, dst extent bigger)");
4434                 const std::string       testName        ("scaling_and_offset");
4435
4436                 TestParams                      params;
4437                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4438                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4439                 params.src.image.extent         = defaultExtent;
4440                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4441                 params.dst.image.extent         = defaultExtent;
4442
4443                 {
4444                         const VkImageBlit                               imageBlit       =
4445                         {
4446                                 defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4447                                 {
4448                                         {defaultFourthSize, defaultFourthSize, 0},
4449                                         {defaultFourthSize*3, defaultFourthSize*3, 1}
4450                                 },                                      // VkOffset3D                                   srcOffsets[2];
4451
4452                                 defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4453                                 {
4454                                         {0, 0, 0},
4455                                         {defaultSize, defaultSize, 1}
4456                                 }                                       // VkOffset3D                                   dstOffset[2];
4457                         };
4458
4459                         CopyRegion      region;
4460                         region.imageBlit        = imageBlit;
4461                         params.regions.push_back(region);
4462                 }
4463
4464                 // Filter is VK_FILTER_NEAREST.
4465                 {
4466                         params.filter                   = VK_FILTER_NEAREST;
4467
4468                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4469                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4470
4471                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4472                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4473                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4474
4475                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4476                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4477                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4478                 }
4479
4480                 // Filter is VK_FILTER_LINEAR.
4481                 {
4482                         params.filter                   = VK_FILTER_LINEAR;
4483
4484                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4485                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4486
4487                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4488                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4489                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4490
4491                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4492                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4493                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4494                 }
4495         }
4496
4497         {
4498                 const std::string       description     ("Blit without scaling (partial)");
4499                 const std::string       testName        ("without_scaling_partial");
4500
4501                 TestParams                      params;
4502                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4503                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4504                 params.src.image.extent         = defaultExtent;
4505                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4506                 params.dst.image.extent         = defaultExtent;
4507
4508                 {
4509                         CopyRegion      region;
4510                         for (int i = 0; i < defaultSize; i += defaultFourthSize)
4511                         {
4512                                 const VkImageBlit                       imageBlit       =
4513                                 {
4514                                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4515                                         {
4516                                                 {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
4517                                                 {defaultSize - i, defaultSize - i, 1}
4518                                         },                                      // VkOffset3D                                   srcOffsets[2];
4519
4520                                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4521                                         {
4522                                                 {i, i, 0},
4523                                                 {i + defaultFourthSize, i + defaultFourthSize, 1}
4524                                         }                                       // VkOffset3D                                   dstOffset[2];
4525                                 };
4526                                 region.imageBlit        = imageBlit;
4527                                 params.regions.push_back(region);
4528                         }
4529                 }
4530
4531                 // Filter is VK_FILTER_NEAREST.
4532                 {
4533                         params.filter                   = VK_FILTER_NEAREST;
4534
4535                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4536                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4537
4538                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4539                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)");
4540                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4541
4542                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4543                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4544                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4545                 }
4546
4547                 // Filter is VK_FILTER_LINEAR.
4548                 {
4549                         params.filter                   = VK_FILTER_LINEAR;
4550
4551                         params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
4552                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4553
4554                         params.dst.image.format = VK_FORMAT_R32_SFLOAT;
4555                         const std::string       descriptionOfRGBAToR32  (description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4556                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4557
4558                         params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
4559                         const std::string       descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4560                         blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4561                 }
4562         }
4563
4564         {
4565                 const std::string       description     ("Blit with scaling (partial)");
4566                 const std::string       testName        ("scaling_partial");
4567
4568                 // Test Color formats.
4569                 {
4570                         TestParams      params;
4571                         params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4572                         params.src.image.extent         = defaultExtent;
4573                         params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4574                         params.dst.image.extent         = defaultExtent;
4575
4576                         CopyRegion      region;
4577                         for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
4578                         {
4579                                 const VkImageBlit                       imageBlit       =
4580                                 {
4581                                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4582                                         {
4583                                                 {0, 0, 0},
4584                                                 {defaultSize, defaultSize, 1}
4585                                         },                                      // VkOffset3D                                   srcOffsets[2];
4586
4587                                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4588                                         {
4589                                                 {i, 0, 0},
4590                                                 {i + defaultFourthSize / j, defaultFourthSize / j, 1}
4591                                         }                                       // VkOffset3D                                   dstOffset[2];
4592                                 };
4593                                 region.imageBlit        = imageBlit;
4594                                 params.regions.push_back(region);
4595                         }
4596                         for (int i = 0; i < defaultSize; i += defaultFourthSize)
4597                         {
4598                                 const VkImageBlit                       imageBlit       =
4599                                 {
4600                                         defaultSourceLayer,     // VkImageSubresourceLayers     srcSubresource;
4601                                         {
4602                                                 {i, i, 0},
4603                                                 {i + defaultFourthSize, i + defaultFourthSize, 1}
4604                                         },                                      // VkOffset3D                                   srcOffsets[2];
4605
4606                                         defaultSourceLayer,     // VkImageSubresourceLayers     dstSubresource;
4607                                         {
4608                                                 {i, defaultSize / 2, 0},
4609                                                 {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
4610                                         }                                       // VkOffset3D                                   dstOffset[2];
4611                                 };
4612                                 region.imageBlit        = imageBlit;
4613                                 params.regions.push_back(region);
4614                         }
4615
4616                         addBlittingTestsAllFormats(blitImgAllFormatsTests.get(), testCtx, params);
4617                 }
4618
4619                 // Test Depth and Stencil formats.
4620                 {
4621                         const VkFormat  compatibleDepthAndStencilFormats[]      =
4622                         {
4623                                 VK_FORMAT_D16_UNORM,
4624                                 VK_FORMAT_X8_D24_UNORM_PACK32,
4625                                 VK_FORMAT_D32_SFLOAT,
4626                                 VK_FORMAT_S8_UINT,
4627                                 VK_FORMAT_D16_UNORM_S8_UINT,
4628                                 VK_FORMAT_D24_UNORM_S8_UINT,
4629                                 VK_FORMAT_D32_SFLOAT_S8_UINT,
4630                         };
4631
4632                         for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(compatibleDepthAndStencilFormats); ++compatibleFormatsIndex)
4633                         {
4634                                 TestParams params;
4635
4636                                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4637                                 params.src.image.extent         = defaultExtent;
4638                                 params.dst.image.extent         = defaultExtent;
4639                                 params.src.image.format         = compatibleDepthAndStencilFormats[compatibleFormatsIndex];
4640                                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4641                                 params.dst.image.format         = params.src.image.format;
4642                                 std::ostringstream      oss;
4643                                 oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
4644
4645                                 const VkImageSubresourceLayers  defaultDepthSourceLayer         = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
4646                                 const VkImageSubresourceLayers  defaultStencilSourceLayer       = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
4647
4648                                 CopyRegion      region;
4649                                 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
4650                                 {
4651                                         const VkOffset3D        srcOffset0      = {0, 0, 0};
4652                                         const VkOffset3D        srcOffset1      = {defaultSize, defaultSize, 1};
4653                                         const VkOffset3D        dstOffset0      = {i, 0, 0};
4654                                         const VkOffset3D        dstOffset1      = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
4655
4656                                         if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4657                                         {
4658                                                 const VkImageBlit                       imageBlit       =
4659                                                 {
4660                                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
4661                                                         { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
4662                                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
4663                                                         { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
4664                                                 };
4665                                                 region.imageBlit        = imageBlit;
4666                                                 params.regions.push_back(region);
4667                                         }
4668                                         if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4669                                         {
4670                                                 const VkImageBlit                       imageBlit       =
4671                                                 {
4672                                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
4673                                                         { srcOffset0 , srcOffset1 },    // VkOffset3D                                   srcOffsets[2];
4674                                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
4675                                                         { dstOffset0 , dstOffset1 },    // VkOffset3D                                   dstOffset[2];
4676                                                 };
4677                                                 region.imageBlit        = imageBlit;
4678                                                 params.regions.push_back(region);
4679                                         }
4680                                 }
4681                                 for (int i = 0; i < defaultSize; i += defaultFourthSize)
4682                                 {
4683                                         const VkOffset3D        srcOffset0      = {i, i, 0};
4684                                         const VkOffset3D        srcOffset1      = {i + defaultFourthSize, i + defaultFourthSize, 1};
4685                                         const VkOffset3D        dstOffset0      = {i, defaultSize / 2, 0};
4686                                         const VkOffset3D        dstOffset1      = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
4687
4688                                         if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4689                                         {
4690                                                 const VkImageBlit                       imageBlit       =
4691                                                 {
4692                                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     srcSubresource;
4693                                                         { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
4694                                                         defaultDepthSourceLayer,                // VkImageSubresourceLayers     dstSubresource;
4695                                                         { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
4696                                                 };
4697                                                 region.imageBlit        = imageBlit;
4698                                                 params.regions.push_back(region);
4699                                         }
4700                                         if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4701                                         {
4702                                                 const VkImageBlit                       imageBlit       =
4703                                                 {
4704                                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     srcSubresource;
4705                                                         { srcOffset0, srcOffset1 },             // VkOffset3D                                   srcOffsets[2];
4706                                                         defaultStencilSourceLayer,              // VkImageSubresourceLayers     dstSubresource;
4707                                                         { dstOffset0, dstOffset1 }              // VkOffset3D                                   dstOffset[2];
4708                                                 };
4709                                                 region.imageBlit        = imageBlit;
4710                                                 params.regions.push_back(region);
4711                                         }
4712                                 }
4713
4714                                 params.filter                   = VK_FILTER_NEAREST;
4715                                 blitImgAllFormatsTests->addChild(new BlittingTestCase(testCtx, oss.str() + "_nearest", description, params));
4716                         }
4717                 }
4718         }
4719         blittingImageTests->addChild(blitImgSimpleTests.release());
4720         blittingImageTests->addChild(blitImgAllFormatsTests.release());
4721
4722         // Resolve image to image testcases.
4723         const VkSampleCountFlagBits     samples[]               =
4724         {
4725                 VK_SAMPLE_COUNT_2_BIT,
4726                 VK_SAMPLE_COUNT_4_BIT,
4727                 VK_SAMPLE_COUNT_8_BIT,
4728                 VK_SAMPLE_COUNT_16_BIT,
4729                 VK_SAMPLE_COUNT_32_BIT,
4730                 VK_SAMPLE_COUNT_64_BIT
4731         };
4732         const VkExtent3D                        resolveExtent   = {256u, 256u, 1};
4733
4734         {
4735                 const std::string       description     ("Resolve from image to image");
4736                 const std::string       testName        ("whole");
4737
4738                 TestParams                      params;
4739                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4740                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4741                 params.src.image.extent         = resolveExtent;
4742                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4743                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4744                 params.dst.image.extent         = resolveExtent;
4745
4746                 {
4747                         const VkImageSubresourceLayers  sourceLayer     =
4748                         {
4749                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4750                                 0u,                                                     // uint32_t                             mipLevel;
4751                                 0u,                                                     // uint32_t                             baseArrayLayer;
4752                                 1u                                                      // uint32_t                             layerCount;
4753                         };
4754                         const VkImageResolve                    testResolve     =
4755                         {
4756                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
4757                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
4758                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
4759                                 {0, 0, 0},              // VkOffset3D                           dstOffset;
4760                                 resolveExtent,  // VkExtent3D                           extent;
4761                         };
4762
4763                         CopyRegion      imageResolve;
4764                         imageResolve.imageResolve       = testResolve;
4765                         params.regions.push_back(imageResolve);
4766                 }
4767
4768                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4769                 {
4770                         params.samples = samples[samplesIndex];
4771                         std::ostringstream caseName;
4772                         caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4773                         resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
4774                 }
4775         }
4776
4777         {
4778                 const std::string       description     ("Resolve from image to image");
4779                 const std::string       testName        ("partial");
4780
4781                 TestParams                      params;
4782                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4783                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4784                 params.src.image.extent         = resolveExtent;
4785                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4786                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4787                 params.dst.image.extent         = resolveExtent;
4788
4789                 {
4790                         const VkImageSubresourceLayers  sourceLayer     =
4791                         {
4792                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4793                                 0u,                                                     // uint32_t                             mipLevel;
4794                                 0u,                                                     // uint32_t                             baseArrayLayer;
4795                                 1u                                                      // uint32_t                             layerCount;
4796                         };
4797                         const VkImageResolve                    testResolve     =
4798                         {
4799                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
4800                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
4801                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
4802                                 {64u, 64u, 0},          // VkOffset3D                           dstOffset;
4803                                 {128u, 128u, 1u},       // VkExtent3D                           extent;
4804                         };
4805
4806                         CopyRegion      imageResolve;
4807                         imageResolve.imageResolve = testResolve;
4808                         params.regions.push_back(imageResolve);
4809                 }
4810
4811                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4812                 {
4813                         params.samples = samples[samplesIndex];
4814                         std::ostringstream caseName;
4815                         caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4816                         resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
4817                 }
4818         }
4819
4820         {
4821                 const std::string       description     ("Resolve from image to image");
4822                 const std::string       testName        ("with_regions");
4823
4824                 TestParams                      params;
4825                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4826                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4827                 params.src.image.extent         = resolveExtent;
4828                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4829                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4830                 params.dst.image.extent         = resolveExtent;
4831
4832                 {
4833                         const VkImageSubresourceLayers  sourceLayer     =
4834                         {
4835                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4836                                 0u,                                                     // uint32_t                             mipLevel;
4837                                 0u,                                                     // uint32_t                             baseArrayLayer;
4838                                 1u                                                      // uint32_t                             layerCount;
4839                         };
4840
4841                         for (int i = 0; i < 256; i += 64)
4842                         {
4843                                 const VkImageResolve                    testResolve     =
4844                                 {
4845                                         sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
4846                                         {i, i, 0},              // VkOffset3D                           srcOffset;
4847                                         sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
4848                                         {i, 0, 0},              // VkOffset3D                           dstOffset;
4849                                         {64u, 64u, 1u}, // VkExtent3D                           extent;
4850                                 };
4851
4852                                 CopyRegion      imageResolve;
4853                                 imageResolve.imageResolve = testResolve;
4854                                 params.regions.push_back(imageResolve);
4855                         }
4856                 }
4857
4858                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4859                 {
4860                         params.samples = samples[samplesIndex];
4861                         std::ostringstream caseName;
4862                         caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4863                         resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
4864                 }
4865         }
4866
4867         {
4868                 const std::string       description     ("Resolve from image to image");
4869                 const std::string       testName        ("whole_copy_before_resolving");
4870
4871                 TestParams                      params;
4872                 params.src.image.imageType      = VK_IMAGE_TYPE_2D;
4873                 params.src.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4874                 params.src.image.extent         = defaultExtent;
4875                 params.dst.image.imageType      = VK_IMAGE_TYPE_2D;
4876                 params.dst.image.format         = VK_FORMAT_R8G8B8A8_UNORM;
4877                 params.dst.image.extent         = defaultExtent;
4878
4879                 {
4880                         const VkImageSubresourceLayers  sourceLayer     =
4881                         {
4882                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
4883                                 0u,                                                     // uint32_t                             mipLevel;
4884                                 0u,                                                     // uint32_t                             baseArrayLayer;
4885                                 1u                                                      // uint32_t                             layerCount;
4886                         };
4887
4888                         const VkImageResolve                    testResolve     =
4889                         {
4890                                 sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
4891                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
4892                                 sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
4893                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
4894                                 defaultExtent,          // VkExtent3D                           extent;
4895                         };
4896
4897                         CopyRegion      imageResolve;
4898                         imageResolve.imageResolve       = testResolve;
4899                         params.regions.push_back(imageResolve);
4900                 }
4901
4902                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4903                 {
4904                         params.samples = samples[samplesIndex];
4905                         std::ostringstream caseName;
4906                         caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4907                         resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
4908                 }
4909         }
4910
4911         {
4912                 const std::string       description     ("Resolve from image to image");
4913                 const std::string       testName        ("whole_array_image");
4914
4915                 TestParams                      params;
4916                 params.src.image.imageType              = VK_IMAGE_TYPE_2D;
4917                 params.src.image.format                 = VK_FORMAT_R8G8B8A8_UNORM;
4918                 params.src.image.extent                 = defaultExtent;
4919                 params.dst.image.imageType              = VK_IMAGE_TYPE_2D;
4920                 params.dst.image.format                 = VK_FORMAT_R8G8B8A8_UNORM;
4921                 params.dst.image.extent                 = defaultExtent;
4922                 params.dst.image.extent.depth   = 5u;
4923
4924                 for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
4925                 {
4926                         const VkImageSubresourceLayers  sourceLayer     =
4927                         {
4928                                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
4929                                 0u,                                                             // uint32_t                             mipLevel;
4930                                 layerNdx,                                               // uint32_t                             baseArrayLayer;
4931                                 1u                                                              // uint32_t                             layerCount;
4932                         };
4933
4934                         const VkImageResolve                    testResolve     =
4935                         {
4936                                 sourceLayer,            // VkImageSubresourceLayers     srcSubresource;
4937                                 {0, 0, 0},                      // VkOffset3D                           srcOffset;
4938                                 sourceLayer,            // VkImageSubresourceLayers     dstSubresource;
4939                                 {0, 0, 0},                      // VkOffset3D                           dstOffset;
4940                                 defaultExtent,          // VkExtent3D                           extent;
4941                         };
4942
4943                         CopyRegion      imageResolve;
4944                         imageResolve.imageResolve       = testResolve;
4945                         params.regions.push_back(imageResolve);
4946                 }
4947
4948                 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4949                 {
4950                         params.samples = samples[samplesIndex];
4951                         std::ostringstream caseName;
4952                         caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4953                         resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
4954                 }
4955         }
4956
4957         copiesAndBlittingTests->addChild(imageToImageTests.release());
4958         copiesAndBlittingTests->addChild(imageToBufferTests.release());
4959         copiesAndBlittingTests->addChild(bufferToImageTests.release());
4960         copiesAndBlittingTests->addChild(bufferToBufferTests.release());
4961         copiesAndBlittingTests->addChild(blittingImageTests.release());
4962         copiesAndBlittingTests->addChild(resolveImageTests.release());
4963
4964         return copiesAndBlittingTests.release();
4965 }
4966
4967 } // api
4968 } // vkt