Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / memory / vktMemoryBindingTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktMemoryBindingTests.hpp"
25
26 #include "vktTestCase.hpp"
27 #include "tcuTestLog.hpp"
28
29 #include "vkPlatform.hpp"
30 #include "gluVarType.hpp"
31 #include "deStringUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "deSharedPtr.hpp"
36 #include "vktTestCase.hpp"
37 #include "vkTypeUtil.hpp"
38
39 #include <algorithm>
40
41 namespace vkt
42 {
43 namespace memory
44 {
45 namespace
46 {
47
48 using namespace vk;
49
50 typedef const VkMemoryDedicatedAllocateInfoKHR                                                          ConstDedicatedInfo;
51 typedef de::SharedPtr<Move<VkDeviceMemory> >                                                            MemoryRegionPtr;
52 typedef std::vector<MemoryRegionPtr>                                                                            MemoryRegionsList;
53 typedef de::SharedPtr<Move<VkBuffer> >                                                                          BufferPtr;
54 typedef std::vector<BufferPtr>                                                                                          BuffersList;
55 typedef de::SharedPtr<Move<VkImage> >                                                                           ImagePtr;
56 typedef std::vector<ImagePtr>                                                                                           ImagesList;
57 typedef std::vector<VkBindBufferMemoryInfoKHR>                                                          BindBufferMemoryInfosList;
58 typedef std::vector<VkBindImageMemoryInfoKHR>                                                           BindImageMemoryInfosList;
59
60 class MemoryMappingRAII
61 {
62 public:
63                                                                                 MemoryMappingRAII                                       (const DeviceInterface& deviceInterface,
64                                                                                                                                                          const VkDevice&                device,
65                                                                                                                                                          VkDeviceMemory                 deviceMemory,
66                                                                                                                                                          VkDeviceSize                   offset,
67                                                                                                                                                          VkDeviceSize                   size,
68                                                                                                                                                          VkMemoryMapFlags               flags)
69                                                                                 : vk                                                            (deviceInterface)
70                                                                                 , dev                                                           (device)
71                                                                                 , memory                                                        (deviceMemory)
72                                                                                 , hostPtr                                                       (DE_NULL)
73
74         {
75                 vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
76         }
77
78                                                                                 ~MemoryMappingRAII                                      ()
79         {
80                 vk.unmapMemory(dev, memory);
81                 hostPtr = DE_NULL;
82         }
83
84         void*                                                           ptr                                                                     ()
85         {
86                 return hostPtr;
87         }
88
89         void                                                            flush                                                           (VkDeviceSize                   offset,
90                                                                                                                                                          VkDeviceSize                   size)
91         {
92                 const VkMappedMemoryRange               range                                                           = makeMemoryRange(offset, size);
93                 VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
94         }
95
96 protected:
97         const DeviceInterface&                          vk;
98         const VkDevice&                                         dev;
99         VkDeviceMemory                                          memory;
100         void*                                                           hostPtr;
101
102         const VkMappedMemoryRange                       makeMemoryRange                                         (VkDeviceSize                   offset,
103                                                                                                                                                          VkDeviceSize                   size)
104         {
105                 const VkMappedMemoryRange               range                                                           =
106                 {
107                         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
108                         DE_NULL,
109                         memory,
110                         offset,
111                         size
112                 };
113                 return range;
114         }
115 };
116
117 class SimpleRandomGenerator
118 {
119 public:
120                                                                                 SimpleRandomGenerator                           (deUint32                               seed)
121                                                                                 : value                                                         (seed)
122         {}
123         deUint32                                                        getNext                                                         ()
124         {
125                 value += 1;
126                 value ^= (value << 21);
127                 value ^= (value >> 15);
128                 value ^= (value << 4);
129                 return value;
130         }
131 protected:
132         deUint32                                                        value;
133 };
134
135 struct BindingCaseParameters
136 {
137         VkBufferCreateFlags                                     flags;
138         VkBufferUsageFlags                                      usage;
139         VkSharingMode                                           sharing;
140         VkDeviceSize                                            bufferSize;
141         VkExtent3D                                                      imageSize;
142         deUint32                                                        targetsCount;
143 };
144
145 BindingCaseParameters                                   makeBindingCaseParameters                       (deUint32                               targetsCount,
146                                                                                                                                                          deUint32                               width,
147                                                                                                                                                          deUint32                               height)
148 {
149         BindingCaseParameters                           params;
150         deMemset(&params, 0, sizeof(BindingCaseParameters));
151         params.imageSize.width = width;
152         params.imageSize.height = height;
153         params.imageSize.depth = 1;
154         params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
155         params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
156         params.targetsCount = targetsCount;
157         return params;
158 }
159
160 BindingCaseParameters                                   makeBindingCaseParameters                       (deUint32                               targetsCount,
161                                                                                                                                                          VkBufferUsageFlags             usage,
162                                                                                                                                                          VkSharingMode                  sharing,
163                                                                                                                                                          VkDeviceSize                   bufferSize)
164 {
165         BindingCaseParameters                           params                                                          =
166         {
167                 0,                                                                                                                                      // VkBufferCreateFlags  flags;
168                 usage,                                                                                                                          // VkBufferUsageFlags   usage;
169                 sharing,                                                                                                                        // VkSharingMode                sharing;
170                 bufferSize,                                                                                                                     // VkDeviceSize                 bufferSize;
171                 {0u, 0u, 0u},                                                                                                           // VkExtent3D                   imageSize;
172                 targetsCount                                                                                                            // deUint32                             targetsCount;
173         };
174         return params;
175 }
176
177 VkImageCreateInfo                                               makeImageCreateInfo                                     (BindingCaseParameters& params)
178 {
179         const VkImageCreateInfo                         imageParams                                                     =
180         {
181                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                            // VkStructureType              sType;
182                 DE_NULL,                                                                                                                        // const void*                  pNext;
183                 0u,                                                                                                                                     // VkImageCreateFlags   flags;
184                 VK_IMAGE_TYPE_2D,                                                                                                       // VkImageType                  imageType;
185                 VK_FORMAT_R8G8B8A8_UINT,                                                                                        // VkFormat                             format;
186                 params.imageSize,                                                                                                       // VkExtent3D                   extent;
187                 1u,                                                                                                                                     // deUint32                             mipLevels;
188                 1u,                                                                                                                                     // deUint32                             arrayLayers;
189                 VK_SAMPLE_COUNT_1_BIT,                                                                                          // VkSampleCountFlagBits samples;
190                 VK_IMAGE_TILING_LINEAR,                                                                                         // VkImageTiling                tiling;
191                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,      // VkImageUsageFlags    usage;
192                 VK_SHARING_MODE_EXCLUSIVE,                                                                                      // VkSharingMode                sharingMode;
193                 0u,                                                                                                                                     // deUint32                             queueFamilyIndexCount;
194                 DE_NULL,                                                                                                                        // const deUint32*              pQueueFamilyIndices;
195                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                      // VkImageLayout                initialLayout;
196         };
197         return imageParams;
198 }
199
200 VkBufferCreateInfo                                              makeBufferCreateInfo                            (Context&                               ctx,
201                                                                                                                                                          BindingCaseParameters& params)
202 {
203         const deUint32                                          queueFamilyIndex                                        = ctx.getUniversalQueueFamilyIndex();
204         VkBufferCreateInfo                                      bufferParams                                            =
205         {
206                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                           // VkStructureType              sType;
207                 DE_NULL,                                                                                                                        // const void*                  pNext;
208                 params.flags,                                                                                                           // VkBufferCreateFlags  flags;
209                 params.bufferSize,                                                                                                      // VkDeviceSize                 size;
210                 params.usage,                                                                                                           // VkBufferUsageFlags   usage;
211                 params.sharing,                                                                                                         // VkSharingMode                sharingMode;
212                 1u,                                                                                                                                     // uint32_t                             queueFamilyIndexCount;
213                 &queueFamilyIndex,                                                                                                      // const uint32_t*              pQueueFamilyIndices;
214         };
215         return bufferParams;
216 }
217
218 const VkMemoryAllocateInfo                              makeMemoryAllocateInfo                          (VkMemoryRequirements&  memReqs,
219                                                                                                                                                          ConstDedicatedInfo*    next)
220 {
221         const deUint32                                          heapTypeIndex                                           = (deUint32)deCtz32(memReqs.memoryTypeBits);
222         const VkMemoryAllocateInfo                      allocateParams                                          =
223         {
224                 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                                                         // VkStructureType              sType;
225                 next,                                                                                                                           // const void*                  pNext;
226                 memReqs.size,                                                                                                           // VkDeviceSize                 allocationSize;
227                 heapTypeIndex,                                                                                                          // uint32_t                             memoryTypeIndex;
228         };
229         return allocateParams;
230 }
231
232 enum MemoryHostVisibility
233 {
234         MemoryAny,
235         MemoryHostVisible
236 };
237
238 deUint32                                                                selectMatchingMemoryType                        (Context&                               ctx,
239                                                                                                                                                          VkMemoryRequirements&  memReqs,
240                                                                                                                                                          MemoryHostVisibility   memoryVisibility)
241 {
242         const VkPhysicalDevice                          vkPhysicalDevice                                        = ctx.getPhysicalDevice();
243         const InstanceInterface&                        vkInstance                                                      = ctx.getInstanceInterface();
244         VkPhysicalDeviceMemoryProperties        memoryProperties;
245
246         vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
247         if (memoryVisibility == MemoryHostVisible)
248         {
249                 for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
250                 {
251                         const deBool                            isInAllowed                                                     = (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
252                         const deBool                            hasRightProperties                                      = (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
253                         if (isInAllowed && hasRightProperties)
254                                 return typeNdx;
255                 }
256         }
257         return (deUint32)deCtz32(memReqs.memoryTypeBits);
258 }
259
260 const VkMemoryAllocateInfo                              makeMemoryAllocateInfo                          (Context&                               ctx,
261                                                                                                                                                          VkMemoryRequirements&  memReqs,
262                                                                                                                                                          MemoryHostVisibility   memoryVisibility)
263 {
264         const deUint32                                          heapTypeIndex                                           = selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
265         const VkMemoryAllocateInfo                      allocateParams                                          =
266         {
267                 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                                                         // VkStructureType              sType;
268                 DE_NULL,                                                                                                                        // const void*                  pNext;
269                 memReqs.size,                                                                                                           // VkDeviceSize                 allocationSize;
270                 heapTypeIndex,                                                                                                          // uint32_t                             memoryTypeIndex;
271         };
272         return allocateParams;
273 }
274
275 ConstDedicatedInfo                                              makeDedicatedAllocationInfo                     (VkBuffer                               buffer)
276 {
277         ConstDedicatedInfo                                      dedicatedAllocationInfo                         =
278         {
279                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,                           // VkStructureType              sType
280                 DE_NULL,                                                                                                                        // const void*                  pNext
281                 DE_NULL,                                                                                                                        // VkImage                              image
282                 buffer                                                                                                                          // VkBuffer                             buffer
283         };
284         return dedicatedAllocationInfo;
285 }
286
287 ConstDedicatedInfo                                              makeDedicatedAllocationInfo                     (VkImage                                image)
288 {
289         ConstDedicatedInfo                                      dedicatedAllocationInfo                         =
290         {
291                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,                           // VkStructureType              sType
292                 DE_NULL,                                                                                                                        // const void*                  pNext
293                 image,                                                                                                                          // VkImage                              image
294                 DE_NULL                                                                                                                         // VkBuffer                             buffer
295         };
296         return dedicatedAllocationInfo;
297 }
298
299 const VkBindBufferMemoryInfoKHR                 makeBufferMemoryBindingInfo                     (VkBuffer                               buffer,
300                                                                                                                                                          VkDeviceMemory                 memory)
301 {
302         const VkBindBufferMemoryInfoKHR         bufferMemoryBinding                                     =
303         {
304                 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,                                          // VkStructureType              sType;
305                 DE_NULL,                                                                                                                        // const void*                  pNext;
306                 buffer,                                                                                                                         // VkBuffer                             buffer;
307                 memory,                                                                                                                         // VkDeviceMemory               memory;
308                 0u,                                                                                                                                     // VkDeviceSize                 memoryOffset;
309         };
310         return bufferMemoryBinding;
311 }
312
313 const VkBindImageMemoryInfoKHR                  makeImageMemoryBindingInfo                      (VkImage                                image,
314                                                                                                                                                          VkDeviceMemory                 memory)
315 {
316         const VkBindImageMemoryInfoKHR          imageMemoryBinding                                      =
317         {
318                 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,                                           // VkStructureType              sType;
319                 DE_NULL,                                                                                                                        // const void*                  pNext;
320                 image,                                                                                                                          // VkImage                              image;
321                 memory,                                                                                                                         // VkDeviceMemory               memory;
322                 0u,                                                                                                                                     // VkDeviceSize                 memoryOffset;
323         };
324         return imageMemoryBinding;
325 }
326
327 enum TransferDirection
328 {
329         TransferToResource                                                                                                              = 0,
330         TransferFromResource                                                                                                    = 1
331 };
332
333 const VkBufferMemoryBarrier                             makeMemoryBarrierInfo                           (VkBuffer                               buffer,
334                                                                                                                                                          VkDeviceSize                   size,
335                                                                                                                                                          TransferDirection              direction)
336 {
337         const deBool fromRes                                                                                                    = direction == TransferFromResource;
338         const VkAccessFlags                                     srcMask                                                         = static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
339         const VkAccessFlags                                     dstMask                                                         = static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
340         const VkBufferMemoryBarrier                     bufferBarrier                                           =
341         {
342                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                                                        // VkStructureType              sType;
343                 DE_NULL,                                                                                                                        // const void*                  pNext;
344                 srcMask,                                                                                                                        // VkAccessFlags                srcAccessMask;
345                 dstMask,                                                                                                                        // VkAccessFlags                dstAccessMask;
346                 VK_QUEUE_FAMILY_IGNORED,                                                                                        // deUint32                             srcQueueFamilyIndex;
347                 VK_QUEUE_FAMILY_IGNORED,                                                                                        // deUint32                             dstQueueFamilyIndex;
348                 buffer,                                                                                                                         // VkBuffer                             buffer;
349                 0u,                                                                                                                                     // VkDeviceSize                 offset;
350                 size                                                                                                                            // VkDeviceSize                 size;
351         };
352         return bufferBarrier;
353 }
354
355 const VkImageMemoryBarrier                              makeMemoryBarrierInfo                           (VkImage                                image,
356                                                                                                                                                          VkAccessFlags                  srcAccess,
357                                                                                                                                                          VkAccessFlags                  dstAccess,
358                                                                                                                                                          VkImageLayout                  oldLayout,
359                                                                                                                                                          VkImageLayout                  newLayout)
360 {
361         const VkImageAspectFlags                        aspect                                                          = VK_IMAGE_ASPECT_COLOR_BIT;
362         const VkImageMemoryBarrier                      imageBarrier                                            =
363         {
364                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                         // VkStructureType              sType;
365                 DE_NULL,                                                                                                                        // const void*                  pNext;
366                 srcAccess,                                                                                                                      // VkAccessFlags                srcAccessMask;
367                 dstAccess,                                                                                                                      // VkAccessFlags                dstAccessMask;
368                 oldLayout,                                                                                                                      // VkImageLayout                oldLayout;
369                 newLayout,                                                                                                                      // VkImageLayout                newLayout;
370                 VK_QUEUE_FAMILY_IGNORED,                                                                                        // deUint32                             srcQueueFamilyIndex;
371                 VK_QUEUE_FAMILY_IGNORED,                                                                                        // deUint32                             dstQueueFamilyIndex;
372                 image,                                                                                                                          // VkImage                              image;
373                 {                                                                                                                                       // VkImageSubresourceRange subresourceRange;
374                         aspect,                                                                                                                 // VkImageAspectFlags   aspect;
375                         0u,                                                                                                                             // deUint32                             baseMipLevel;
376                         1u,                                                                                                                             // deUint32                             mipLevels;
377                         0u,                                                                                                                             // deUint32                             baseArraySlice;
378                         1u,                                                                                                                             // deUint32                             arraySize;
379                 }
380         };
381         return imageBarrier;
382 }
383
384 const VkCommandBufferBeginInfo                  makeCommandBufferInfo                           ()
385 {
386         const VkCommandBufferBeginInfo          cmdBufferBeginInfo                                      =
387         {
388                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
389                 DE_NULL,
390                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
391                 static_cast<const VkCommandBufferInheritanceInfo*>(DE_NULL)
392         };
393         return cmdBufferBeginInfo;
394 }
395
396 const VkSubmitInfo                                              makeSubmitInfo                                          (const VkCommandBuffer& commandBuffer)
397 {
398         const VkSubmitInfo                                      submitInfo                                                      =
399         {
400                 VK_STRUCTURE_TYPE_SUBMIT_INFO,                                                                          // VkStructureType              sType;
401                 DE_NULL,                                                                                                                        // const void*                  pNext;
402                 0u,                                                                                                                                     // deUint32                             waitSemaphoreCount;
403                 DE_NULL,                                                                                                                        // const VkSemaphore*   pWaitSemaphores;
404                 (const VkPipelineStageFlags*)DE_NULL,                                                           // const VkPipelineStageFlags* flags;
405                 1u,                                                                                                                                     // deUint32                             commandBufferCount;
406                 &commandBuffer,                                                                                                         // const VkCommandBuffer* pCommandBuffers;
407                 0u,                                                                                                                                     // deUint32                             signalSemaphoreCount;
408                 DE_NULL                                                                                                                         // const VkSemaphore*   pSignalSemaphores;
409         };
410         return submitInfo;
411 }
412
413 Move<VkCommandBuffer>                                   createCommandBuffer                                     (const DeviceInterface& vk,
414                                                                                                                                                          VkDevice                               device,
415                                                                                                                                                          VkCommandPool                  commandPool)
416 {
417         const VkCommandBufferAllocateInfo allocInfo =
418         {
419                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
420                 DE_NULL,
421                 commandPool,
422                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
423                 1
424         };
425         return allocateCommandBuffer(vk, device, &allocInfo);
426 }
427
428
429 template<typename TTarget>
430 void                                                                    createBindingTargets                            (std::vector<de::SharedPtr<Move<TTarget> > >&
431                                                                                                                                                                                                         targets,
432                                                                                                                                                          Context&                               ctx,
433                                                                                                                                                          BindingCaseParameters  params);
434
435 template<>
436 void                                                                    createBindingTargets<VkBuffer>          (BuffersList&                   targets,
437                                                                                                                                                          Context&                               ctx,
438                                                                                                                                                          BindingCaseParameters  params)
439 {
440         const deUint32                                          count                                                           = params.targetsCount;
441         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
442         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
443
444         targets.reserve(count);
445         for (deUint32 i = 0u; i < count; ++i)
446         {
447                 VkBufferCreateInfo                              bufferParams                                            = makeBufferCreateInfo(ctx, params);
448                 targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
449         }
450 }
451
452 template<>
453 void                                                                    createBindingTargets<VkImage>           (ImagesList&                    targets,
454                                                                                                                                                          Context&                               ctx,
455                                                                                                                                                          BindingCaseParameters  params)
456 {
457         const deUint32                                          count                                                           = params.targetsCount;
458         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
459         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
460
461         targets.reserve(count);
462         for (deUint32 i = 0u; i < count; ++i)
463         {
464                 VkImageCreateInfo                               imageParams                                                     = makeImageCreateInfo(params);
465                 targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
466         }
467 }
468
469 template<typename TTarget, deBool TDedicated>
470 void                                                                    createMemory                                            (std::vector<de::SharedPtr<Move<TTarget> > >&
471                                                                                                                                                                                                         targets,
472                                                                                                                                                          MemoryRegionsList&             memory,
473                                                                                                                                                          Context&                               ctx,
474                                                                                                                                                          BindingCaseParameters  params);
475
476 template<>
477 void                                                                    createMemory<VkBuffer, DE_FALSE>        (BuffersList&                   targets,
478                                                                                                                                                          MemoryRegionsList&             memory,
479                                                                                                                                                          Context&                               ctx,
480                                                                                                                                                          BindingCaseParameters  params)
481 {
482         DE_UNREF(params);
483         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
484         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
485         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
486
487         memory.reserve(count);
488         for (deUint32 i = 0; i < count; ++i)
489         {
490                 VkMemoryRequirements                    memReqs;
491
492                 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
493
494                 const VkMemoryAllocateInfo              memAlloc                                                        = makeMemoryAllocateInfo(memReqs, DE_NULL);
495                 VkDeviceMemory                                  rawMemory                                                       = DE_NULL;
496
497                 vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
498                 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
499         }
500 }
501
502 template<>
503 void                                                                    createMemory<VkImage, DE_FALSE>         (ImagesList&                    targets,
504                                                                                                                                                          MemoryRegionsList&             memory,
505                                                                                                                                                          Context&                               ctx,
506                                                                                                                                                          BindingCaseParameters  params)
507 {
508         DE_UNREF(params);
509         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
510         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
511         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
512
513         memory.reserve(count);
514         for (deUint32 i = 0; i < count; ++i)
515         {
516                 VkMemoryRequirements                    memReqs;
517                 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
518
519                 const VkMemoryAllocateInfo              memAlloc                                                        = makeMemoryAllocateInfo(memReqs, DE_NULL);
520                 VkDeviceMemory                                  rawMemory                                                       = DE_NULL;
521
522                 vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
523                 memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
524         }
525 }
526
527 template<>
528 void                                                                    createMemory<VkBuffer, DE_TRUE>         (BuffersList&                   targets,
529                                                                                                                                                          MemoryRegionsList&             memory,
530                                                                                                                                                          Context&                               ctx,
531                                                                                                                                                          BindingCaseParameters  params)
532 {
533         DE_UNREF(params);
534         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
535         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
536         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
537
538         memory.reserve(count);
539         for (deUint32 i = 0; i < count; ++i)
540         {
541                 VkMemoryRequirements                    memReqs;
542
543                 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
544
545                 ConstDedicatedInfo                              dedicatedAllocationInfo                         = makeDedicatedAllocationInfo(**targets[i]);;
546                 const VkMemoryAllocateInfo              memAlloc                                                        = makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
547                 VkDeviceMemory                                  rawMemory                                                       = DE_NULL;
548
549                 vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
550                 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
551         }
552 }
553
554 template<>
555 void                                                                    createMemory<VkImage, DE_TRUE>          (ImagesList&                    targets,
556                                                                                                                                                          MemoryRegionsList&             memory,
557                                                                                                                                                          Context&                               ctx,
558                                                                                                                                                          BindingCaseParameters  params)
559 {
560         DE_UNREF(params);
561         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
562         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
563         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
564
565         memory.reserve(count);
566         for (deUint32 i = 0; i < count; ++i)
567         {
568                 VkMemoryRequirements                    memReqs;
569                 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
570
571                 ConstDedicatedInfo                              dedicatedAllocationInfo                         = makeDedicatedAllocationInfo(**targets[i]);
572                 const VkMemoryAllocateInfo              memAlloc                                                        = makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
573                 VkDeviceMemory                                  rawMemory                                                       = DE_NULL;
574
575                 vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
576                 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
577         }
578 }
579
580 template<typename TTarget>
581 void                                                                    makeBinding                                                     (std::vector<de::SharedPtr<Move<TTarget> > >&
582                                                                                                                                                                                                         targets,
583                                                                                                                                                          MemoryRegionsList&             memory,
584                                                                                                                                                          Context&                               ctx,
585                                                                                                                                                          BindingCaseParameters  params);
586
587 template<>
588 void                                                                    makeBinding<VkBuffer>                           (BuffersList&                   targets,
589                                                                                                                                                          MemoryRegionsList&             memory,
590                                                                                                                                                          Context&                               ctx,
591                                                                                                                                                          BindingCaseParameters  params)
592 {
593         DE_UNREF(params);
594         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
595         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
596         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
597         BindBufferMemoryInfosList                       bindMemoryInfos;
598
599         for (deUint32 i = 0; i < count; ++i)
600         {
601                 bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
602         }
603
604         VK_CHECK(vk.bindBufferMemory2KHR(vkDevice, count, &bindMemoryInfos.front()));
605 }
606
607 template<>
608 void                                                                    makeBinding<VkImage>                            (ImagesList&                    targets,
609                                                                                                                                                          MemoryRegionsList&             memory,
610                                                                                                                                                          Context&                               ctx,
611                                                                                                                                                          BindingCaseParameters  params)
612 {
613         DE_UNREF(params);
614         const deUint32                                          count                                                           = static_cast<deUint32>(targets.size());
615         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
616         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
617         BindImageMemoryInfosList                        bindMemoryInfos;
618
619         for (deUint32 i = 0; i < count; ++i)
620         {
621                 bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
622         }
623
624         VK_CHECK(vk.bindImageMemory2KHR(vkDevice, count, &bindMemoryInfos.front()));
625 }
626
627 template <typename TTarget>
628 void                                                                    fillUpResource                                          (Move<VkBuffer>&                source,
629                                                                                                                                                          Move<TTarget>&                 target,
630                                                                                                                                                          Context&                               ctx,
631                                                                                                                                                          BindingCaseParameters  params);
632
633 template <>
634 void                                                                    fillUpResource<VkBuffer>                        (Move<VkBuffer>&                source,
635                                                                                                                                                          Move<VkBuffer>&                target,
636                                                                                                                                                          Context&                               ctx,
637                                                                                                                                                          BindingCaseParameters  params)
638 {
639         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
640         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
641         const VkQueue                                           queue                                                           = ctx.getUniversalQueue();
642
643         const VkBufferMemoryBarrier                     srcBufferBarrier                                        = makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
644         const VkBufferMemoryBarrier                     dstBufferBarrier                                        = makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
645
646         const VkCommandBufferBeginInfo          cmdBufferBeginInfo                                      = makeCommandBufferInfo();
647         Move<VkCommandPool>                                     commandPool                                                     = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
648         Move<VkCommandBuffer>                           cmdBuffer                                                       = createCommandBuffer(vk, vkDevice, *commandPool);
649         VkBufferCopy                                            bufferCopy                                                      = { 0u, 0u, params.bufferSize };
650
651         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
652         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
653         vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
654         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
655         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
656
657         const VkSubmitInfo                                      submitInfo                                                      = makeSubmitInfo(*cmdBuffer);
658         Move<VkFence>                                           fence                                                           = createFence(vk, vkDevice);
659
660         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
661         VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
662 }
663
664 template <>
665 void                                                                    fillUpResource<VkImage>                         (Move<VkBuffer>&                source,
666                                                                                                                                                          Move<VkImage>&                 target,
667                                                                                                                                                          Context&                               ctx,
668                                                                                                                                                          BindingCaseParameters  params)
669 {
670         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
671         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
672         const VkQueue                                           queue                                                           = ctx.getUniversalQueue();
673
674         const VkBufferMemoryBarrier                     srcBufferBarrier                                        = makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
675         const VkImageMemoryBarrier                      preImageBarrier                                         = makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
676         const VkImageMemoryBarrier                      dstImageBarrier                                         = makeMemoryBarrierInfo(*target, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
677
678         const VkCommandBufferBeginInfo          cmdBufferBeginInfo                                      = makeCommandBufferInfo();
679         Move<VkCommandPool>                                     commandPool                                                     = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
680         Move<VkCommandBuffer>                           cmdBuffer                                                       = createCommandBuffer(vk, vkDevice, *commandPool);
681
682         const VkBufferImageCopy                         copyRegion                                                      =
683         {
684                 0u,                                                                                                                                     // VkDeviceSize                 bufferOffset;
685                 params.imageSize.width,                                                                                         // deUint32                             bufferRowLength;
686                 params.imageSize.height,                                                                                        // deUint32                             bufferImageHeight;
687                 {
688                         VK_IMAGE_ASPECT_COLOR_BIT,                                                                              // VkImageAspectFlags   aspect;
689                         0u,                                                                                                                             // deUint32                             mipLevel;
690                         0u,                                                                                                                             // deUint32                             baseArrayLayer;
691                         1u,                                                                                                                             // deUint32                             layerCount;
692                 },                                                                                                                                      // VkImageSubresourceLayers imageSubresource;
693                 { 0, 0, 0 },                                                                                                            // VkOffset3D                   imageOffset;
694                 params.imageSize                                                                                                        // VkExtent3D                   imageExtent;
695         };
696
697         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
698         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
699         vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (&copyRegion));
700         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
701         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
702
703         const VkSubmitInfo                                      submitInfo                                                      = makeSubmitInfo(*cmdBuffer);
704         Move<VkFence>                                           fence                                                           = createFence(vk, vkDevice);
705
706         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
707         VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
708 }
709
710 template <typename TTarget>
711 void                                                                    readUpResource                                          (Move<TTarget>&                 source,
712                                                                                                                                                          Move<VkBuffer>&                target,
713                                                                                                                                                          Context&                               ctx,
714                                                                                                                                                          BindingCaseParameters  params);
715
716 template <>
717 void                                                                    readUpResource                                          (Move<VkBuffer>&                source,
718                                                                                                                                                          Move<VkBuffer>&                target,
719                                                                                                                                                          Context&                               ctx,
720                                                                                                                                                          BindingCaseParameters  params)
721 {
722         fillUpResource(source, target, ctx, params);
723 }
724
725 template <>
726 void                                                                    readUpResource                                          (Move<VkImage>&                 source,
727                                                                                                                                                          Move<VkBuffer>&                target,
728                                                                                                                                                          Context&                               ctx,
729                                                                                                                                                          BindingCaseParameters  params)
730 {
731         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
732         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
733         const VkQueue                                           queue                                                           = ctx.getUniversalQueue();
734
735         const VkImageMemoryBarrier                      srcImageBarrier                                         = makeMemoryBarrierInfo(*source, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
736         const VkBufferMemoryBarrier                     dstBufferBarrier                                        = makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
737         const VkImageMemoryBarrier                      postImageBarrier                                        = makeMemoryBarrierInfo(*source, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
738
739         const VkCommandBufferBeginInfo          cmdBufferBeginInfo                                      = makeCommandBufferInfo();
740         Move<VkCommandPool>                                     commandPool                                                     = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
741         Move<VkCommandBuffer>                           cmdBuffer                                                       = createCommandBuffer(vk, vkDevice, *commandPool);
742
743         const VkBufferImageCopy                         copyRegion                                                      =
744         {
745                 0u,                                                                                                                                     // VkDeviceSize                 bufferOffset;
746                 params.imageSize.width,                                                                                         // deUint32                             bufferRowLength;
747                 params.imageSize.height,                                                                                        // deUint32                             bufferImageHeight;
748                 {
749                         VK_IMAGE_ASPECT_COLOR_BIT,                                                                              // VkImageAspectFlags   aspect;
750                         0u,                                                                                                                             // deUint32                             mipLevel;
751                         0u,                                                                                                                             // deUint32                             baseArrayLayer;
752                         1u,                                                                                                                             // deUint32                             layerCount;
753                 },                                                                                                                                      // VkImageSubresourceLayers imageSubresource;
754                 { 0, 0, 0 },                                                                                                            // VkOffset3D                   imageOffset;
755                 params.imageSize                                                                                                        // VkExtent3D                   imageExtent;
756         };
757
758         VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
759         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
760         vk.cmdCopyImageToBuffer(*cmdBuffer, *source, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *target, 1, (&copyRegion));
761         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 1, &postImageBarrier);
762         VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
763
764         const VkSubmitInfo                                      submitInfo                                                      = makeSubmitInfo(*cmdBuffer);
765         Move<VkFence>                                           fence                                                           = createFence(vk, vkDevice);
766
767         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
768         VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
769 }
770
771 void                                                                    createBuffer                                            (Move<VkBuffer>&                buffer,
772                                                                                                                                                          Move<VkDeviceMemory>&  memory,
773                                                                                                                                                          Context&                               ctx,
774                                                                                                                                                          BindingCaseParameters  params)
775 {
776         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
777         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
778         VkBufferCreateInfo                                      bufferParams                                            = makeBufferCreateInfo(ctx, params);
779         VkMemoryRequirements                            memReqs;
780
781         buffer = createBuffer(vk, vkDevice, &bufferParams);
782         vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
783
784         const VkMemoryAllocateInfo                      memAlloc                                                        = makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
785         VkDeviceMemory                                          rawMemory                                                       = DE_NULL;
786
787         vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
788         memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
789         VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
790 }
791
792 void                                                                    pushData                                                        (VkDeviceMemory                 memory,
793                                                                                                                                                          deUint32                               dataSeed,
794                                                                                                                                                          Context&                               ctx,
795                                                                                                                                                          BindingCaseParameters  params)
796 {
797         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
798         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
799         MemoryMappingRAII                                       hostMemory                                                      (vk, vkDevice, memory, 0u, params.bufferSize, 0u);
800         deUint8*                                                        hostBuffer                                                      = static_cast<deUint8*>(hostMemory.ptr());
801         SimpleRandomGenerator                           random                                                          (dataSeed);
802
803         for (deUint32 i = 0u; i < params.bufferSize; ++i)
804         {
805                 hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
806         }
807         hostMemory.flush(0u, params.bufferSize);
808 }
809
810 deBool                                                                  checkData                                                       (VkDeviceMemory                 memory,
811                                                                                                                                                          deUint32                               dataSeed,
812                                                                                                                                                          Context&                               ctx,
813                                                                                                                                                          BindingCaseParameters  params)
814 {
815         const DeviceInterface&                          vk                                                                      = ctx.getDeviceInterface();
816         const VkDevice                                          vkDevice                                                        = ctx.getDevice();
817         MemoryMappingRAII                                       hostMemory                                                      (vk, vkDevice, memory, 0u, params.bufferSize, 0u);
818         deUint8*                                                        hostBuffer                                                      = static_cast<deUint8*>(hostMemory.ptr());
819         SimpleRandomGenerator                           random                                                          (dataSeed);
820
821         for (deUint32 i = 0u; i < params.bufferSize; ++i)
822         {
823                 if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
824                         return DE_FALSE;
825         }
826         return DE_TRUE;
827 }
828
829 template<typename TTarget, deBool TDedicated>
830 class MemoryBindingInstance : public TestInstance
831 {
832 public:
833                                                                                 MemoryBindingInstance                           (Context&                               ctx,
834                                                                                                                                                          BindingCaseParameters  params)
835                                                                                 : TestInstance                                          (ctx)
836                                                                                 , m_params                                                      (params)
837         {
838         }
839
840         virtual tcu::TestStatus                         iterate                                                         (void)
841         {
842                 const std::vector<std::string>& extensions                                                      = m_context.getDeviceExtensions();
843                 const deBool                                    isSupported                                                     = std::find(extensions.begin(), extensions.end(), "VK_KHR_bind_memory2") != extensions.end();
844                 if (!isSupported)
845                 {
846                         TCU_THROW(NotSupportedError, "Not supported");
847                 }
848
849                 std::vector<de::SharedPtr<Move<TTarget> > >
850                                                                                 targets;
851                 MemoryRegionsList                               memory;
852
853                 createBindingTargets<TTarget>(targets, m_context, m_params);
854                 createMemory<TTarget, TDedicated>(targets, memory, m_context, m_params);
855                 makeBinding<TTarget>(targets, memory, m_context, m_params);
856
857                 Move<VkBuffer>                                  srcBuffer;
858                 Move<VkDeviceMemory>                    srcMemory;
859
860                 createBuffer(srcBuffer, srcMemory, m_context, m_params);
861                 pushData(*srcMemory, 1, m_context, m_params);
862
863                 Move<VkBuffer>                                  dstBuffer;
864                 Move<VkDeviceMemory>                    dstMemory;
865
866                 createBuffer(dstBuffer, dstMemory, m_context, m_params);
867
868                 deBool                                                  passed                                                          = DE_TRUE;
869                 for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
870                 {
871                         fillUpResource(srcBuffer, *targets[i], m_context, m_params);
872                         readUpResource(*targets[i], dstBuffer, m_context, m_params);
873                         passed = checkData(*dstMemory, 1, m_context, m_params);
874                 }
875
876                 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
877         }
878 private:
879         BindingCaseParameters                           m_params;
880 };
881
882 template<typename TTarget, deBool TDedicated>
883 class AliasedMemoryBindingInstance : public TestInstance
884 {
885 public:
886                                                                                 AliasedMemoryBindingInstance            (Context&                               ctx,
887                                                                                                                                                          BindingCaseParameters  params)
888                                                                                 : TestInstance                                          (ctx)
889                                                                                 , m_params                                                      (params)
890         {
891         }
892
893         virtual tcu::TestStatus                         iterate                                                         (void)
894         {
895                 const std::vector<std::string>& extensions                                                      = m_context.getDeviceExtensions();
896                 const deBool                                    isSupported                                                     = std::find(extensions.begin(), extensions.end(), "VK_KHR_bind_memory2") != extensions.end();
897                 if (!isSupported)
898                 {
899                         TCU_THROW(NotSupportedError, "Not supported");
900                 }
901
902                 std::vector<de::SharedPtr<Move<TTarget> > >
903                                                                                 targets[2];
904                 MemoryRegionsList                               memory;
905
906                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
907                         createBindingTargets<TTarget>(targets[i], m_context, m_params);
908                 createMemory<TTarget, TDedicated>(targets[0], memory, m_context, m_params);
909                 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
910                         makeBinding<TTarget>(targets[i], memory, m_context, m_params);
911
912                 Move<VkBuffer>                                  srcBuffer;
913                 Move<VkDeviceMemory>                    srcMemory;
914
915                 createBuffer(srcBuffer, srcMemory, m_context, m_params);
916                 pushData(*srcMemory, 2, m_context, m_params);
917
918                 Move<VkBuffer>                                  dstBuffer;
919                 Move<VkDeviceMemory>                    dstMemory;
920
921                 createBuffer(dstBuffer, dstMemory, m_context, m_params);
922
923                 deBool                                                  passed                                                          = DE_TRUE;
924                 for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
925                 {
926                         fillUpResource(srcBuffer, *(targets[0][i]), m_context, m_params);
927                         readUpResource(*(targets[1][i]), dstBuffer, m_context, m_params);
928                         passed = checkData(*dstMemory, 2, m_context, m_params);
929                 }
930
931                 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
932         }
933 private:
934         BindingCaseParameters                           m_params;
935 };
936
937 template<typename TInstance>
938 class MemoryBindingTest : public TestCase
939 {
940 public:
941                                                                                 MemoryBindingTest                                       (tcu::TestContext&              testCtx,
942                                                                                                                                                          const std::string&             name,
943                                                                                                                                                          const std::string&             description,
944                                                                                                                                                          BindingCaseParameters  params)
945                                                                                 : TestCase                                                      (testCtx, name, description)
946                                                                                 , m_params                                                      (params)
947         {
948         }
949
950         virtual                                                         ~MemoryBindingTest                                      (void)
951         {
952         }
953
954         virtual TestInstance*                           createInstance                                          (Context&                               ctx) const
955         {
956                 return new TInstance(ctx, m_params);
957         }
958
959 private:
960         BindingCaseParameters                           m_params;
961 };
962
963 } // unnamed namespace
964
965 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
966 {
967         de::MovePtr<tcu::TestCaseGroup>         group                                                           (new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));
968
969         de::MovePtr<tcu::TestCaseGroup>         regular                                                         (new tcu::TestCaseGroup(testCtx, "regular", "Basic memory binding tests."));
970         de::MovePtr<tcu::TestCaseGroup>         aliasing                                                        (new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));
971
972         de::MovePtr<tcu::TestCaseGroup>         regular_suballocated                            (new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
973         de::MovePtr<tcu::TestCaseGroup>         regular_dedicated                                       (new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));
974
975         de::MovePtr<tcu::TestCaseGroup>         aliasing_suballocated                           (new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
976
977         const VkDeviceSize                                      allocationSizes[]                                       = {     33, 257, 4087, 8095, 1*1024*1024 + 1    };
978
979         for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
980         {
981                 const VkDeviceSize                              bufferSize                                                      = allocationSizes[sizeNdx];
982                 const BindingCaseParameters             params                                                          = makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize);
983                 std::ostringstream                              testName;
984
985                 testName << "buffer_" << bufferSize;
986                 regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
987                 regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(), " ", params));
988                 aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
989         }
990
991         const deUint32                                          imageSizes[]                                            = {     8, 33, 257      };
992
993         for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
994         for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
995         {
996                 const deUint32                                  width                                                           = imageSizes[widthNdx];
997                 const deUint32                                  height                                                          = imageSizes[heightNdx];
998                 const BindingCaseParameters             regularparams                                           = makeBindingCaseParameters(10, width, height);
999                 std::ostringstream                              testName;
1000
1001                 testName << "image_" << width << '_' << height;
1002                 regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
1003                 regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), "", regularparams));
1004                 aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
1005         }
1006
1007         regular->addChild(regular_suballocated.release());
1008         regular->addChild(regular_dedicated.release());
1009
1010         aliasing->addChild(aliasing_suballocated.release());
1011
1012         group->addChild(regular.release());
1013         group->addChild(aliasing.release());
1014
1015         return group.release();
1016 }
1017
1018 } // memory
1019 } // vkt