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