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