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