Merge branch 'jekstrand_renderpass_transfer_bit_fix' into 'master'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiCopiesAndBlittingTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Vulkan Copies And Blitting Tests
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktApiCopiesAndBlittingTests.hpp"
37
38 #include "deRandom.hpp"
39 #include "deStringUtil.hpp"
40 #include "deUniquePtr.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vktTestCase.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vkQueryUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vkTypeUtil.hpp"
48 #include "tcuImageCompare.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorType.hpp"
51 #include "tcuTexture.hpp"
52
53 namespace vkt
54 {
55
56 namespace api
57 {
58
59 using namespace vk;
60
61 namespace
62 {
63
64 union CopyRegion
65 {
66         VkBufferCopy            bufferCopy;
67         VkImageCopy                     imageCopy;
68         VkBufferImageCopy       bufferImageCopy;
69         VkImageBlit                     imageBlit;
70 };
71
72 struct TestParams
73 {
74         union Data
75         {
76                 struct Buffer
77                 {
78                         VkDeviceSize    size;
79                 }       buffer;
80                 struct Image
81                 {
82                         VkFormat                format;
83                         VkExtent3D              extent;
84                 }       image;
85         }       src, dst;
86
87         std::vector<CopyRegion> regions;
88 };
89
90 class CopiesAndBlittingTestInstance : public vkt::TestInstance
91 {
92 public:
93                                                                                 CopiesAndBlittingTestInstance           (Context&       context,
94                                                                                                                                                          TestParams     testParams);
95         virtual                                                         ~CopiesAndBlittingTestInstance          (void);
96         virtual tcu::TestStatus                         iterate                                                         (void) = 0;
97         enum FillMode
98         {
99                 FILL_MODE_SEQUENTIAL = 0,
100                 FILL_MODE_RANDOM,
101                 FILL_MODE_WHITE,
102                 FILL_MODE_RED,
103
104                 FILL_MODE_LAST
105         };
106 protected:
107         const TestParams                                        m_params;
108
109         Move<VkCommandPool>                                     m_cmdPool;
110         Move<VkCommandBuffer>                           m_cmdBuffer;
111         Move<VkFence>                                           m_fence;
112         de::MovePtr<tcu::TextureLevel>          m_sourceTextureLevel;
113         de::MovePtr<tcu::TextureLevel>          m_destinationTextureLevel;
114         de::MovePtr<tcu::TextureLevel>          m_expectedTextureLevel;
115
116         VkCommandBufferBeginInfo                        m_cmdBufferBeginInfo;
117
118         void                                                            generateBuffer                                          (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_SEQUENTIAL);
119         virtual void                                            generateExpectedResult                          (void);
120         void                                                            uploadBuffer                                            (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
121         void                                                            uploadImage                                                     (tcu::ConstPixelBufferAccess imageAccess, const VkImage& image);
122         virtual tcu::TestStatus                         checkTestResult                                         (tcu::ConstPixelBufferAccess result);
123         virtual void                                            copyRegionToTextureLevel                        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
124         VkImageAspectFlags                                      getAspectFlag                                           (tcu::TextureFormat format);
125         deUint32                                                        calculateSize                                           (tcu::ConstPixelBufferAccess src) const
126                                                                                 {
127                                                                                         return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
128                                                                                 }
129
130         de::MovePtr<tcu::TextureLevel>          readImage                                                       (const vk::DeviceInterface&     vk,
131                                                                                                                                                          vk::VkDevice                           device,
132                                                                                                                                                          vk::VkQueue                            queue,
133                                                                                                                                                          vk::Allocator&                         allocator,
134                                                                                                                                                          vk::VkImage                            image,
135                                                                                                                                                          vk::VkFormat                           format,
136                                                                                                                                                          const VkExtent3D                       imageSize);
137 };
138
139 CopiesAndBlittingTestInstance::~CopiesAndBlittingTestInstance   (void)
140 {
141 }
142
143 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance    (Context& context, TestParams testParams)
144         : vkt::TestInstance             (context)
145         , m_params                      (testParams)
146 {
147         const DeviceInterface&          vk                                      = context.getDeviceInterface();
148         const VkDevice                          vkDevice                        = context.getDevice();
149         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
150
151         // Create command pool
152         {
153                 const VkCommandPoolCreateInfo cmdPoolParams =
154                 {
155                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType              sType;
156                         DE_NULL,                                                                                // const void*                  pNext;
157                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCmdPoolCreateFlags flags;
158                         queueFamilyIndex,                                                               // deUint32                             queueFamilyIndex;
159                 };
160
161                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
162         }
163
164         // Create command buffer
165         {
166                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
167                 {
168                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
169                         DE_NULL,                                                                                // const void*                          pNext;
170                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
171                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
172                         1u                                                                                              // deUint32                                     bufferCount;
173                 };
174
175                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
176         }
177
178         // Create fence
179         {
180                 const VkFenceCreateInfo fenceParams =
181                 {
182                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
183                         DE_NULL,                                                                // const void*                  pNext;
184                         0u                                                                              // VkFenceCreateFlags   flags;
185                 };
186
187                 m_fence = createFence(vk, vkDevice, &fenceParams);
188         }
189 }
190
191 void CopiesAndBlittingTestInstance::generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
192 {
193         de::Random rnd(width ^ height ^ depth);
194         for (int z = 0; z < depth; z++)
195         {
196                 for (int y = 0; y < height; y++)
197                 {
198                         for (int x = 0; x < width; x++)
199                         {
200                                 switch (mode)
201                                 {
202                                         case FILL_MODE_SEQUENTIAL:
203                                                 buffer.setPixel(tcu::UVec4(x, y, z, 255), x, y, z);
204                                                 break;
205                                         case FILL_MODE_WHITE:
206                                                 buffer.setPixel(tcu::UVec4(255, 255, 255, 255), x, y, z);
207                                                 break;
208                                         case FILL_MODE_RED:
209                                                 buffer.setPixel(tcu::UVec4(255, 0, 0, 255), x, y, z);
210                                                 break;
211                                         case FILL_MODE_RANDOM:
212                                                 buffer.setPixel(tcu::UVec4(rnd.getUint8(), rnd.getUint8(), rnd.getUint8(), 255), x, y, z);
213                                         default:
214                                                 break;
215                                 }
216                         }
217                 }
218         }
219 }
220
221 void CopiesAndBlittingTestInstance::uploadBuffer(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
222 {
223         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
224         const VkDevice                          vkDevice        = m_context.getDevice();
225         const deUint32                          bufferSize      = calculateSize(bufferAccess);
226
227         // Write buffer data
228         deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
229         flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
230 }
231
232 void CopiesAndBlittingTestInstance::uploadImage(tcu::ConstPixelBufferAccess imageAccess, const VkImage& image)
233 {
234         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
235         const VkDevice                          vkDevice                        = m_context.getDevice();
236         const VkQueue                           queue                           = m_context.getUniversalQueue();
237         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
238         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
239
240         Move<VkBuffer>                          buffer;
241         const deUint32                          bufferSize              = calculateSize(imageAccess);
242         de::MovePtr<Allocation>         bufferAlloc;
243         Move<VkCommandBuffer>           cmdBuffer;
244         Move<VkFence>                           fence;
245
246         // Create source buffer
247         {
248                 const VkBufferCreateInfo                        bufferParams                    =
249                 {
250                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
251                         DE_NULL,                                                                        // const void*                  pNext;
252                         0u,                                                                                     // VkBufferCreateFlags  flags;
253                         bufferSize,                                                                     // VkDeviceSize                 size;
254                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
255                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
256                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
257                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
258                 };
259
260                 buffer          = createBuffer(vk, vkDevice, &bufferParams);
261                 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
262                 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
263         }
264
265         // Create command buffer
266         {
267                 const VkCommandBufferAllocateInfo       cmdBufferAllocateInfo   =
268                 {
269                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
270                         DE_NULL,                                                                                // const void*                          pNext;
271                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
272                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
273                         1u,                                                                                             // deUint32                                     bufferCount;
274                 };
275
276                 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
277         }
278
279         // Create fence
280         {
281                 const VkFenceCreateInfo                         fenceParams                             =
282                 {
283                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
284                         DE_NULL,                                                                        // const void*                  pNext;
285                         0u                                                                                      // VkFenceCreateFlags   flags;
286                 };
287
288                 fence = createFence(vk, vkDevice, &fenceParams);
289         }
290
291         // Barriers for copying buffer to image
292         const VkBufferMemoryBarrier                             preBufferBarrier                =
293         {
294                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType      sType;
295                 DE_NULL,                                                                                // const void*          pNext;
296                 VK_ACCESS_HOST_WRITE_BIT,                                               // VkAccessFlags        srcAccessMask;
297                 VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessFlags        dstAccessMask;
298                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     srcQueueFamilyIndex;
299                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                     dstQueueFamilyIndex;
300                 *buffer,                                                                                // VkBuffer                     buffer;
301                 0u,                                                                                             // VkDeviceSize         offset;
302                 bufferSize                                                                              // VkDeviceSize         size;
303         };
304
305         const VkImageMemoryBarrier                              preImageBarrier                 =
306         {
307                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
308                 DE_NULL,                                                                                // const void*                          pNext;
309                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
310                 0u,                                                                                             // VkAccessFlags                        dstAccessMask;
311                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
312                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        newLayout;
313                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
314                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
315                 image,                                                                                  // VkImage                                      image;
316                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
317                         getAspectFlag(imageAccess.getFormat()), // VkImageAspect        aspect;
318                         0u,                                                                             // deUint32                     baseMipLevel;
319                         1u,                                                                             // deUint32                     mipLevels;
320                         0u,                                                                             // deUint32                     baseArraySlice;
321                         1u,                                                                             // deUint32                     arraySize;
322                 }
323         };
324
325         const VkImageMemoryBarrier                              postImageBarrier                =
326         {
327                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
328                 DE_NULL,                                                                                // const void*                          pNext;
329                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                        srcAccessMask;
330                 VK_ACCESS_SHADER_READ_BIT,                                              // VkAccessFlags                        dstAccessMask;
331                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                        oldLayout;
332                 VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                        newLayout;
333                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
334                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
335                 image,                                                                                  // VkImage                                      image;
336                 {                                                                                               // VkImageSubresourceRange      subresourceRange;
337                         getAspectFlag(imageAccess.getFormat()), // VkImageAspect        aspect;
338                         0u,                                                                             // deUint32                     baseMipLevel;
339                         1u,                                                                             // deUint32                     mipLevels;
340                         0u,                                                                             // deUint32                     baseArraySlice;
341                         1u,                                                                             // deUint32                     arraySize;
342                 }
343         };
344
345         const VkBufferImageCopy                                 copyRegion                              =
346         {
347                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
348                 (deUint32)imageAccess.getWidth(),                               // deUint32                                     bufferRowLength;
349                 (deUint32)imageAccess.getHeight(),                              // deUint32                                     bufferImageHeight;
350                 {                                                                                               // VkImageSubresourceLayers     imageSubresource;
351                         getAspectFlag(imageAccess.getFormat()), // VkImageAspect        aspect;
352                         0u,                                                                             // deUint32                     mipLevel;
353                         0u,                                                                             // deUint32                     baseArrayLayer;
354                         1u,                                                                             // deUint32                     layerCount;
355                 },
356                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
357                 {
358                         (deUint32)imageAccess.getWidth(),
359                         (deUint32)imageAccess.getHeight(),
360                         1u
361                 }                                                                                               // VkExtent3D                           imageExtent;
362         };
363
364         // Write buffer data
365         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
366         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
367
368         // Copy buffer to image
369         const VkCommandBufferBeginInfo                  cmdBufferBeginInfo              =
370         {
371                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
372                 DE_NULL,                                                                                                // const void*                                          pNext;
373                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
374                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
375         };
376
377         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
378         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
379         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
380         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);
381         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
382
383         const VkSubmitInfo                                              submitInfo                              =
384         {
385                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
386                 DE_NULL,                                                // const void*                          pNext;
387                 0u,                                                             // deUint32                                     waitSemaphoreCount;
388                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
389                 (const VkPipelineStageFlags*)DE_NULL,
390                 1u,                                                             // deUint32                                     commandBufferCount;
391                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
392                 0u,                                                             // deUint32                                     signalSemaphoreCount;
393                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
394         };
395
396         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
397         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
398 }
399
400 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult(tcu::ConstPixelBufferAccess result)
401 {
402         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel->getAccess();
403         const tcu::UVec4                                        treshold        (0, 0, 0, 0);
404
405         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, treshold, tcu::COMPARE_LOG_RESULT))
406                 return tcu::TestStatus::fail("CopiesAndBlitting test");
407
408         return tcu::TestStatus::pass("CopiesAndBlitting test");
409 }
410
411 void CopiesAndBlittingTestInstance::generateExpectedResult()
412 {
413         const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
414         const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
415
416         m_expectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
417         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
418         for (deUint32 i = 0; i < m_params.regions.size(); i++)
419                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
420 }
421
422 class CopiesAndBlittingTestCase : public vkt::TestCase
423 {
424 public:
425                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
426                                                                                                                  const std::string&                     name,
427                                                                                                                  const std::string&                     description)
428                                                                 : vkt::TestCase                 (testCtx, name, description)
429                                                         {}
430
431         virtual                                 ~CopiesAndBlittingTestCase      (void) {}
432
433         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
434 };
435
436 VkImageAspectFlags CopiesAndBlittingTestInstance::getAspectFlag(tcu::TextureFormat format)
437 {
438         VkImageAspectFlags aspectFlag = 0;
439         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
440         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
441
442         if (!aspectFlag)
443                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
444
445         return aspectFlag;
446 }
447
448 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (const vk::DeviceInterface&     vk,
449                                                                                                                                                  vk::VkDevice                           device,
450                                                                                                                                                  vk::VkQueue                            queue,
451                                                                                                                                                  vk::Allocator&                         allocator,
452                                                                                                                                                  vk::VkImage                            image,
453                                                                                                                                                  vk::VkFormat                           format,
454                                                                                                                                                  const VkExtent3D                       imageSize)
455 {
456         Move<VkBuffer>                                  buffer;
457         de::MovePtr<Allocation>                 bufferAlloc;
458         Move<VkCommandBuffer>                   cmdBuffer;
459         Move<VkFence>                                   fence;
460         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
461         const tcu::TextureFormat                tcuFormat                       = mapVkFormat(format);
462         const VkDeviceSize                              pixelDataSize           = imageSize.width * imageSize.height * imageSize.depth * tcu::getPixelSize(tcuFormat);
463         de::MovePtr<tcu::TextureLevel>  resultLevel                     (new tcu::TextureLevel(tcuFormat, imageSize.width, imageSize.height, imageSize.depth));
464
465         // Create destination buffer
466         {
467                 const VkBufferCreateInfo bufferParams =
468                 {
469                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
470                         DE_NULL,                                                                        // const void*                  pNext;
471                         0u,                                                                                     // VkBufferCreateFlags  flags;
472                         pixelDataSize,                                                          // VkDeviceSize                 size;
473                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
474                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
475                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
476                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
477                 };
478
479                 buffer          = createBuffer(vk, device, &bufferParams);
480                 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
481                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
482         }
483
484         // Create command pool and buffer
485         {
486                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
487                 {
488                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
489                         DE_NULL,                                                                                // const void*                          pNext;
490                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
491                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
492                         1u                                                                                              // deUint32                                     bufferCount;
493                 };
494
495                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
496         }
497
498         // Create fence
499         {
500                 const VkFenceCreateInfo fenceParams =
501                 {
502                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
503                         DE_NULL,                                                                        // const void*                  pNext;
504                         0u                                                                                      // VkFenceCreateFlags   flags;
505                 };
506
507                 fence = createFence(vk, device, &fenceParams);
508         }
509
510         // Barriers for copying image to buffer
511
512         const VkImageMemoryBarrier imageBarrier =
513         {
514                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
515                 DE_NULL,                                                                        // const void*                          pNext;
516                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
517                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
518                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
519                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
520                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
521                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
522                 image,                                                                          // VkImage                                      image;
523                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
524                         getAspectFlag(tcuFormat),       // VkImageAspectFlags   aspectMask;
525                         0u,                                                     // deUint32                             baseMipLevel;
526                         1u,                                                     // deUint32                             mipLevels;
527                         0u,                                                     // deUint32                             baseArraySlice;
528                         1u                                                      // deUint32                             arraySize;
529                 }
530         };
531
532         const VkBufferMemoryBarrier bufferBarrier =
533         {
534                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
535                 DE_NULL,                                                                        // const void*          pNext;
536                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
537                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
538                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
539                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
540                 *buffer,                                                                        // VkBuffer                     buffer;
541                 0u,                                                                                     // VkDeviceSize         offset;
542                 pixelDataSize                                                           // VkDeviceSize         size;
543         };
544
545         // Copy image to buffer
546
547         const VkBufferImageCopy copyRegion =
548         {
549                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
550                 (deUint32)imageSize.width,                                      // deUint32                                     bufferRowLength;
551                 (deUint32)imageSize.height,                                     // deUint32                                     bufferImageHeight;
552                 { getAspectFlag(tcuFormat), 0u, 0u, 1u },       // VkImageSubresourceLayers     imageSubresource;
553                 { 0, 0, 0 },                                                            // VkOffset3D                           imageOffset;
554                 imageSize                                                                       // VkExtent3D                           imageExtent;
555         };
556
557         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
558         {
559                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
560                 DE_NULL,                                                                                                // const void*                                          pNext;
561                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
562                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
563         };
564
565         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
566         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);
567         vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
568         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);
569         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
570
571         const VkSubmitInfo submitInfo =
572         {
573                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
574                 DE_NULL,                                                // const void*                          pNext;
575                 0u,                                                             // deUint32                                     waitSemaphoreCount;
576                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
577                 (const VkPipelineStageFlags*)DE_NULL,
578                 1u,                                                             // deUint32                                     commandBufferCount;
579                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
580                 0u,                                                             // deUint32                                     signalSemaphoreCount;
581                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
582         };
583
584         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
585         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
586
587         // Read buffer data
588         invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
589         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
590
591         return resultLevel;
592 }
593
594 // Copy from image to image.
595
596 class CopyImageToImage : public CopiesAndBlittingTestInstance
597 {
598 public:
599                                                                                 CopyImageToImage                        (Context&       context,
600                                                                                                                                          TestParams params);
601         virtual tcu::TestStatus                         iterate                                         (void);
602 private:
603         Move<VkImage>                                           m_source;
604         de::MovePtr<Allocation>                         m_sourceImageAlloc;
605         Move<VkImage>                                           m_destination;
606         de::MovePtr<Allocation>                         m_destinationImageAlloc;
607
608         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
609 };
610
611 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
612         : CopiesAndBlittingTestInstance(context, params)
613 {
614         const DeviceInterface&          vk                                      = context.getDeviceInterface();
615         const VkDevice                          vkDevice                        = context.getDevice();
616         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
617         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
618
619         VkImageFormatProperties properties;
620         if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
621                                                                                                                                                                 m_params.src.image.format,
622                                                                                                                                                                 VK_IMAGE_TYPE_2D,
623                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
624                                                                                                                                                                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
625                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
626                 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
627                                                                                                                                                                 m_params.dst.image.format,
628                                                                                                                                                                 VK_IMAGE_TYPE_2D,
629                                                                                                                                                                 VK_IMAGE_TILING_OPTIMAL,
630                                                                                                                                                                 VK_FORMAT_FEATURE_BLIT_DST_BIT, 0,
631                                                                                                                                                                 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
632         {
633                 TCU_THROW(NotSupportedError, "Format not supported");
634         }
635
636         // Create source image
637         {
638                 const VkImageCreateInfo sourceImageParams =
639                 {
640                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
641                         DE_NULL,                                                                // const void*                  pNext;
642                         0u,                                                                             // VkImageCreateFlags   flags;
643                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
644                         m_params.src.image.format,                              // VkFormat                             format;
645                         m_params.src.image.extent,                              // VkExtent3D                   extent;
646                         1u,                                                                             // deUint32                             mipLevels;
647                         1u,                                                                             // deUint32                             arraySize;
648                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
649                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
650                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,                // VkImageUsageFlags    usage;
651                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
652                         1u,                                                                             // deUint32                             queueFamilyCount;
653                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
654                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
655                 };
656
657                 m_source = createImage(vk, vkDevice, &sourceImageParams);
658                 m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
659                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
660         }
661
662         // Create destination image
663         {
664                 const VkImageCreateInfo destinationImageParams =
665                 {
666                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
667                         DE_NULL,                                                                // const void*                  pNext;
668                         0u,                                                                             // VkImageCreateFlags   flags;
669                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
670                         m_params.dst.image.format,                              // VkFormat                             format;
671                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
672                         1u,                                                                             // deUint32                             mipLevels;
673                         1u,                                                                             // deUint32                             arraySize;
674                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
675                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
676                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,                // VkImageUsageFlags    usage;
677                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
678                         1u,                                                                             // deUint32                             queueFamilyCount;
679                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
680                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
681                 };
682
683                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
684                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
685                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
686         }
687 }
688
689 tcu::TestStatus CopyImageToImage::iterate()
690 {
691         tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
692         tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
693         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
694                                                                                                                                                                 m_params.src.image.extent.width,
695                                                                                                                                                                 m_params.src.image.extent.height,
696                                                                                                                                                                 m_params.src.image.extent.depth));
697         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);
698         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
699                                                                                                                                                                          (int)m_params.dst.image.extent.width,
700                                                                                                                                                                          (int)m_params.dst.image.extent.height,
701                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
702         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_SEQUENTIAL);
703         generateExpectedResult();
704
705         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get());
706         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
707
708         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
709         const VkDevice                          vkDevice                        = m_context.getDevice();
710         const VkQueue                           queue                           = m_context.getUniversalQueue();
711         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
712
713         VkImageCopy* imageCopies = ((VkImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkImageCopy)));
714         for (deUint32 i = 0; i < m_params.regions.size(); i++)
715                 imageCopies[i] = m_params.regions[i].imageCopy;
716
717         // Barriers for copying image to buffer
718         const VkImageMemoryBarrier srcImageBarrier =
719         {
720                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
721                 DE_NULL,                                                                        // const void*                          pNext;
722                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
723                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
724                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
725                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
726                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
727                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
728                 m_source.get(),                                                         // VkImage                                      image;
729                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
730                         getAspectFlag(srcTcuFormat),    // VkImageAspectFlags   aspectMask;
731                         0u,                                                     // deUint32                             baseMipLevel;
732                         1u,                                                     // deUint32                             mipLevels;
733                         0u,                                                     // deUint32                             baseArraySlice;
734                         1u                                                      // deUint32                             arraySize;
735                 }
736         };
737
738         const VkImageMemoryBarrier dstImageBarrier =
739         {
740                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
741                 DE_NULL,                                                                        // const void*                          pNext;
742                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
743                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
744                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
745                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
746                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
747                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
748                 m_destination.get(),                                            // VkImage                                      image;
749                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
750                         getAspectFlag(dstTcuFormat),    // VkImageAspectFlags   aspectMask;
751                         0u,                                                     // deUint32                             baseMipLevel;
752                         1u,                                                     // deUint32                             mipLevels;
753                         0u,                                                     // deUint32                             baseArraySlice;
754                         1u                                                      // deUint32                             arraySize;
755                 }
756         };
757
758         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
759         {
760                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
761                 DE_NULL,                                                                                                // const void*                                          pNext;
762                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
763                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
764         };
765
766         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
767         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);
768         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);
769         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);
770         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
771
772         const VkSubmitInfo submitInfo =
773         {
774                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
775                 DE_NULL,                                                // const void*                          pNext;
776                 0u,                                                             // deUint32                                     waitSemaphoreCount;
777                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
778                 (const VkPipelineStageFlags*)DE_NULL,
779                 1u,                                                             // deUint32                                     commandBufferCount;
780                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
781                 0u,                                                             // deUint32                                     signalSemaphoreCount;
782                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
783         };
784
785         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
786         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
787         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
788         deFree(imageCopies);
789
790         de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
791
792         return checkTestResult(resultTextureLevel->getAccess());
793 }
794
795 void CopyImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
796 {
797         VkOffset3D srcOffset    = region.imageCopy.srcOffset;
798         VkOffset3D dstOffset    = region.imageCopy.dstOffset;
799         VkExtent3D extent               = region.imageCopy.extent;
800
801         const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, extent.width, extent.height);
802         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
803         const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
804         const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, extent.width, extent.height);
805
806         tcu::copy(dstSubRegion, srcSubRegion);
807 }
808
809 class CopyImageToImageTestCase : public vkt::TestCase
810 {
811 public:
812                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
813                                                                                                                  const std::string&                             name,
814                                                                                                                  const std::string&                             description,
815                                                                                                                  const TestParams                               params)
816                                                                 : vkt::TestCase                 (testCtx, name, description)
817                                                                 , m_params                              (params)
818                                                         {}
819
820         virtual                                 ~CopyImageToImageTestCase       (void) {}
821
822         virtual TestInstance*   createInstance                          (Context&                                               context) const
823                                                         {
824                                                                 return new CopyImageToImage(context, m_params);
825                                                         }
826 private:
827         TestParams                              m_params;
828 };
829
830 // Copy from buffer to buffer.
831
832 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
833 {
834 public:
835                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
836         virtual tcu::TestStatus         iterate                                         (void);
837 private:
838         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
839         Move<VkBuffer>                          m_source;
840         de::MovePtr<Allocation>         m_sourceBufferAlloc;
841         Move<VkBuffer>                          m_destination;
842         de::MovePtr<Allocation>         m_destinationBufferAlloc;
843 };
844
845 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
846         : CopiesAndBlittingTestInstance (context, params)
847 {
848         const DeviceInterface&          vk                                      = context.getDeviceInterface();
849         const VkDevice                          vkDevice                        = context.getDevice();
850         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
851         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
852
853         // Create source buffer
854         {
855                 const VkBufferCreateInfo        sourceBufferParams      =
856                 {
857                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
858                         DE_NULL,                                                                        // const void*                  pNext;
859                         0u,                                                                                     // VkBufferCreateFlags  flags;
860                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
861                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
862                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
863                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
864                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
865                 };
866
867                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
868                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
869                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
870         }
871
872         // Create desctination buffer
873         {
874                 const VkBufferCreateInfo        destinationBufferParams =
875                 {
876                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
877                         DE_NULL,                                                                        // const void*                  pNext;
878                         0u,                                                                                     // VkBufferCreateFlags  flags;
879                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
880                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
881                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
882                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
883                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
884                 };
885
886                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
887                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
888                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
889         }
890 }
891
892 tcu::TestStatus CopyBufferToBuffer::iterate()
893 {
894         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
895         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
896         generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
897
898         const int dstLevelWidth = (int)(m_params.dst.buffer.size/4);
899         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
900         generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
901
902         generateExpectedResult();
903
904         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
905         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
906
907         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
908         const VkDevice                          vkDevice        = m_context.getDevice();
909         const VkQueue                           queue           = m_context.getUniversalQueue();
910
911         const VkBufferMemoryBarrier srcBufferBarrier =
912         {
913                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
914                 DE_NULL,                                                                        // const void*          pNext;
915                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
916                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
917                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
918                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
919                 *m_source,                                                                      // VkBuffer                     buffer;
920                 0u,                                                                                     // VkDeviceSize         offset;
921                 m_params.src.buffer.size                                        // VkDeviceSize         size;
922         };
923
924         const VkBufferMemoryBarrier dstBufferBarrier    =
925         {
926                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
927                 DE_NULL,                                                                        // const void*          pNext;
928                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
929                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
930                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
931                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
932                 *m_destination,                                                         // VkBuffer                     buffer;
933                 0u,                                                                                     // VkDeviceSize         offset;
934                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
935         };
936
937         VkBufferCopy* bufferCopies = ((VkBufferCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferCopy)));
938         for (deUint32 i = 0; i < m_params.regions.size(); i++)
939                 bufferCopies[i] = m_params.regions[i].bufferCopy;
940
941         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
942         {
943                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
944                 DE_NULL,                                                                                                // const void*                                          pNext;
945                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
946                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
947         };
948
949         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
950         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
951         vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), bufferCopies);
952         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);
953         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
954
955         const VkSubmitInfo submitInfo =
956         {
957                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
958                 DE_NULL,                                                // const void*                          pNext;
959                 0u,                                                             // deUint32                                     waitSemaphoreCount;
960                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
961                 (const VkPipelineStageFlags*)DE_NULL,
962                 1u,                                                             // deUint32                                     commandBufferCount;
963                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
964                 0u,                                                             // deUint32                                     signalSemaphoreCount;
965                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
966         };
967
968         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
969         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
970         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
971
972         // Read buffer data
973         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
974         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
975         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
976         deFree(bufferCopies);
977
978         return checkTestResult(resultLevel->getAccess());
979 }
980
981 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
982 {
983         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
984                                 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
985                                 (size_t)region.bufferCopy.size);
986 }
987
988 class BufferToBufferTestCase : public vkt::TestCase
989 {
990 public:
991                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
992                                                                                                          const std::string&     name,
993                                                                                                          const std::string&     description,
994                                                                                                          const TestParams       params)
995                                                                 : vkt::TestCase         (testCtx, name, description)
996                                                                 , m_params                      (params)
997                                                         {}
998         virtual                                 ~BufferToBufferTestCase (void) {}
999
1000         virtual TestInstance*   createInstance                  (Context& context) const
1001                                                         {
1002                                                                 return new CopyBufferToBuffer(context, m_params);
1003                                                         }
1004 private:
1005         TestParams                              m_params;
1006 };
1007
1008 // Copy from image to buffer.
1009
1010 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1011 {
1012 public:
1013                                                                 CopyImageToBuffer                       (Context&       context,
1014                                                                                                                          TestParams     testParams);
1015         virtual                                         ~CopyImageToBuffer                      (void) {}
1016         virtual tcu::TestStatus         iterate                                         (void);
1017 private:
1018         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1019
1020         tcu::TextureFormat                      m_textureFormat;
1021         VkDeviceSize                            m_bufferSize;
1022
1023         Move<VkImage>                           m_source;
1024         de::MovePtr<Allocation>         m_sourceImageAlloc;
1025         Move<VkBuffer>                          m_destination;
1026         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1027 };
1028
1029 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1030         : CopiesAndBlittingTestInstance(context, testParams)
1031         , m_textureFormat(mapVkFormat(testParams.src.image.format))
1032         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1033 {
1034         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1035         const VkDevice                          vkDevice                        = context.getDevice();
1036         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1037         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1038
1039         // Create source image
1040         {
1041                 const VkImageCreateInfo         sourceImageParams               =
1042                 {
1043                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1044                         DE_NULL,                                                                // const void*                  pNext;
1045                         0u,                                                                             // VkImageCreateFlags   flags;
1046                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1047                         m_params.src.image.format,                              // VkFormat                             format;
1048                         m_params.src.image.extent,                              // VkExtent3D                   extent;
1049                         1u,                                                                             // deUint32                             mipLevels;
1050                         1u,                                                                             // deUint32                             arraySize;
1051                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1052                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1053                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1054                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1055                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1056                         1u,                                                                             // deUint32                             queueFamilyCount;
1057                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1058                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1059                 };
1060
1061                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
1062                 m_sourceImageAlloc      = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1063                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1064         }
1065
1066         // Create destination buffer
1067         {
1068                 const VkBufferCreateInfo        destinationBufferParams =
1069                 {
1070                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1071                         DE_NULL,                                                                        // const void*                  pNext;
1072                         0u,                                                                                     // VkBufferCreateFlags  flags;
1073                         m_bufferSize,                                                           // VkDeviceSize                 size;
1074                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1075                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1076                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1077                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1078                 };
1079
1080                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1081                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1082                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1083         }
1084 }
1085
1086 tcu::TestStatus CopyImageToBuffer::iterate()
1087 {
1088         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1089                                                                                                                                                                 m_params.src.image.extent.width,
1090                                                                                                                                                                 m_params.src.image.extent.height,
1091                                                                                                                                                                 m_params.src.image.extent.depth));
1092         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);
1093         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1094         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1095
1096         generateExpectedResult();
1097
1098         uploadImage(m_sourceTextureLevel->getAccess(), *m_source);
1099         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1100
1101         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1102         const VkDevice                          vkDevice        = m_context.getDevice();
1103         const VkQueue                           queue           = m_context.getUniversalQueue();
1104
1105         // Barriers for copying image to buffer
1106         const VkImageMemoryBarrier imageBarrier =
1107         {
1108                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1109                 DE_NULL,                                                                        // const void*                          pNext;
1110                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1111                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1112                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
1113                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1114                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1115                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1116                 *m_source,                                                                      // VkImage                                      image;
1117                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1118                         getAspectFlag(m_textureFormat), // VkImageAspectFlags   aspectMask;
1119                         0u,                                                             // deUint32                             baseMipLevel;
1120                         1u,                                                             // deUint32                             mipLevels;
1121                         0u,                                                             // deUint32                             baseArraySlice;
1122                         1u                                                              // deUint32                             arraySize;
1123                 }
1124         };
1125
1126         const VkBufferMemoryBarrier bufferBarrier =
1127         {
1128                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1129                 DE_NULL,                                                                        // const void*          pNext;
1130                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1131                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1132                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1133                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1134                 *m_destination,                                                         // VkBuffer                     buffer;
1135                 0u,                                                                                     // VkDeviceSize         offset;
1136                 m_bufferSize                                                            // VkDeviceSize         size;
1137         };
1138
1139         // Copy from image to buffer
1140         VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1141         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1142                 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1143
1144         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1145         {
1146                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1147                 DE_NULL,                                                                                                // const void*                                          pNext;
1148                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1149                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1150         };
1151
1152         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1153         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);
1154         vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), bufferImageCopies);
1155         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);
1156         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1157
1158         const VkSubmitInfo                              submitInfo              =
1159         {
1160                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1161                 DE_NULL,                                                // const void*                          pNext;
1162                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1163                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1164                 (const VkPipelineStageFlags*)DE_NULL,
1165                 1u,                                                             // deUint32                                     commandBufferCount;
1166                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1167                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1168                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1169         };
1170
1171         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1172         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1173         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1174
1175         // Read buffer data
1176         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1177         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1178         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1179         deFree(bufferImageCopies);
1180
1181         return checkTestResult(resultLevel->getAccess());
1182 }
1183
1184 class CopyImageToBufferTestCase : public vkt::TestCase
1185 {
1186 public:
1187                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
1188                                                                                                                  const std::string&             name,
1189                                                                                                                  const std::string&             description,
1190                                                                                                                  const TestParams               params)
1191                                                                 : vkt::TestCase                 (testCtx, name, description)
1192                                                                 , m_params                              (params)
1193                                                         {}
1194
1195         virtual                                 ~CopyImageToBufferTestCase      (void) {}
1196
1197         virtual TestInstance*   createInstance                          (Context&                               context) const
1198                                                         {
1199                                                                 return new CopyImageToBuffer(context, m_params);
1200                                                         }
1201 private:
1202         TestParams                              m_params;
1203 };
1204
1205 void CopyImageToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1206 {
1207         deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1208         if (!rowLength)
1209                 rowLength = region.bufferImageCopy.imageExtent.width;
1210
1211         deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1212         if (!imageHeight)
1213                 imageHeight = region.bufferImageCopy.imageExtent.height;
1214
1215         const int                       texelSize       = src.getFormat().getPixelSize();
1216         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1217         const VkOffset3D        srcOffset       = region.bufferImageCopy.imageOffset;
1218         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1219
1220         for (deUint32 z = 0; z < extent.depth; z++)
1221         {
1222                 for (deUint32 y = 0; y < extent.height; y++)
1223                 {
1224                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) *  rowLength;
1225                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1226                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1227                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1228                         tcu::copy(dstSubRegion, srcSubRegion);
1229                 }
1230         }
1231 }
1232
1233 // Copy from buffer to image.
1234
1235 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1236 {
1237 public:
1238                                                                 CopyBufferToImage                       (Context&       context,
1239                                                                                                                          TestParams     testParams);
1240         virtual                                         ~CopyBufferToImage                      (void) {}
1241         virtual tcu::TestStatus         iterate                                         (void);
1242 private:
1243         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1244
1245         tcu::TextureFormat                      m_textureFormat;
1246         VkDeviceSize                            m_bufferSize;
1247
1248         Move<VkBuffer>                          m_source;
1249         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1250         Move<VkImage>                           m_destination;
1251         de::MovePtr<Allocation>         m_destinationImageAlloc;
1252 };
1253
1254 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1255         : CopiesAndBlittingTestInstance(context, testParams)
1256         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1257         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1258 {
1259         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1260         const VkDevice                          vkDevice                        = context.getDevice();
1261         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1262         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1263
1264         // Create source buffer
1265         {
1266                 const VkBufferCreateInfo        sourceBufferParams              =
1267                 {
1268                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1269                         DE_NULL,                                                                        // const void*                  pNext;
1270                         0u,                                                                                     // VkBufferCreateFlags  flags;
1271                         m_bufferSize,                                                           // VkDeviceSize                 size;
1272                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1273                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1274                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1275                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1276                 };
1277
1278                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1279                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1280                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1281         }
1282
1283         // Create destination image
1284         {
1285                 const VkImageCreateInfo         destinationImageParams  =
1286                 {
1287                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1288                         DE_NULL,                                                                // const void*                  pNext;
1289                         0u,                                                                             // VkImageCreateFlags   flags;
1290                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1291                         m_params.dst.image.format,                              // VkFormat                             format;
1292                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
1293                         1u,                                                                             // deUint32                             mipLevels;
1294                         1u,                                                                             // deUint32                             arraySize;
1295                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1296                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1297                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1298                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1299                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1300                         1u,                                                                             // deUint32                             queueFamilyCount;
1301                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1302                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1303                 };
1304
1305                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1306                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1307                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1308         }
1309 }
1310
1311 tcu::TestStatus CopyBufferToImage::iterate()
1312 {
1313         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1314         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);
1315         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1316                                                                                                                                                                         m_params.dst.image.extent.width,
1317                                                                                                                                                                         m_params.dst.image.extent.height,
1318                                                                                                                                                                         m_params.dst.image.extent.depth));
1319         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1, FILL_MODE_SEQUENTIAL);
1320
1321         generateExpectedResult();
1322
1323         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1324         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination);
1325
1326         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1327         const VkDevice                          vkDevice        = m_context.getDevice();
1328         const VkQueue                           queue           = m_context.getUniversalQueue();
1329         SimpleAllocator                         memAlloc        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1330
1331         // Barriers for copying image to buffer
1332         const VkBufferMemoryBarrier bufferBarrier =
1333         {
1334                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1335                 DE_NULL,                                                                        // const void*          pNext;
1336                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1337                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1338                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1339                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1340                 *m_source,                                                                      // VkBuffer                     buffer;
1341                 0u,                                                                                     // VkDeviceSize         offset;
1342                 m_bufferSize                                                            // VkDeviceSize         size;
1343         };
1344
1345         const VkImageMemoryBarrier imageBarrier =
1346         {
1347                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1348                 DE_NULL,                                                                        // const void*                          pNext;
1349                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1350                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1351                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
1352                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1353                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1354                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1355                 *m_destination,                                                         // VkImage                                      image;
1356                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1357                         getAspectFlag(m_textureFormat), // VkImageAspectFlags   aspectMask;
1358                         0u,                                                             // deUint32                             baseMipLevel;
1359                         1u,                                                             // deUint32                             mipLevels;
1360                         0u,                                                             // deUint32                             baseArraySlice;
1361                         1u                                                              // deUint32                             arraySize;
1362                 }
1363         };
1364
1365         // Copy from buffer to image
1366         VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1367         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1368                 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1369
1370         const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1371         {
1372                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1373                 DE_NULL,                                                                                                // const void*                                          pNext;
1374                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1375                 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1376         };
1377
1378         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1379         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);
1380         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies);
1381         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);
1382         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1383
1384         const VkSubmitInfo                              submitInfo              =
1385         {
1386                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1387                 DE_NULL,                                                // const void*                          pNext;
1388                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1389                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1390                 (const VkPipelineStageFlags*)DE_NULL,
1391                 1u,                                                             // deUint32                                     commandBufferCount;
1392                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1393                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1394                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1395         };
1396
1397         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1398         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1399         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1400
1401         // Read buffer data
1402         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
1403         deFree(bufferImageCopies);
1404
1405         return checkTestResult(resultLevel->getAccess());
1406 }
1407
1408 class CopyBufferToImageTestCase : public vkt::TestCase
1409 {
1410 public:
1411                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
1412                                                                                                                  const std::string&             name,
1413                                                                                                                  const std::string&             description,
1414                                                                                                                  const TestParams               params)
1415                                                                 : vkt::TestCase                 (testCtx, name, description)
1416                                                                 , m_params                              (params)
1417                                                         {}
1418
1419         virtual                                 ~CopyBufferToImageTestCase      (void) {}
1420
1421         virtual TestInstance*   createInstance                          (Context&                               context) const
1422                                                         {
1423                                                                 return new CopyBufferToImage(context, m_params);
1424                                                         }
1425 private:
1426         TestParams                              m_params;
1427 };
1428
1429 void CopyBufferToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1430 {
1431         deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1432         if (!rowLength)
1433                 rowLength = region.bufferImageCopy.imageExtent.width;
1434
1435         deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1436         if (!imageHeight)
1437                 imageHeight = region.bufferImageCopy.imageExtent.height;
1438
1439         const int                       texelSize       = dst.getFormat().getPixelSize();
1440         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1441         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
1442         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1443
1444         for (deUint32 z = 0; z < extent.depth; z++)
1445         {
1446                 for (deUint32 y = 0; y < extent.height; y++)
1447                 {
1448                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) *  rowLength;
1449                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1450                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1451                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1452                         tcu::copy(dstSubRegion, srcSubRegion);
1453                 }
1454         }
1455 }
1456
1457 } // anonymous
1458
1459 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
1460 {
1461         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests  (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
1462
1463         const VkExtent3D                                defaultExtent                   = {256, 256, 1};
1464         const VkImageSubresourceLayers  defaultSourceLayer              =
1465         {
1466                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1467                 0u,                                                     // uint32_t                             mipLevel;
1468                 0u,                                                     // uint32_t                             baseArrayLayer;
1469                 1u,                                                     // uint32_t                             layerCount;
1470         };
1471
1472         {
1473                 std::ostringstream description;
1474                 description << "Copy from image to image";
1475
1476                 TestParams      params;
1477                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1478                 params.src.image.extent = defaultExtent;
1479                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1480                 params.dst.image.extent = defaultExtent;
1481
1482                 {
1483                         const VkImageSubresourceLayers sourceLayer =
1484                         {
1485                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1486                                 0u,                                                     // uint32_t                             mipLevel;
1487                                 0u,                                                     // uint32_t                             baseArrayLayer;
1488                                 1u                                                      // uint32_t                             layerCount;
1489                         };
1490                         const VkImageCopy testCopy =
1491                         {
1492                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1493                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1494                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1495                                 {0, 0, 0},              // VkOffset3D                           dstOffset;
1496                                 {256, 256, 1},  // VkExtent3D                           extent;
1497                         };
1498
1499                         CopyRegion imageCopy;
1500                         imageCopy.imageCopy = testCopy;
1501
1502                         params.regions.push_back(imageCopy);
1503                 }
1504
1505                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "imageToImage_whole", description.str(), params));
1506         }
1507
1508         {
1509                 std::ostringstream description;
1510                 description << "Copy from image to image";
1511
1512                 TestParams      params;
1513                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1514                 params.src.image.extent = defaultExtent;
1515                 params.dst.image.format = VK_FORMAT_R32_UINT;
1516                 params.dst.image.extent = defaultExtent;
1517
1518                 {
1519                         const VkImageSubresourceLayers sourceLayer =
1520                         {
1521                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1522                                 0u,                                                     // uint32_t                             mipLevel;
1523                                 0u,                                                     // uint32_t                             baseArrayLayer;
1524                                 1u                                                      // uint32_t                             layerCount;
1525                         };
1526                         const VkImageCopy testCopy =
1527                         {
1528                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1529                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1530                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1531                                 {0, 0, 0},              // VkOffset3D                           dstOffset;
1532                                 {256, 256, 1},  // VkExtent3D                           extent;
1533                         };
1534
1535                         CopyRegion imageCopy;
1536                         imageCopy.imageCopy = testCopy;
1537
1538                         params.regions.push_back(imageCopy);
1539                 }
1540
1541                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_whole_different_format_uncompressed", description.str(), params));
1542         }
1543
1544         {
1545                 std::ostringstream description;
1546                 description << "Copy from image to image";
1547
1548                 TestParams      params;
1549                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1550                 params.src.image.extent = defaultExtent;
1551                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1552                 params.dst.image.extent = defaultExtent;
1553
1554                 {
1555                         const VkImageSubresourceLayers sourceLayer =
1556                         {
1557                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1558                                 0u,                                                     // uint32_t                             mipLevel;
1559                                 0u,                                                     // uint32_t                             baseArrayLayer;
1560                                 1u                                                      // uint32_t                             layerCount;
1561                         };
1562                         const VkImageCopy testCopy =
1563                         {
1564                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1565                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1566                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1567                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1568                                 {16, 16, 1},    // VkExtent3D                           extent;
1569                         };
1570
1571                         CopyRegion imageCopy;
1572                         imageCopy.imageCopy = testCopy;
1573
1574                         params.regions.push_back(imageCopy);
1575                 }
1576
1577                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial", description.str(), params));
1578         }
1579
1580         {
1581                 std::ostringstream description;
1582                 description << "Copy from image to image";
1583
1584                 TestParams      params;
1585                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1586                 params.src.image.extent = defaultExtent;
1587                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1588                 params.dst.image.extent = defaultExtent;
1589
1590                 for (deInt32 i = 0; i < 16; i++)
1591                 {
1592                         const VkImageSubresourceLayers sourceLayer =
1593                         {
1594                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1595                                 0u,                                                     // uint32_t                             mipLevel;
1596                                 0u,                                                     // uint32_t                             baseArrayLayer;
1597                                 1u                                                      // uint32_t                             layerCount;
1598                         };
1599                         const VkImageCopy testCopy =
1600                         {
1601                                 sourceLayer,                    // VkImageSubresourceLayers     srcSubresource;
1602                                 {0, 0, 0},                              // VkOffset3D                           srcOffset;
1603                                 sourceLayer,                    // VkImageSubresourceLayers     dstSubresource;
1604                                 {i*16, 240-i*16, 0},    // VkOffset3D                           dstOffset;
1605                                 {16, 16, 1},                    // VkExtent3D                           extent;
1606                         };
1607
1608                         CopyRegion imageCopy;
1609                         imageCopy.imageCopy = testCopy;
1610
1611                         params.regions.push_back(imageCopy);
1612                 }
1613
1614                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial_multiple", description.str(), params));
1615         }
1616
1617         // Copy image to buffer testcases.
1618         {
1619                 std::ostringstream      description;
1620                 description << "Copy from image to buffer";
1621
1622                 TestParams      params;
1623                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1624                 params.src.image.extent = defaultExtent;
1625                 params.dst.buffer.size  = 256 * 256;
1626
1627                 const VkBufferImageCopy                 bufferImageCopy =
1628                 {
1629                         0u,                                             // VkDeviceSize                         bufferOffset;
1630                         0u,                                             // uint32_t                                     bufferRowLength;
1631                         0u,                                             // uint32_t                                     bufferImageHeight;
1632                         defaultSourceLayer,             // VkImageSubresourceLayers     imageSubresource;
1633                         {0, 0, 0},                              // VkOffset3D                           imageOffset;
1634                         {16, 16, 1}                             // VkExtent3D                           imageExtent;
1635                 };
1636                 CopyRegion copyRegion;
1637                 copyRegion.bufferImageCopy = bufferImageCopy;
1638
1639                 params.regions.push_back(copyRegion);
1640
1641                 copiesAndBlittingTests->addChild(new CopyImageToBufferTestCase(testCtx, "image_to_buffer", description.str(), params));
1642         }
1643
1644         // Copy buffer to image testcases.
1645         {
1646                 std::ostringstream      description;
1647                 description << "Copy from buffer to image";
1648
1649                 TestParams      params;
1650                 params.src.buffer.size  = 256 * 256;
1651                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1652                 params.dst.image.extent = defaultExtent;
1653
1654                 const VkBufferImageCopy                 bufferImageCopy =
1655                 {
1656                         0u,                                             // VkDeviceSize                         bufferOffset;
1657                         0u,                                             // uint32_t                                     bufferRowLength;
1658                         0u,                                             // uint32_t                                     bufferImageHeight;
1659                         defaultSourceLayer,             // VkImageSubresourceLayers     imageSubresource;
1660                         {0, 0, 0},                              // VkOffset3D                           imageOffset;
1661                         {16, 16, 1}                             // VkExtent3D                           imageExtent;
1662                 };
1663                 CopyRegion copyRegion;
1664                 copyRegion.bufferImageCopy = bufferImageCopy;
1665
1666                 params.regions.push_back(copyRegion);
1667
1668                 copiesAndBlittingTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_to_image", description.str(), params));
1669         }
1670
1671         {
1672                 std::ostringstream      description;
1673                 description << "Copy from buffer to buffer: whole buffer.";
1674
1675                 TestParams params;
1676                 params.src.buffer.size = 256;
1677                 params.dst.buffer.size = 256;
1678                 const VkBufferCopy bufferCopy = {
1679                         0u,             // VkDeviceSize srcOffset;
1680                         0u,             // VkDeviceSize dstOffset;
1681                         256u,   // VkDeviceSize size;
1682                 };
1683                 CopyRegion copyRegion;
1684                 copyRegion.bufferCopy = bufferCopy;
1685
1686                 params.regions.push_back(copyRegion);
1687
1688                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_whole", description.str(), params));
1689         }
1690
1691         {
1692                 std::ostringstream      description;
1693                 description << "Copy from buffer to buffer: small area.";
1694
1695                 TestParams params;
1696                 params.src.buffer.size = 16;
1697                 params.dst.buffer.size = 16;
1698                 const VkBufferCopy bufferCopy = {
1699                         12u,    // VkDeviceSize srcOffset;
1700                         4u,             // VkDeviceSize dstOffset;
1701                         1u,             // VkDeviceSize size;
1702                 };
1703                 CopyRegion copyRegion;
1704                 copyRegion.bufferCopy = bufferCopy;
1705
1706                 params.regions.push_back(copyRegion);
1707
1708                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_small", description.str(), params));
1709         }
1710
1711         {
1712                 std::ostringstream      description;
1713                 description << "Copy from buffer to buffer: more regions.";
1714
1715                 const deUint32 size = 16;
1716
1717                 TestParams params;
1718                 params.src.buffer.size = size;
1719                 params.dst.buffer.size = size * (size + 1);
1720
1721                 // Copy region with size 0..size
1722                 for (unsigned int i = 0; i <= size; i++)
1723                 {
1724                         const VkBufferCopy bufferCopy = {
1725                                 0,              // VkDeviceSize srcOffset;
1726                                 i*size, // VkDeviceSize dstOffset;
1727                                 i,              // VkDeviceSize size;
1728                         };
1729                         CopyRegion copyRegion;
1730                         copyRegion.bufferCopy = bufferCopy;
1731                         params.regions.push_back(copyRegion);
1732                 }
1733                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_regions", description.str(), params));
1734         }
1735
1736         {
1737                 std::ostringstream description;
1738                 description << "Copy from image to image depth";
1739
1740                 TestParams      params;
1741                 params.src.image.format = VK_FORMAT_D32_SFLOAT;
1742                 params.src.image.extent = defaultExtent;
1743                 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
1744                 params.dst.image.extent = defaultExtent;
1745
1746                 {
1747                         const VkImageSubresourceLayers sourceLayer =
1748                         {
1749                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
1750                                 0u,                                                     // uint32_t                             mipLevel;
1751                                 0u,                                                     // uint32_t                             baseArrayLayer;
1752                                 1u                                                      // uint32_t                             layerCount;
1753                         };
1754                         const VkImageCopy testCopy =
1755                         {
1756                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1757                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1758                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1759                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1760                                 {16, 16, 1},    // VkExtent3D                           extent;
1761                         };
1762
1763                         CopyRegion imageCopy;
1764                         imageCopy.imageCopy = testCopy;
1765
1766                         params.regions.push_back(imageCopy);
1767                 }
1768
1769                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_depth", description.str(), params));
1770         }
1771
1772         {
1773                 std::ostringstream description;
1774                 description << "Copy from image to image stencil";
1775
1776                 TestParams      params;
1777                 params.src.image.format = VK_FORMAT_S8_UINT;
1778                 params.src.image.extent = defaultExtent;
1779                 params.dst.image.format = VK_FORMAT_S8_UINT;
1780                 params.dst.image.extent = defaultExtent;
1781
1782                 {
1783                         const VkImageSubresourceLayers sourceLayer =
1784                         {
1785                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
1786                                 0u,                                                             // uint32_t                             mipLevel;
1787                                 0u,                                                             // uint32_t                             baseArrayLayer;
1788                                 1u                                                              // uint32_t                             layerCount;
1789                         };
1790                         const VkImageCopy testCopy =
1791                         {
1792                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1793                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1794                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1795                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1796                                 {16, 16, 1},    // VkExtent3D                           extent;
1797                         };
1798
1799                         CopyRegion imageCopy;
1800                         imageCopy.imageCopy = testCopy;
1801
1802                         params.regions.push_back(imageCopy);
1803                 }
1804
1805                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_stencil", description.str(), params));
1806         }
1807
1808         return copiesAndBlittingTests.release();
1809 }
1810
1811 } // api
1812 } // vkt