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