1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
22 *//*--------------------------------------------------------------------*/
24 #include "vktMemoryBindingTests.hpp"
26 #include "vktTestCase.hpp"
27 #include "tcuTestLog.hpp"
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"
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;
60 class MemoryMappingRAII
63 MemoryMappingRAII (const DeviceInterface& deviceInterface,
64 const VkDevice& device,
65 VkDeviceMemory deviceMemory,
68 VkMemoryMapFlags flags)
69 : vk (deviceInterface)
71 , memory (deviceMemory)
75 vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
80 vk.unmapMemory(dev, memory);
89 void flush (VkDeviceSize offset,
92 const VkMappedMemoryRange range = makeMemoryRange(offset, size);
93 VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
97 const DeviceInterface& vk;
99 VkDeviceMemory memory;
102 const VkMappedMemoryRange makeMemoryRange (VkDeviceSize offset,
105 const VkMappedMemoryRange range =
107 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
117 class SimpleRandomGenerator
120 SimpleRandomGenerator (deUint32 seed)
126 value ^= (value << 21);
127 value ^= (value >> 15);
128 value ^= (value << 4);
135 struct BindingCaseParameters
137 VkBufferCreateFlags flags;
138 VkBufferUsageFlags usage;
139 VkSharingMode sharing;
140 VkDeviceSize bufferSize;
141 VkExtent3D imageSize;
142 deUint32 targetsCount;
145 BindingCaseParameters makeBindingCaseParameters (deUint32 targetsCount,
149 BindingCaseParameters params;
150 deMemset(¶ms, 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;
160 BindingCaseParameters makeBindingCaseParameters (deUint32 targetsCount,
161 VkBufferUsageFlags usage,
162 VkSharingMode sharing,
163 VkDeviceSize bufferSize)
165 BindingCaseParameters params =
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;
177 VkImageCreateInfo makeImageCreateInfo (BindingCaseParameters& params)
179 const VkImageCreateInfo imageParams =
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;
200 VkBufferCreateInfo makeBufferCreateInfo (Context& ctx,
201 BindingCaseParameters& params)
203 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
204 VkBufferCreateInfo bufferParams =
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;
218 const VkMemoryAllocateInfo makeMemoryAllocateInfo (VkMemoryRequirements& memReqs,
219 ConstDedicatedInfo* next)
221 const deUint32 heapTypeIndex = (deUint32)deCtz32(memReqs.memoryTypeBits);
222 const VkMemoryAllocateInfo allocateParams =
224 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
225 next, // const void* pNext;
226 memReqs.size, // VkDeviceSize allocationSize;
227 heapTypeIndex, // uint32_t memoryTypeIndex;
229 return allocateParams;
232 enum MemoryHostVisibility
238 deUint32 selectMatchingMemoryType (Context& ctx,
239 VkMemoryRequirements& memReqs,
240 MemoryHostVisibility memoryVisibility)
242 const VkPhysicalDevice vkPhysicalDevice = ctx.getPhysicalDevice();
243 const InstanceInterface& vkInstance = ctx.getInstanceInterface();
244 VkPhysicalDeviceMemoryProperties memoryProperties;
246 vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
247 if (memoryVisibility == MemoryHostVisible)
249 for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
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)
257 return (deUint32)deCtz32(memReqs.memoryTypeBits);
260 const VkMemoryAllocateInfo makeMemoryAllocateInfo (Context& ctx,
261 VkMemoryRequirements& memReqs,
262 MemoryHostVisibility memoryVisibility)
264 const deUint32 heapTypeIndex = selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
265 const VkMemoryAllocateInfo allocateParams =
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;
272 return allocateParams;
275 ConstDedicatedInfo makeDedicatedAllocationInfo (VkBuffer buffer)
277 ConstDedicatedInfo dedicatedAllocationInfo =
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
284 return dedicatedAllocationInfo;
287 ConstDedicatedInfo makeDedicatedAllocationInfo (VkImage image)
289 ConstDedicatedInfo dedicatedAllocationInfo =
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
296 return dedicatedAllocationInfo;
299 const VkBindBufferMemoryInfoKHR makeBufferMemoryBindingInfo (VkBuffer buffer,
300 VkDeviceMemory memory)
302 const VkBindBufferMemoryInfoKHR bufferMemoryBinding =
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;
310 return bufferMemoryBinding;
313 const VkBindImageMemoryInfoKHR makeImageMemoryBindingInfo (VkImage image,
314 VkDeviceMemory memory)
316 const VkBindImageMemoryInfoKHR imageMemoryBinding =
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;
324 return imageMemoryBinding;
327 enum TransferDirection
329 TransferToResource = 0,
330 TransferFromResource = 1
333 const VkBufferMemoryBarrier makeMemoryBarrierInfo (VkBuffer buffer,
335 TransferDirection direction)
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 =
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;
352 return bufferBarrier;
355 const VkImageMemoryBarrier makeMemoryBarrierInfo (VkImage image,
356 VkAccessFlags srcAccess,
357 VkAccessFlags dstAccess,
358 VkImageLayout oldLayout,
359 VkImageLayout newLayout)
361 const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
362 const VkImageMemoryBarrier imageBarrier =
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;
384 const VkCommandBufferBeginInfo makeCommandBufferInfo ()
386 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
388 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
390 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
391 static_cast<const VkCommandBufferInheritanceInfo*>(DE_NULL)
393 return cmdBufferBeginInfo;
396 const VkSubmitInfo makeSubmitInfo (const VkCommandBuffer& commandBuffer)
398 const VkSubmitInfo submitInfo =
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;
413 Move<VkCommandBuffer> createCommandBuffer (const DeviceInterface& vk,
415 VkCommandPool commandPool)
417 const VkCommandBufferAllocateInfo allocInfo =
419 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
422 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
425 return allocateCommandBuffer(vk, device, &allocInfo);
429 template<typename TTarget>
430 void createBindingTargets (std::vector<de::SharedPtr<Move<TTarget> > >&
433 BindingCaseParameters params);
436 void createBindingTargets<VkBuffer> (BuffersList& targets,
438 BindingCaseParameters params)
440 const deUint32 count = params.targetsCount;
441 const VkDevice vkDevice = ctx.getDevice();
442 const DeviceInterface& vk = ctx.getDeviceInterface();
444 targets.reserve(count);
445 for (deUint32 i = 0u; i < count; ++i)
447 VkBufferCreateInfo bufferParams = makeBufferCreateInfo(ctx, params);
448 targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
453 void createBindingTargets<VkImage> (ImagesList& targets,
455 BindingCaseParameters params)
457 const deUint32 count = params.targetsCount;
458 const VkDevice vkDevice = ctx.getDevice();
459 const DeviceInterface& vk = ctx.getDeviceInterface();
461 targets.reserve(count);
462 for (deUint32 i = 0u; i < count; ++i)
464 VkImageCreateInfo imageParams = makeImageCreateInfo(params);
465 targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
469 template<typename TTarget, deBool TDedicated>
470 void createMemory (std::vector<de::SharedPtr<Move<TTarget> > >&
472 MemoryRegionsList& memory,
474 BindingCaseParameters params);
477 void createMemory<VkBuffer, DE_FALSE> (BuffersList& targets,
478 MemoryRegionsList& memory,
480 BindingCaseParameters params)
483 const deUint32 count = static_cast<deUint32>(targets.size());
484 const DeviceInterface& vk = ctx.getDeviceInterface();
485 const VkDevice vkDevice = ctx.getDevice();
487 memory.reserve(count);
488 for (deUint32 i = 0; i < count; ++i)
490 VkMemoryRequirements memReqs;
492 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
494 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, DE_NULL);
495 VkDeviceMemory rawMemory = DE_NULL;
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))));
503 void createMemory<VkImage, DE_FALSE> (ImagesList& targets,
504 MemoryRegionsList& memory,
506 BindingCaseParameters params)
509 const deUint32 count = static_cast<deUint32>(targets.size());
510 const DeviceInterface& vk = ctx.getDeviceInterface();
511 const VkDevice vkDevice = ctx.getDevice();
513 memory.reserve(count);
514 for (deUint32 i = 0; i < count; ++i)
516 VkMemoryRequirements memReqs;
517 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
519 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, DE_NULL);
520 VkDeviceMemory rawMemory = DE_NULL;
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))));
528 void createMemory<VkBuffer, DE_TRUE> (BuffersList& targets,
529 MemoryRegionsList& memory,
531 BindingCaseParameters params)
534 const deUint32 count = static_cast<deUint32>(targets.size());
535 const DeviceInterface& vk = ctx.getDeviceInterface();
536 const VkDevice vkDevice = ctx.getDevice();
538 memory.reserve(count);
539 for (deUint32 i = 0; i < count; ++i)
541 VkMemoryRequirements memReqs;
543 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
545 ConstDedicatedInfo dedicatedAllocationInfo = makeDedicatedAllocationInfo(**targets[i]);;
546 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
547 VkDeviceMemory rawMemory = DE_NULL;
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))));
555 void createMemory<VkImage, DE_TRUE> (ImagesList& targets,
556 MemoryRegionsList& memory,
558 BindingCaseParameters params)
561 const deUint32 count = static_cast<deUint32>(targets.size());
562 const DeviceInterface& vk = ctx.getDeviceInterface();
563 const VkDevice vkDevice = ctx.getDevice();
565 memory.reserve(count);
566 for (deUint32 i = 0; i < count; ++i)
568 VkMemoryRequirements memReqs;
569 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
571 ConstDedicatedInfo dedicatedAllocationInfo = makeDedicatedAllocationInfo(**targets[i]);
572 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
573 VkDeviceMemory rawMemory = DE_NULL;
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))));
580 template<typename TTarget>
581 void makeBinding (std::vector<de::SharedPtr<Move<TTarget> > >&
583 MemoryRegionsList& memory,
585 BindingCaseParameters params);
588 void makeBinding<VkBuffer> (BuffersList& targets,
589 MemoryRegionsList& memory,
591 BindingCaseParameters 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;
599 for (deUint32 i = 0; i < count; ++i)
601 bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
604 VK_CHECK(vk.bindBufferMemory2KHR(vkDevice, count, &bindMemoryInfos.front()));
608 void makeBinding<VkImage> (ImagesList& targets,
609 MemoryRegionsList& memory,
611 BindingCaseParameters 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;
619 for (deUint32 i = 0; i < count; ++i)
621 bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
624 VK_CHECK(vk.bindImageMemory2KHR(vkDevice, count, &bindMemoryInfos.front()));
627 template <typename TTarget>
628 void fillUpResource (Move<VkBuffer>& source,
629 Move<TTarget>& target,
631 BindingCaseParameters params);
634 void fillUpResource<VkBuffer> (Move<VkBuffer>& source,
635 Move<VkBuffer>& target,
637 BindingCaseParameters params)
639 const DeviceInterface& vk = ctx.getDeviceInterface();
640 const VkDevice vkDevice = ctx.getDevice();
641 const VkQueue queue = ctx.getUniversalQueue();
643 const VkBufferMemoryBarrier srcBufferBarrier = makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
644 const VkBufferMemoryBarrier dstBufferBarrier = makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
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 };
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));
657 const VkSubmitInfo submitInfo = makeSubmitInfo(*cmdBuffer);
658 Move<VkFence> fence = createFence(vk, vkDevice);
660 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
661 VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
665 void fillUpResource<VkImage> (Move<VkBuffer>& source,
666 Move<VkImage>& target,
668 BindingCaseParameters params)
670 const DeviceInterface& vk = ctx.getDeviceInterface();
671 const VkDevice vkDevice = ctx.getDevice();
672 const VkQueue queue = ctx.getUniversalQueue();
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);
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);
682 const VkBufferImageCopy copyRegion =
684 0u, // VkDeviceSize bufferOffset;
685 params.imageSize.width, // deUint32 bufferRowLength;
686 params.imageSize.height, // deUint32 bufferImageHeight;
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;
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, (©Region));
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));
703 const VkSubmitInfo submitInfo = makeSubmitInfo(*cmdBuffer);
704 Move<VkFence> fence = createFence(vk, vkDevice);
706 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
707 VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
710 template <typename TTarget>
711 void readUpResource (Move<TTarget>& source,
712 Move<VkBuffer>& target,
714 BindingCaseParameters params);
717 void readUpResource (Move<VkBuffer>& source,
718 Move<VkBuffer>& target,
720 BindingCaseParameters params)
722 fillUpResource(source, target, ctx, params);
726 void readUpResource (Move<VkImage>& source,
727 Move<VkBuffer>& target,
729 BindingCaseParameters params)
731 const DeviceInterface& vk = ctx.getDeviceInterface();
732 const VkDevice vkDevice = ctx.getDevice();
733 const VkQueue queue = ctx.getUniversalQueue();
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);
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);
743 const VkBufferImageCopy copyRegion =
745 0u, // VkDeviceSize bufferOffset;
746 params.imageSize.width, // deUint32 bufferRowLength;
747 params.imageSize.height, // deUint32 bufferImageHeight;
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;
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, (©Region));
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));
764 const VkSubmitInfo submitInfo = makeSubmitInfo(*cmdBuffer);
765 Move<VkFence> fence = createFence(vk, vkDevice);
767 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
768 VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
771 void createBuffer (Move<VkBuffer>& buffer,
772 Move<VkDeviceMemory>& memory,
774 BindingCaseParameters params)
776 const DeviceInterface& vk = ctx.getDeviceInterface();
777 const VkDevice vkDevice = ctx.getDevice();
778 VkBufferCreateInfo bufferParams = makeBufferCreateInfo(ctx, params);
779 VkMemoryRequirements memReqs;
781 buffer = createBuffer(vk, vkDevice, &bufferParams);
782 vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
784 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
785 VkDeviceMemory rawMemory = DE_NULL;
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));
792 void pushData (VkDeviceMemory memory,
795 BindingCaseParameters params)
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);
803 for (deUint32 i = 0u; i < params.bufferSize; ++i)
805 hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
807 hostMemory.flush(0u, params.bufferSize);
810 deBool checkData (VkDeviceMemory memory,
813 BindingCaseParameters params)
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);
821 for (deUint32 i = 0u; i < params.bufferSize; ++i)
823 if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
829 template<typename TTarget, deBool TDedicated>
830 class MemoryBindingInstance : public TestInstance
833 MemoryBindingInstance (Context& ctx,
834 BindingCaseParameters params)
840 virtual tcu::TestStatus iterate (void)
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();
846 TCU_THROW(NotSupportedError, "Not supported");
849 std::vector<de::SharedPtr<Move<TTarget> > >
851 MemoryRegionsList memory;
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);
857 Move<VkBuffer> srcBuffer;
858 Move<VkDeviceMemory> srcMemory;
860 createBuffer(srcBuffer, srcMemory, m_context, m_params);
861 pushData(*srcMemory, 1, m_context, m_params);
863 Move<VkBuffer> dstBuffer;
864 Move<VkDeviceMemory> dstMemory;
866 createBuffer(dstBuffer, dstMemory, m_context, m_params);
868 deBool passed = DE_TRUE;
869 for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
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);
876 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
879 BindingCaseParameters m_params;
882 template<typename TTarget, deBool TDedicated>
883 class AliasedMemoryBindingInstance : public TestInstance
886 AliasedMemoryBindingInstance (Context& ctx,
887 BindingCaseParameters params)
893 virtual tcu::TestStatus iterate (void)
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();
899 TCU_THROW(NotSupportedError, "Not supported");
902 std::vector<de::SharedPtr<Move<TTarget> > >
904 MemoryRegionsList memory;
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);
912 Move<VkBuffer> srcBuffer;
913 Move<VkDeviceMemory> srcMemory;
915 createBuffer(srcBuffer, srcMemory, m_context, m_params);
916 pushData(*srcMemory, 2, m_context, m_params);
918 Move<VkBuffer> dstBuffer;
919 Move<VkDeviceMemory> dstMemory;
921 createBuffer(dstBuffer, dstMemory, m_context, m_params);
923 deBool passed = DE_TRUE;
924 for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
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);
931 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
934 BindingCaseParameters m_params;
937 template<typename TInstance>
938 class MemoryBindingTest : public TestCase
941 MemoryBindingTest (tcu::TestContext& testCtx,
942 const std::string& name,
943 const std::string& description,
944 BindingCaseParameters params)
945 : TestCase (testCtx, name, description)
950 virtual ~MemoryBindingTest (void)
954 virtual TestInstance* createInstance (Context& ctx) const
956 return new TInstance(ctx, m_params);
960 BindingCaseParameters m_params;
963 } // unnamed namespace
965 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
967 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));
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."));
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."));
975 de::MovePtr<tcu::TestCaseGroup> aliasing_suballocated (new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
977 const VkDeviceSize allocationSizes[] = { 33, 257, 4087, 8095, 1*1024*1024 + 1 };
979 for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
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;
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));
991 const deUint32 imageSizes[] = { 8, 33, 257 };
993 for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
994 for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
996 const deUint32 width = imageSizes[widthNdx];
997 const deUint32 height = imageSizes[heightNdx];
998 const BindingCaseParameters regularparams = makeBindingCaseParameters(10, width, height);
999 std::ostringstream testName;
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));
1007 regular->addChild(regular_suballocated.release());
1008 regular->addChild(regular_dedicated.release());
1010 aliasing->addChild(aliasing_suballocated.release());
1012 group->addChild(regular.release());
1013 group->addChild(aliasing.release());
1015 return group.release();