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