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