Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vulkan memory alignment requirements

I'm implementing a naive memory manager for Vulkan device memory, and would like to make sure that I understand the alignment requirements for memory and how to satisfy them.

So, assuming that I've allocated a 'pool' of memory using vkAllocateMemory and wish to sub-allocate blocks of memory in this pool to individual resources (based on a VkMemoryRequirements struct), will the following pseudocode be able to allocate a section of this memory with the correct size and alignment requirements?

  • Request memory with RequiredSize and RequiredAlignment
  • Iterate over blocks in the pool looking for one that is free and has size > RequiredSize
  • If the offset in memory of the current block is NOT divisible by RequiredAlignment, figure out the difference between the alignment and the remainder
  • If the size of the current block minus the difference is less than RequiredSize, skip to the next block in the pool
  • If the difference is more than 0, insert a padding block with size equal to the difference, and adjust the current unallocated block size and offset
  • Allocate RequiredSize bytes from the start of the current unallocated block (now aligned), adjust the Size and Offset of the unallocated block accordingly
  • Return vkDeviceMemory handle (of pool), size and offset (of new allocated block)
  • If we reach the end of the block list instead, this pool cannot allocate the memory

In other words, do we just need to make sure that Offset is a multiple of RequiredAlignment?

like image 751
Scott Oliver Avatar asked Sep 03 '25 02:09

Scott Oliver


1 Answers

In other words, do we just need to make sure that Offset is a multiple of RequiredAlignment?

for alignment that is nearly sufficient.

in vkBindbufferMemory one of the valid usage requirements is:

memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

and there is a parallel statement in the valid usage requirements of vkBindImageMemory:

memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image

If the previous block contains a non-linear resource while the current one is linear or vice versa then the alignment requirement is the max of the VkMemoryRequirements.alignment and the device's bufferImageGranularity. This also needs to be check for the end of the memory block.

However you also need to take into account that the memory type of the pool must be set in the memoryTypeBits flags of VkMemoryRequirements .

like image 143
ratchet freak Avatar answered Sep 04 '25 15:09

ratchet freak