am 52759610: (-s ours) am 22595308: Remove differing precision ubo tests from mustpas...
[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 void*                                                             preCopyBarriers[2]              =
346         {
347                 &preBufferBarrier,
348                 &preImageBarrier
349         };
350         const void* const                                               postCopyBarrier                 = &postImageBarrier;
351
352         const VkBufferImageCopy                                 copyRegion                              =
353         {
354                 0u,                                                                                             // VkDeviceSize                         bufferOffset;
355                 (deUint32)imageAccess.getWidth(),                               // deUint32                                     bufferRowLength;
356                 (deUint32)imageAccess.getHeight(),                              // deUint32                                     bufferImageHeight;
357                 {                                                                                               // VkImageSubresourceLayers     imageSubresource;
358                         getAspectFlag(imageAccess.getFormat()), // VkImageAspect        aspect;
359                         0u,                                                                             // deUint32                     mipLevel;
360                         0u,                                                                             // deUint32                     baseArrayLayer;
361                         1u,                                                                             // deUint32                     layerCount;
362                 },
363                 { 0, 0, 0 },                                                                    // VkOffset3D                           imageOffset;
364                 { imageAccess.getWidth(), imageAccess.getHeight(), 1u }                 // VkExtent3D                           imageExtent;
365         };
366
367         // Write buffer data
368         deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
369         flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
370
371         // Copy buffer to image
372         VkCommandBufferBeginInfo                                cmdBufferBeginInfo              =
373         {
374                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
375                 DE_NULL,                                                                                                // const void*                                          pNext;
376                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
377                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
378                 0u,                                                                                                             // deUint32                                                     subpass;
379                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
380                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
381                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
382                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
383         };
384
385         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
386         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 2u, preCopyBarriers);
387         vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
388         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1u, &postCopyBarrier);
389         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
390
391         const VkSubmitInfo                                              submitInfo                              =
392         {
393                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
394                 DE_NULL,                                                // const void*                          pNext;
395                 0u,                                                             // deUint32                                     waitSemaphoreCount;
396                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
397                 1u,                                                             // deUint32                                     commandBufferCount;
398                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
399                 0u,                                                             // deUint32                                     signalSemaphoreCount;
400                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
401         };
402
403         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
404         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
405 }
406
407 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult(tcu::ConstPixelBufferAccess result)
408 {
409         const tcu::ConstPixelBufferAccess       expected        = m_expectedTextureLevel->getAccess();
410         const tcu::UVec4                                        treshold        (0, 0, 0, 0);
411
412         if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, treshold, tcu::COMPARE_LOG_RESULT))
413                 return tcu::TestStatus::fail("CopiesAndBlitting test");
414
415         return tcu::TestStatus::pass("CopiesAndBlitting test");
416 }
417
418 void CopiesAndBlittingTestInstance::generateExpectedResult()
419 {
420         const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
421         const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
422
423         m_expectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
424         tcu::copy(m_expectedTextureLevel->getAccess(), dst);
425         for (deUint32 i = 0; i < m_params.regions.size(); i++)
426                 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
427 }
428
429 class CopiesAndBlittingTestCase : public vkt::TestCase
430 {
431 public:
432                                                         CopiesAndBlittingTestCase       (tcu::TestContext&                      testCtx,
433                                                                                                                  const std::string&                     name,
434                                                                                                                  const std::string&                     description)
435                                                                 : vkt::TestCase                 (testCtx, name, description)
436                                                         {}
437
438         virtual                                 ~CopiesAndBlittingTestCase      (void) {}
439
440         virtual TestInstance*   createInstance                          (Context&                                       context) const = 0;
441 };
442
443 VkImageAspectFlags CopiesAndBlittingTestInstance::getAspectFlag(tcu::TextureFormat format)
444 {
445         VkImageAspectFlags aspectFlag = 0;
446         aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
447         aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
448
449         if (!aspectFlag)
450                 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
451
452         return aspectFlag;
453 }
454
455 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (const vk::DeviceInterface&     vk,
456                                                                                                                                                  vk::VkDevice                           device,
457                                                                                                                                                  vk::VkQueue                            queue,
458                                                                                                                                                  vk::Allocator&                         allocator,
459                                                                                                                                                  vk::VkImage                            image,
460                                                                                                                                                  vk::VkFormat                           format,
461                                                                                                                                                  const VkExtent3D                       imageSize)
462 {
463         Move<VkBuffer>                                  buffer;
464         de::MovePtr<Allocation>                 bufferAlloc;
465         Move<VkCommandBuffer>                   cmdBuffer;
466         Move<VkFence>                                   fence;
467         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
468         const tcu::TextureFormat                tcuFormat                       = mapVkFormat(format);
469         const VkDeviceSize                              pixelDataSize           = imageSize.width * imageSize.height * imageSize.depth * tcu::getPixelSize(tcuFormat);
470         de::MovePtr<tcu::TextureLevel>  resultLevel                     (new tcu::TextureLevel(tcuFormat, imageSize.width, imageSize.height, imageSize.depth));
471
472         // Create destination buffer
473         {
474                 const VkBufferCreateInfo bufferParams =
475                 {
476                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
477                         DE_NULL,                                                                        // const void*                  pNext;
478                         0u,                                                                                     // VkBufferCreateFlags  flags;
479                         pixelDataSize,                                                          // VkDeviceSize                 size;
480                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
481                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
482                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
483                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
484                 };
485
486                 buffer          = createBuffer(vk, device, &bufferParams);
487                 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
488                 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
489         }
490
491         // Create command pool and buffer
492         {
493                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
494                 {
495                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
496                         DE_NULL,                                                                                // const void*                          pNext;
497                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
498                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
499                         1u                                                                                              // deUint32                                     bufferCount;
500                 };
501
502                 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
503         }
504
505         // Create fence
506         {
507                 const VkFenceCreateInfo fenceParams =
508                 {
509                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,            // VkStructureType              sType;
510                         DE_NULL,                                                                        // const void*                  pNext;
511                         0u                                                                                      // VkFenceCreateFlags   flags;
512                 };
513
514                 fence = createFence(vk, device, &fenceParams);
515         }
516
517         // Barriers for copying image to buffer
518
519         const VkImageMemoryBarrier imageBarrier =
520         {
521                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
522                 DE_NULL,                                                                        // const void*                          pNext;
523                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
524                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
525                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
526                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
527                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
528                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
529                 image,                                                                          // VkImage                                      image;
530                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
531                         getAspectFlag(tcuFormat),       // VkImageAspectFlags   aspectMask;
532                         0u,                                                     // deUint32                             baseMipLevel;
533                         1u,                                                     // deUint32                             mipLevels;
534                         0u,                                                     // deUint32                             baseArraySlice;
535                         1u                                                      // deUint32                             arraySize;
536                 }
537         };
538
539         const VkBufferMemoryBarrier bufferBarrier =
540         {
541                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
542                 DE_NULL,                                                                        // const void*          pNext;
543                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
544                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
545                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
546                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
547                 *buffer,                                                                        // VkBuffer                     buffer;
548                 0u,                                                                                     // VkDeviceSize         offset;
549                 pixelDataSize                                                           // VkDeviceSize         size;
550         };
551
552         const void* const       imageBarrierPtr         = &imageBarrier;
553         const void* const       bufferBarrierPtr        = &bufferBarrier;
554
555         // Copy image to buffer
556
557         const VkBufferImageCopy copyRegion =
558         {
559                 0u,                                                                                     // VkDeviceSize                         bufferOffset;
560                 (deUint32)imageSize.width,                                      // deUint32                                     bufferRowLength;
561                 (deUint32)imageSize.height,                                     // deUint32                                     bufferImageHeight;
562                 { getAspectFlag(tcuFormat), 0u, 0u, 1u },       // VkImageSubresourceLayers     imageSubresource;
563                 { 0, 0, 0 },                                                            // VkOffset3D                           imageOffset;
564                 imageSize                                                                       // VkExtent3D                           imageExtent;
565         };
566
567         VkCommandBufferBeginInfo cmdBufferBeginInfo =
568         {
569                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
570                 DE_NULL,                                                                                                // const void*                                          pNext;
571                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
572                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
573                 0u,                                                                                                             // deUint32                                                     subpass;
574                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
575                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
576                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
577                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
578         };
579
580         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
581         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &imageBarrierPtr);
582         vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, &copyRegion);
583         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &bufferBarrierPtr);
584         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
585
586         const VkSubmitInfo submitInfo =
587         {
588                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
589                 DE_NULL,                                                // const void*                          pNext;
590                 0u,                                                             // deUint32                                     waitSemaphoreCount;
591                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
592                 1u,                                                             // deUint32                                     commandBufferCount;
593                 &cmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers;
594                 0u,                                                             // deUint32                                     signalSemaphoreCount;
595                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
596         };
597
598         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
599         VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
600
601         // Read buffer data
602         invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
603         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
604
605         return resultLevel;
606 }
607
608 // Copy from image to image.
609
610 class CopyImageToImage : public CopiesAndBlittingTestInstance
611 {
612 public:
613                                                                                 CopyImageToImage                        (Context&       context,
614                                                                                                                                          TestParams params);
615         virtual tcu::TestStatus                         iterate                                         (void);
616 private:
617         Move<VkImage>                                           m_source;
618         de::MovePtr<Allocation>                         m_sourceImageAlloc;
619         Move<VkImage>                                           m_destination;
620         de::MovePtr<Allocation>                         m_destinationImageAlloc;
621
622         virtual void                                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
623 };
624
625 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
626         : CopiesAndBlittingTestInstance(context, params)
627 {
628         const DeviceInterface&          vk                                      = context.getDeviceInterface();
629         const VkDevice                          vkDevice                        = context.getDevice();
630         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
631         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
632
633         // Create source image
634         {
635                 const VkImageCreateInfo sourceImageParams =
636                 {
637                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
638                         DE_NULL,                                                                // const void*                  pNext;
639                         0u,                                                                             // VkImageCreateFlags   flags;
640                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
641                         m_params.src.image.format,                              // VkFormat                             format;
642                         m_params.src.image.extent,                              // VkExtent3D                   extent;
643                         1u,                                                                             // deUint32                             mipLevels;
644                         1u,                                                                             // deUint32                             arraySize;
645                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
646                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
647                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,                // VkImageUsageFlags    usage;
648                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
649                         1u,                                                                             // deUint32                             queueFamilyCount;
650                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
651                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
652                 };
653
654                 m_source = createImage(vk, vkDevice, &sourceImageParams);
655                 m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
656                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
657         }
658
659         // Create destination image
660         {
661                 const VkImageCreateInfo destinationImageParams =
662                 {
663                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
664                         DE_NULL,                                                                // const void*                  pNext;
665                         0u,                                                                             // VkImageCreateFlags   flags;
666                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
667                         m_params.dst.image.format,                              // VkFormat                             format;
668                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
669                         1u,                                                                             // deUint32                             mipLevels;
670                         1u,                                                                             // deUint32                             arraySize;
671                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
672                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
673                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,                // VkImageUsageFlags    usage;
674                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
675                         1u,                                                                             // deUint32                             queueFamilyCount;
676                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
677                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
678                 };
679
680                 m_destination = createImage(vk, vkDevice, &destinationImageParams);
681                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
682                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
683         }
684 }
685
686 tcu::TestStatus CopyImageToImage::iterate()
687 {
688         tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
689         tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
690         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
691                                                                                                                                                                 m_params.src.image.extent.width,
692                                                                                                                                                                 m_params.src.image.extent.height,
693                                                                                                                                                                 m_params.src.image.extent.depth));
694         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
695         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
696                                                                                                                                                                          (int)m_params.dst.image.extent.width,
697                                                                                                                                                                          (int)m_params.dst.image.extent.height,
698                                                                                                                                                                          (int)m_params.dst.image.extent.depth));
699         generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
700         generateExpectedResult();
701
702         uploadImage(m_sourceTextureLevel->getAccess(), m_source.get());
703         uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
704
705         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
706         const VkDevice                          vkDevice                        = m_context.getDevice();
707         const VkQueue                           queue                           = m_context.getUniversalQueue();
708         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
709
710         VkImageCopy* imageCopies = ((VkImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkImageCopy)));
711         for (deUint32 i = 0; i < m_params.regions.size(); i++)
712                 imageCopies[i] = m_params.regions[i].imageCopy;
713
714         // Barriers for copying image to buffer
715         const VkImageMemoryBarrier srcImageBarrier =
716         {
717                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
718                 DE_NULL,                                                                        // const void*                          pNext;
719                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
720                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
721                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
722                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
723                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
724                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
725                 m_source.get(),                                                         // VkImage                                      image;
726                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
727                         getAspectFlag(srcTcuFormat),    // VkImageAspectFlags   aspectMask;
728                         0u,                                                     // deUint32                             baseMipLevel;
729                         1u,                                                     // deUint32                             mipLevels;
730                         0u,                                                     // deUint32                             baseArraySlice;
731                         1u                                                      // deUint32                             arraySize;
732                 }
733         };
734
735         const VkImageMemoryBarrier dstImageBarrier =
736         {
737                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
738                 DE_NULL,                                                                        // const void*                          pNext;
739                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
740                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
741                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
742                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
743                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
744                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
745                 m_destination.get(),                                            // VkImage                                      image;
746                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
747                         getAspectFlag(dstTcuFormat),    // VkImageAspectFlags   aspectMask;
748                         0u,                                                     // deUint32                             baseMipLevel;
749                         1u,                                                     // deUint32                             mipLevels;
750                         0u,                                                     // deUint32                             baseArraySlice;
751                         1u                                                      // deUint32                             arraySize;
752                 }
753         };
754
755         const void* const       srcImageBarrierPtr              = &srcImageBarrier;
756         const void* const       dstImageBarrierPtr              = &dstImageBarrier;
757
758         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                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
764                 0u,                                                                                                             // deUint32                                                     subpass;
765                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
766                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
767                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
768                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
769         };
770
771         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
772         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &srcImageBarrierPtr);
773         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);
774         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &dstImageBarrierPtr);
775         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
776
777         const VkSubmitInfo submitInfo =
778         {
779                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
780                 DE_NULL,                                                // const void*                          pNext;
781                 0u,                                                             // deUint32                                     waitSemaphoreCount;
782                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
783                 1u,                                                             // deUint32                                     commandBufferCount;
784                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
785                 0u,                                                             // deUint32                                     signalSemaphoreCount;
786                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
787         };
788
789         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
790         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
791         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
792         deFree(imageCopies);
793
794         de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
795
796         return checkTestResult(resultTextureLevel->getAccess());
797 }
798
799 void CopyImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
800 {
801         VkOffset3D srcOffset    = region.imageCopy.srcOffset;
802         VkOffset3D dstOffset    = region.imageCopy.dstOffset;
803         VkExtent3D extent               = region.imageCopy.extent;
804
805         const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, extent.width, extent.height);
806         // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
807         const tcu::PixelBufferAccess            dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
808         const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, extent.width, extent.height);
809
810         tcu::copy(dstSubRegion, srcSubRegion);
811 }
812
813 class CopyImageToImageTestCase : public vkt::TestCase
814 {
815 public:
816                                                         CopyImageToImageTestCase        (tcu::TestContext&                              testCtx,
817                                                                                                                  const std::string&                             name,
818                                                                                                                  const std::string&                             description,
819                                                                                                                  const TestParams                               params)
820                                                                 : vkt::TestCase                 (testCtx, name, description)
821                                                                 , m_params                              (params)
822                                                         {}
823
824         virtual                                 ~CopyImageToImageTestCase       (void) {}
825
826         virtual TestInstance*   createInstance                          (Context&                                               context) const
827                                                         {
828                                                                 return new CopyImageToImage(context, m_params);
829                                                         }
830 private:
831         TestParams                              m_params;
832 };
833
834 // Copy from buffer to buffer.
835
836 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
837 {
838 public:
839                                                                 CopyBufferToBuffer                      (Context& context, TestParams params);
840         virtual tcu::TestStatus         iterate                                         (void);
841 private:
842         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
843         Move<VkBuffer>                          m_source;
844         de::MovePtr<Allocation>         m_sourceBufferAlloc;
845         Move<VkBuffer>                          m_destination;
846         de::MovePtr<Allocation>         m_destinationBufferAlloc;
847 };
848
849 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
850         : CopiesAndBlittingTestInstance (context, params)
851 {
852         const DeviceInterface&          vk                                      = context.getDeviceInterface();
853         const VkDevice                          vkDevice                        = context.getDevice();
854         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
855         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
856
857         // Create source buffer
858         {
859                 const VkBufferCreateInfo        sourceBufferParams      =
860                 {
861                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
862                         DE_NULL,                                                                        // const void*                  pNext;
863                         0u,                                                                                     // VkBufferCreateFlags  flags;
864                         m_params.src.buffer.size,                                       // VkDeviceSize                 size;
865                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
866                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
867                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
868                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
869                 };
870
871                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
872                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
873                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
874         }
875
876         // Create desctination buffer
877         {
878                 const VkBufferCreateInfo        destinationBufferParams =
879                 {
880                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
881                         DE_NULL,                                                                        // const void*                  pNext;
882                         0u,                                                                                     // VkBufferCreateFlags  flags;
883                         m_params.dst.buffer.size,                                       // VkDeviceSize                 size;
884                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
885                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
886                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
887                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
888                 };
889
890                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
891                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
892                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
893         }
894 }
895
896 tcu::TestStatus CopyBufferToBuffer::iterate()
897 {
898         m_sourceTextureLevel            = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), (int)m_params.src.buffer.size, 1));
899         generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1, FILL_MODE_RED);
900         m_destinationTextureLevel       = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), (int)m_params.dst.buffer.size, 1));
901         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1, FILL_MODE_WHITE);
902
903         generateExpectedResult();
904
905         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
906         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
907
908         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
909         const VkDevice                          vkDevice        = m_context.getDevice();
910         const VkQueue                           queue           = m_context.getUniversalQueue();
911
912         const VkBufferMemoryBarrier srcBufferBarrier =
913         {
914                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
915                 DE_NULL,                                                                        // const void*          pNext;
916                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
917                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
918                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
919                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
920                 *m_source,                                                                      // VkBuffer                     buffer;
921                 0u,                                                                                     // VkDeviceSize         offset;
922                 m_params.src.buffer.size                                        // VkDeviceSize         size;
923         };
924
925         const VkBufferMemoryBarrier dstBufferBarrier    =
926         {
927                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
928                 DE_NULL,                                                                        // const void*          pNext;
929                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
930                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
931                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
932                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
933                 *m_destination,                                                         // VkBuffer                     buffer;
934                 0u,                                                                                     // VkDeviceSize         offset;
935                 m_params.dst.buffer.size                                        // VkDeviceSize         size;
936         };
937
938         const void* const srcBufferBarrierPtr = &srcBufferBarrier;
939         const void* const dstBufferBarrierPtr = &dstBufferBarrier;
940
941         VkBufferCopy* bufferCopies = ((VkBufferCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferCopy)));
942         for (deUint32 i = 0; i < m_params.regions.size(); i++)
943                 bufferCopies[i] = m_params.regions[i].bufferCopy;
944
945         VkCommandBufferBeginInfo cmdBufferBeginInfo =
946         {
947                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
948                 DE_NULL,                                                                                                // const void*                                          pNext;
949                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
950                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
951                 0u,                                                                                                             // deUint32                                                     subpass;
952                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
953                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
954                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
955                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
956         };
957
958         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
959         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &srcBufferBarrierPtr);
960         vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), bufferCopies);
961         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &dstBufferBarrierPtr);
962         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
963
964         const VkSubmitInfo submitInfo =
965         {
966                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
967                 DE_NULL,                                                // const void*                          pNext;
968                 0u,                                                             // deUint32                                     waitSemaphoreCount;
969                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
970                 1u,                                                             // deUint32                                     commandBufferCount;
971                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
972                 0u,                                                             // deUint32                                     signalSemaphoreCount;
973                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
974         };
975
976         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
977         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
978         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
979
980         // Read buffer data
981         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), (int)m_params.dst.buffer.size, 1));
982         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
983         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
984         deFree(bufferCopies);
985
986         return checkTestResult(resultLevel->getAccess());
987 }
988
989 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
990 {
991         deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
992                                 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
993                                 (size_t)region.bufferCopy.size);
994 }
995
996 class BufferToBufferTestCase : public vkt::TestCase
997 {
998 public:
999                                                         BufferToBufferTestCase  (tcu::TestContext&      testCtx,
1000                                                                                                          const std::string&     name,
1001                                                                                                          const std::string&     description,
1002                                                                                                          const TestParams       params)
1003                                                                 : vkt::TestCase         (testCtx, name, description)
1004                                                                 , m_params                      (params)
1005                                                         {}
1006         virtual                                 ~BufferToBufferTestCase (void) {}
1007
1008         virtual TestInstance*   createInstance                  (Context& context) const
1009                                                         {
1010                                                                 return new CopyBufferToBuffer(context, m_params);
1011                                                         }
1012 private:
1013         TestParams                              m_params;
1014 };
1015
1016 // Copy from image to buffer.
1017
1018 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1019 {
1020 public:
1021                                                                 CopyImageToBuffer                       (Context&       context,
1022                                                                                                                          TestParams     testParams);
1023         virtual                                         ~CopyImageToBuffer                      (void) {}
1024         virtual tcu::TestStatus         iterate                                         (void);
1025 private:
1026         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1027
1028         tcu::TextureFormat                      m_textureFormat;
1029         VkDeviceSize                            m_bufferSize;
1030
1031         Move<VkImage>                           m_source;
1032         de::MovePtr<Allocation>         m_sourceImageAlloc;
1033         Move<VkBuffer>                          m_destination;
1034         de::MovePtr<Allocation>         m_destinationBufferAlloc;
1035 };
1036
1037 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1038         : CopiesAndBlittingTestInstance(context, testParams)
1039         , m_textureFormat(mapVkFormat(testParams.src.image.format))
1040         , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1041 {
1042         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1043         const VkDevice                          vkDevice                        = context.getDevice();
1044         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1045         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1046
1047         // Create source image
1048         {
1049                 const VkImageCreateInfo         sourceImageParams               =
1050                 {
1051                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1052                         DE_NULL,                                                                // const void*                  pNext;
1053                         0u,                                                                             // VkImageCreateFlags   flags;
1054                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1055                         m_params.src.image.format,                              // VkFormat                             format;
1056                         m_params.src.image.extent,                              // VkExtent3D                   extent;
1057                         1u,                                                                             // deUint32                             mipLevels;
1058                         1u,                                                                             // deUint32                             arraySize;
1059                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1060                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1061                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1062                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1063                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1064                         1u,                                                                             // deUint32                             queueFamilyCount;
1065                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1066                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1067                 };
1068
1069                 m_source                        = createImage(vk, vkDevice, &sourceImageParams);
1070                 m_sourceImageAlloc      = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1071                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1072         }
1073
1074         // Create destination buffer
1075         {
1076                 const VkBufferCreateInfo        destinationBufferParams =
1077                 {
1078                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1079                         DE_NULL,                                                                        // const void*                  pNext;
1080                         0u,                                                                                     // VkBufferCreateFlags  flags;
1081                         m_bufferSize,                                                           // VkDeviceSize                 size;
1082                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
1083                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1084                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1085                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1086                 };
1087
1088                 m_destination                           = createBuffer(vk, vkDevice, &destinationBufferParams);
1089                 m_destinationBufferAlloc        = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1090                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1091         }
1092 }
1093
1094 tcu::TestStatus CopyImageToBuffer::iterate()
1095 {
1096         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1097                                                                                                                                                                 m_params.src.image.extent.width,
1098                                                                                                                                                                 m_params.src.image.extent.height,
1099                                                                                                                                                                 m_params.src.image.extent.depth));
1100         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);
1101         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1102         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1103
1104         generateExpectedResult();
1105
1106         uploadImage(m_sourceTextureLevel->getAccess(), *m_source);
1107         uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1108
1109         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1110         const VkDevice                          vkDevice        = m_context.getDevice();
1111         const VkQueue                           queue           = m_context.getUniversalQueue();
1112
1113         // Barriers for copying image to buffer
1114         const VkImageMemoryBarrier imageBarrier =
1115         {
1116                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1117                 DE_NULL,                                                                        // const void*                          pNext;
1118                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1119                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1120                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
1121                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1122                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1123                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1124                 *m_source,                                                                      // VkImage                                      image;
1125                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1126                         getAspectFlag(m_textureFormat), // VkImageAspectFlags   aspectMask;
1127                         0u,                                                             // deUint32                             baseMipLevel;
1128                         1u,                                                             // deUint32                             mipLevels;
1129                         0u,                                                             // deUint32                             baseArraySlice;
1130                         1u                                                              // deUint32                             arraySize;
1131                 }
1132         };
1133
1134         const VkBufferMemoryBarrier bufferBarrier =
1135         {
1136                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1137                 DE_NULL,                                                                        // const void*          pNext;
1138                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1139                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1140                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1141                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1142                 *m_destination,                                                         // VkBuffer                     buffer;
1143                 0u,                                                                                     // VkDeviceSize         offset;
1144                 m_bufferSize                                                            // VkDeviceSize         size;
1145         };
1146
1147         const void* const       imageBarrierPtr         = &imageBarrier;
1148         const void* const       bufferBarrierPtr        = &bufferBarrier;
1149
1150         // Copy from image to buffer
1151         VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1152         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1153                 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1154
1155         VkCommandBufferBeginInfo cmdBufferBeginInfo =
1156         {
1157                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1158                 DE_NULL,                                                                                                // const void*                                          pNext;
1159                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1160                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
1161                 0u,                                                                                                             // deUint32                                                     subpass;
1162                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
1163                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
1164                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
1165                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
1166         };
1167
1168         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1169         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &imageBarrierPtr);
1170         vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), bufferImageCopies);
1171         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &bufferBarrierPtr);
1172         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1173
1174         const VkSubmitInfo                              submitInfo              =
1175         {
1176                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1177                 DE_NULL,                                                // const void*                          pNext;
1178                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1179                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1180                 1u,                                                             // deUint32                                     commandBufferCount;
1181                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1182                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1183                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1184         };
1185
1186         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1187         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1188         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1189
1190         // Read buffer data
1191         de::MovePtr<tcu::TextureLevel>  resultLevel             (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1192         invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1193         tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1194         deFree(bufferImageCopies);
1195
1196         return checkTestResult(resultLevel->getAccess());
1197 }
1198
1199 class CopyImageToBufferTestCase : public vkt::TestCase
1200 {
1201 public:
1202                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
1203                                                                                                                  const std::string&             name,
1204                                                                                                                  const std::string&             description,
1205                                                                                                                  const TestParams               params)
1206                                                                 : vkt::TestCase                 (testCtx, name, description)
1207                                                                 , m_params                              (params)
1208                                                         {}
1209
1210         virtual                                 ~CopyImageToBufferTestCase      (void) {}
1211
1212         virtual TestInstance*   createInstance                          (Context&                               context) const
1213                                                         {
1214                                                                 return new CopyImageToBuffer(context, m_params);
1215                                                         }
1216 private:
1217         TestParams                              m_params;
1218 };
1219
1220 void CopyImageToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1221 {
1222         deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1223         if (!rowLength)
1224                 rowLength = region.bufferImageCopy.imageExtent.width;
1225
1226         deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1227         if (!imageHeight)
1228                 imageHeight = region.bufferImageCopy.imageExtent.height;
1229
1230         const int                       texelSize       = src.getFormat().getPixelSize();
1231         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1232         const VkOffset3D        srcOffset       = region.bufferImageCopy.imageOffset;
1233         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1234
1235         for (int z = 0; z < extent.depth; z++)
1236         {
1237                 for (int y = 0; y < extent.height; y++)
1238                 {
1239                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) *  rowLength;
1240                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1241                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1242                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1243                         tcu::copy(dstSubRegion, srcSubRegion);
1244                 }
1245         }
1246 }
1247
1248 // Copy from buffer to image.
1249
1250 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1251 {
1252 public:
1253                                                                 CopyBufferToImage                       (Context&       context,
1254                                                                                                                          TestParams     testParams);
1255         virtual                                         ~CopyBufferToImage                      (void) {}
1256         virtual tcu::TestStatus         iterate                                         (void);
1257 private:
1258         virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1259
1260         tcu::TextureFormat                      m_textureFormat;
1261         VkDeviceSize                            m_bufferSize;
1262
1263         Move<VkBuffer>                          m_source;
1264         de::MovePtr<Allocation>         m_sourceBufferAlloc;
1265         Move<VkImage>                           m_destination;
1266         de::MovePtr<Allocation>         m_destinationImageAlloc;
1267 };
1268
1269 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1270         : CopiesAndBlittingTestInstance(context, testParams)
1271         , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1272         , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1273 {
1274         const DeviceInterface&          vk                                      = context.getDeviceInterface();
1275         const VkDevice                          vkDevice                        = context.getDevice();
1276         const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
1277         SimpleAllocator                         memAlloc                        (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1278
1279         // Create source buffer
1280         {
1281                 const VkBufferCreateInfo        sourceBufferParams              =
1282                 {
1283                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1284                         DE_NULL,                                                                        // const void*                  pNext;
1285                         0u,                                                                                     // VkBufferCreateFlags  flags;
1286                         m_bufferSize,                                                           // VkDeviceSize                 size;
1287                         VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
1288                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1289                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1290                         &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
1291                 };
1292
1293                 m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
1294                 m_sourceBufferAlloc             = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1295                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1296         }
1297
1298         // Create destination image
1299         {
1300                 const VkImageCreateInfo         destinationImageParams  =
1301                 {
1302                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
1303                         DE_NULL,                                                                // const void*                  pNext;
1304                         0u,                                                                             // VkImageCreateFlags   flags;
1305                         VK_IMAGE_TYPE_2D,                                               // VkImageType                  imageType;
1306                         m_params.dst.image.format,                              // VkFormat                             format;
1307                         m_params.dst.image.extent,                              // VkExtent3D                   extent;
1308                         1u,                                                                             // deUint32                             mipLevels;
1309                         1u,                                                                             // deUint32                             arraySize;
1310                         VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
1311                         VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
1312                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1313                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
1314                         VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
1315                         1u,                                                                             // deUint32                             queueFamilyCount;
1316                         &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
1317                         VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
1318                 };
1319
1320                 m_destination                   = createImage(vk, vkDevice, &destinationImageParams);
1321                 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1322                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1323         }
1324 }
1325
1326 tcu::TestStatus CopyBufferToImage::iterate()
1327 {
1328         m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1329         generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1330         m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1331                                                                                                                                                                         m_params.dst.image.extent.width,
1332                                                                                                                                                                         m_params.dst.image.extent.height,
1333                                                                                                                                                                         m_params.dst.image.extent.depth));
1334         generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1335
1336         generateExpectedResult();
1337
1338         uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1339         uploadImage(m_destinationTextureLevel->getAccess(), *m_destination);
1340
1341         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
1342         const VkDevice                          vkDevice        = m_context.getDevice();
1343         const VkQueue                           queue           = m_context.getUniversalQueue();
1344         SimpleAllocator                         memAlloc        (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1345
1346         // Barriers for copying image to buffer
1347         const VkBufferMemoryBarrier bufferBarrier =
1348         {
1349                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
1350                 DE_NULL,                                                                        // const void*          pNext;
1351                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags        srcAccessMask;
1352                 VK_ACCESS_HOST_READ_BIT,                                        // VkAccessFlags        dstAccessMask;
1353                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
1354                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     dstQueueFamilyIndex;
1355                 *m_source,                                                                      // VkBuffer                     buffer;
1356                 0u,                                                                                     // VkDeviceSize         offset;
1357                 m_bufferSize                                                            // VkDeviceSize         size;
1358         };
1359
1360         const VkImageMemoryBarrier imageBarrier =
1361         {
1362                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
1363                 DE_NULL,                                                                        // const void*                          pNext;
1364                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
1365                 VK_ACCESS_TRANSFER_READ_BIT,                            // VkAccessFlags                        dstAccessMask;
1366                 VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                        oldLayout;
1367                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,           // VkImageLayout                        newLayout;
1368                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
1369                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
1370                 *m_destination,                                                         // VkImage                                      image;
1371                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
1372                         getAspectFlag(m_textureFormat), // VkImageAspectFlags   aspectMask;
1373                         0u,                                                             // deUint32                             baseMipLevel;
1374                         1u,                                                             // deUint32                             mipLevels;
1375                         0u,                                                             // deUint32                             baseArraySlice;
1376                         1u                                                              // deUint32                             arraySize;
1377                 }
1378         };
1379
1380         const void* const       bufferBarrierPtr        = &bufferBarrier;
1381         const void* const       imageBarrierPtr         = &imageBarrier;
1382
1383         // Copy from buffer to image
1384         VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1385         for (deUint32 i = 0; i < m_params.regions.size(); i++)
1386                 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1387
1388         VkCommandBufferBeginInfo cmdBufferBeginInfo =
1389         {
1390                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                    // VkStructureType                                      sType;
1391                 DE_NULL,                                                                                                // const void*                                          pNext;
1392                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,                    // VkCommandBufferUsageFlags            flags;
1393                 DE_NULL,                                                                                                // VkRenderPass                                         renderPass;
1394                 0u,                                                                                                             // deUint32                                                     subpass;
1395                 DE_NULL,                                                                                                // VkFramebuffer                                        framebuffer;
1396                 false,                                                                                                  // VkBool32                                                     occlusionQueryEnable;
1397                 0u,                                                                                                             // VkQueryControlFlags                          queryFlags;
1398                 0u                                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
1399         };
1400
1401         VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1402         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_FALSE, 1, &bufferBarrierPtr);
1403         vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies);
1404         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_FALSE, 1, &imageBarrierPtr);
1405         VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1406
1407         const VkSubmitInfo                              submitInfo              =
1408         {
1409                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
1410                 DE_NULL,                                                // const void*                          pNext;
1411                 0u,                                                             // deUint32                                     waitSemaphoreCount;
1412                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
1413                 1u,                                                             // deUint32                                     commandBufferCount;
1414                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
1415                 0u,                                                             // deUint32                                     signalSemaphoreCount;
1416                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
1417         };
1418
1419         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1420         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1421         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1422
1423         // Read buffer data
1424         de::MovePtr<tcu::TextureLevel>  resultLevel     = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
1425         deFree(bufferImageCopies);
1426
1427         return checkTestResult(resultLevel->getAccess());
1428 }
1429
1430 class CopyBufferToImageTestCase : public vkt::TestCase
1431 {
1432 public:
1433                                                         CopyBufferToImageTestCase       (tcu::TestContext&              testCtx,
1434                                                                                                                  const std::string&             name,
1435                                                                                                                  const std::string&             description,
1436                                                                                                                  const TestParams               params)
1437                                                                 : vkt::TestCase                 (testCtx, name, description)
1438                                                                 , m_params                              (params)
1439                                                         {}
1440
1441         virtual                                 ~CopyBufferToImageTestCase      (void) {}
1442
1443         virtual TestInstance*   createInstance                          (Context&                               context) const
1444                                                         {
1445                                                                 return new CopyBufferToImage(context, m_params);
1446                                                         }
1447 private:
1448         TestParams                              m_params;
1449 };
1450
1451 void CopyBufferToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1452 {
1453         deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1454         if (!rowLength)
1455                 rowLength = region.bufferImageCopy.imageExtent.width;
1456
1457         deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1458         if (!imageHeight)
1459                 imageHeight = region.bufferImageCopy.imageExtent.height;
1460
1461         const int                       texelSize       = dst.getFormat().getPixelSize();
1462         const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
1463         const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
1464         const int                       texelOffset     = (int) region.bufferImageCopy.bufferOffset / texelSize;
1465
1466         for (int z = 0; z < extent.depth; z++)
1467         {
1468                 for (int y = 0; y < extent.height; y++)
1469                 {
1470                         int                                                                     texelIndex              = texelOffset + (z * imageHeight + y) *  rowLength;
1471                         const tcu::ConstPixelBufferAccess       srcSubRegion    = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1472                         const tcu::PixelBufferAccess            dstSubRegion    = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1473                                                                                                                                                                         region.bufferImageCopy.imageExtent.width, 1, 1);
1474                         tcu::copy(dstSubRegion, srcSubRegion);
1475                 }
1476         }
1477 }
1478
1479 } // anonymous
1480
1481 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
1482 {
1483         de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests  (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
1484
1485         const VkExtent3D                                defaultExtent                   = {256, 256, 1};
1486         const VkImageSubresourceLayers  defaultSourceLayer              =
1487         {
1488                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1489                 0u,                                                     // uint32_t                             mipLevel;
1490                 0u,                                                     // uint32_t                             baseArrayLayer;
1491                 1u,                                                     // uint32_t                             layerCount;
1492         };
1493
1494         {
1495                 std::ostringstream description;
1496                 description << "Copy from image to image";
1497
1498                 TestParams      params;
1499                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1500                 params.src.image.extent = defaultExtent;
1501                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1502                 params.dst.image.extent = defaultExtent;
1503
1504                 {
1505                         const VkImageSubresourceLayers sourceLayer =
1506                         {
1507                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1508                                 0u,                                                     // uint32_t                             mipLevel;
1509                                 0u,                                                     // uint32_t                             baseArrayLayer;
1510                                 1u                                                      // uint32_t                             layerCount;
1511                         };
1512                         const VkImageCopy testCopy =
1513                         {
1514                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1515                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1516                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1517                                 {0, 0, 0},              // VkOffset3D                           dstOffset;
1518                                 {256, 256, 1},  // VkExtent3D                           extent;
1519                         };
1520
1521                         CopyRegion imageCopy;
1522                         imageCopy.imageCopy = testCopy;
1523
1524                         params.regions.push_back(imageCopy);
1525                 }
1526
1527                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "imageToImage_whole", description.str(), params));
1528         }
1529
1530         {
1531                 std::ostringstream description;
1532                 description << "Copy from image to image";
1533
1534                 TestParams      params;
1535                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1536                 params.src.image.extent = defaultExtent;
1537                 params.dst.image.format = VK_FORMAT_R32_UINT;
1538                 params.dst.image.extent = defaultExtent;
1539
1540                 {
1541                         const VkImageSubresourceLayers sourceLayer =
1542                         {
1543                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1544                                 0u,                                                     // uint32_t                             mipLevel;
1545                                 0u,                                                     // uint32_t                             baseArrayLayer;
1546                                 1u                                                      // uint32_t                             layerCount;
1547                         };
1548                         const VkImageCopy testCopy =
1549                         {
1550                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1551                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1552                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1553                                 {0, 0, 0},              // VkOffset3D                           dstOffset;
1554                                 {256, 256, 1},  // VkExtent3D                           extent;
1555                         };
1556
1557                         CopyRegion imageCopy;
1558                         imageCopy.imageCopy = testCopy;
1559
1560                         params.regions.push_back(imageCopy);
1561                 }
1562
1563                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_whole_different_format_uncompressed", description.str(), params));
1564         }
1565
1566         {
1567                 std::ostringstream description;
1568                 description << "Copy from image to image";
1569
1570                 TestParams      params;
1571                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1572                 params.src.image.extent = defaultExtent;
1573                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1574                 params.dst.image.extent = defaultExtent;
1575
1576                 {
1577                         const VkImageSubresourceLayers sourceLayer =
1578                         {
1579                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1580                                 0u,                                                     // uint32_t                             mipLevel;
1581                                 0u,                                                     // uint32_t                             baseArrayLayer;
1582                                 1u                                                      // uint32_t                             layerCount;
1583                         };
1584                         const VkImageCopy testCopy =
1585                         {
1586                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1587                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1588                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1589                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1590                                 {16, 16, 1},    // VkExtent3D                           extent;
1591                         };
1592
1593                         CopyRegion imageCopy;
1594                         imageCopy.imageCopy = testCopy;
1595
1596                         params.regions.push_back(imageCopy);
1597                 }
1598
1599                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial", description.str(), params));
1600         }
1601
1602         {
1603                 std::ostringstream description;
1604                 description << "Copy from image to image";
1605
1606                 TestParams      params;
1607                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1608                 params.src.image.extent = defaultExtent;
1609                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1610                 params.dst.image.extent = defaultExtent;
1611
1612                 for (deInt32 i = 0; i < 16; i++)
1613                 {
1614                         const VkImageSubresourceLayers sourceLayer =
1615                         {
1616                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspectMask;
1617                                 0u,                                                     // uint32_t                             mipLevel;
1618                                 0u,                                                     // uint32_t                             baseArrayLayer;
1619                                 1u                                                      // uint32_t                             layerCount;
1620                         };
1621                         const VkImageCopy testCopy =
1622                         {
1623                                 sourceLayer,                    // VkImageSubresourceLayers     srcSubresource;
1624                                 {0, 0, 0},                              // VkOffset3D                           srcOffset;
1625                                 sourceLayer,                    // VkImageSubresourceLayers     dstSubresource;
1626                                 {i*16, 240-i*16, 0},    // VkOffset3D                           dstOffset;
1627                                 {16, 16, 1},                    // VkExtent3D                           extent;
1628                         };
1629
1630                         CopyRegion imageCopy;
1631                         imageCopy.imageCopy = testCopy;
1632
1633                         params.regions.push_back(imageCopy);
1634                 }
1635
1636                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial_multiple", description.str(), params));
1637         }
1638
1639         // Copy image to buffer testcases.
1640         {
1641                 std::ostringstream      description;
1642                 description << "Copy from image to buffer";
1643
1644                 TestParams      params;
1645                 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1646                 params.src.image.extent = defaultExtent;
1647                 params.dst.buffer.size  = 256 * 256;
1648
1649                 const VkBufferImageCopy                 bufferImageCopy =
1650                 {
1651                         0u,                                             // VkDeviceSize                         bufferOffset;
1652                         0u,                                             // uint32_t                                     bufferRowLength;
1653                         0u,                                             // uint32_t                                     bufferImageHeight;
1654                         defaultSourceLayer,             // VkImageSubresourceLayers     imageSubresource;
1655                         {0, 0, 0},                              // VkOffset3D                           imageOffset;
1656                         {16, 16, 1}                             // VkExtent3D                           imageExtent;
1657                 };
1658                 CopyRegion copyRegion;
1659                 copyRegion.bufferImageCopy = bufferImageCopy;
1660
1661                 params.regions.push_back(copyRegion);
1662
1663                 copiesAndBlittingTests->addChild(new CopyImageToBufferTestCase(testCtx, "image_to_buffer", description.str(), params));
1664         }
1665
1666         // Copy buffer to image testcases.
1667         {
1668                 std::ostringstream      description;
1669                 description << "Copy from buffer to image";
1670
1671                 TestParams      params;
1672                 params.src.buffer.size  = 256 * 256;
1673                 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1674                 params.dst.image.extent = defaultExtent;
1675
1676                 const VkBufferImageCopy                 bufferImageCopy =
1677                 {
1678                         0u,                                             // VkDeviceSize                         bufferOffset;
1679                         0u,                                             // uint32_t                                     bufferRowLength;
1680                         0u,                                             // uint32_t                                     bufferImageHeight;
1681                         defaultSourceLayer,             // VkImageSubresourceLayers     imageSubresource;
1682                         {0, 0, 0},                              // VkOffset3D                           imageOffset;
1683                         {16, 16, 1}                             // VkExtent3D                           imageExtent;
1684                 };
1685                 CopyRegion copyRegion;
1686                 copyRegion.bufferImageCopy = bufferImageCopy;
1687
1688                 params.regions.push_back(copyRegion);
1689
1690                 copiesAndBlittingTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_to_image", description.str(), params));
1691         }
1692
1693         {
1694                 std::ostringstream      description;
1695                 description << "Copy from buffer to buffer: whole buffer.";
1696
1697                 TestParams params;
1698                 params.src.buffer.size = 256;
1699                 params.dst.buffer.size = 256;
1700                 const VkBufferCopy bufferCopy = {
1701                         0u,             // VkDeviceSize srcOffset;
1702                         0u,             // VkDeviceSize dstOffset;
1703                         256u,   // VkDeviceSize size;
1704                 };
1705                 CopyRegion copyRegion;
1706                 copyRegion.bufferCopy = bufferCopy;
1707
1708                 params.regions.push_back(copyRegion);
1709
1710                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_whole", description.str(), params));
1711         }
1712
1713         {
1714                 std::ostringstream      description;
1715                 description << "Copy from buffer to buffer: small area.";
1716
1717                 TestParams params;
1718                 params.src.buffer.size = 16;
1719                 params.dst.buffer.size = 16;
1720                 const VkBufferCopy bufferCopy = {
1721                         12u,    // VkDeviceSize srcOffset;
1722                         4u,             // VkDeviceSize dstOffset;
1723                         1u,             // VkDeviceSize size;
1724                 };
1725                 CopyRegion copyRegion;
1726                 copyRegion.bufferCopy = bufferCopy;
1727
1728                 params.regions.push_back(copyRegion);
1729
1730                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_small", description.str(), params));
1731         }
1732
1733         {
1734                 std::ostringstream      description;
1735                 description << "Copy from buffer to buffer: more regions.";
1736
1737                 const deUint32 size = 16;
1738
1739                 TestParams params;
1740                 params.src.buffer.size = size;
1741                 params.dst.buffer.size = size * (size + 1);
1742
1743                 // Copy region with size 0..size
1744                 for (unsigned int i = 0; i <= size; i++)
1745                 {
1746                         const VkBufferCopy bufferCopy = {
1747                                 0,              // VkDeviceSize srcOffset;
1748                                 i*size, // VkDeviceSize dstOffset;
1749                                 i,              // VkDeviceSize size;
1750                         };
1751                         CopyRegion copyRegion;
1752                         copyRegion.bufferCopy = bufferCopy;
1753                         params.regions.push_back(copyRegion);
1754                 }
1755                 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_regions", description.str(), params));
1756         }
1757
1758         {
1759                 std::ostringstream description;
1760                 description << "Copy from image to image depth";
1761
1762                 TestParams      params;
1763                 params.src.image.format = VK_FORMAT_D32_SFLOAT;
1764                 params.src.image.extent = defaultExtent;
1765                 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
1766                 params.dst.image.extent = defaultExtent;
1767
1768                 {
1769                         const VkImageSubresourceLayers sourceLayer =
1770                         {
1771                                 VK_IMAGE_ASPECT_DEPTH_BIT,      // VkImageAspectFlags   aspectMask;
1772                                 0u,                                                     // uint32_t                             mipLevel;
1773                                 0u,                                                     // uint32_t                             baseArrayLayer;
1774                                 1u                                                      // uint32_t                             layerCount;
1775                         };
1776                         const VkImageCopy testCopy =
1777                         {
1778                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1779                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1780                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1781                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1782                                 {16, 16, 1},    // VkExtent3D                           extent;
1783                         };
1784
1785                         CopyRegion imageCopy;
1786                         imageCopy.imageCopy = testCopy;
1787
1788                         params.regions.push_back(imageCopy);
1789                 }
1790
1791                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_depth", description.str(), params));
1792         }
1793
1794         {
1795                 std::ostringstream description;
1796                 description << "Copy from image to image stencil";
1797
1798                 TestParams      params;
1799                 params.src.image.format = VK_FORMAT_S8_UINT;
1800                 params.src.image.extent = defaultExtent;
1801                 params.dst.image.format = VK_FORMAT_S8_UINT;
1802                 params.dst.image.extent = defaultExtent;
1803
1804                 {
1805                         const VkImageSubresourceLayers sourceLayer =
1806                         {
1807                                 VK_IMAGE_ASPECT_STENCIL_BIT,    // VkImageAspectFlags   aspectMask;
1808                                 0u,                                                             // uint32_t                             mipLevel;
1809                                 0u,                                                             // uint32_t                             baseArrayLayer;
1810                                 1u                                                              // uint32_t                             layerCount;
1811                         };
1812                         const VkImageCopy testCopy =
1813                         {
1814                                 sourceLayer,    // VkImageSubresourceLayers     srcSubresource;
1815                                 {0, 0, 0},              // VkOffset3D                           srcOffset;
1816                                 sourceLayer,    // VkImageSubresourceLayers     dstSubresource;
1817                                 {64, 98, 0},    // VkOffset3D                           dstOffset;
1818                                 {16, 16, 1},    // VkExtent3D                           extent;
1819                         };
1820
1821                         CopyRegion imageCopy;
1822                         imageCopy.imageCopy = testCopy;
1823
1824                         params.regions.push_back(imageCopy);
1825                 }
1826
1827                 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_stencil", description.str(), params));
1828         }
1829
1830         return copiesAndBlittingTests.release();
1831 }
1832
1833 } // api
1834 } // vkt