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