Zebrafish
Zebrafish

Reputation: 13876

The proper way to invalidate and flush Vulkan memory

When flushing and invalidating non-coherent memory in Vulkan you need to do it to ranges with a starting offset and size both aligned to an alignment called 'nonCoherentAtomSize', which on my physical device is 128 bytes. To do this you would round DOWN the starting offset and round UP the size to this alignment (128 bytes). The issue I can see is that types have a less strict (smaller) alignment, and this rounding up and down can spill the range outside the memory of the allocation. So:

// CREATE A BUFFER WITH SIZE 17
VkMemoryRequirements memRequirements;
vkGetBufferMemoryRequirements(logicalDevice, vk_buffer, &memRequirements);

memRequirements.size; // == 20
memRequirements.alignment; // == 4
// ON MY SETUP

Let's just say I allocate 20 bytes of memory and I this buffer at the beginning, (0), and I want to flush this range, I would flush offset 0 with size 20 (but this needs to rounded up to 128 (nonCoherentAtomSize), which is bigger than the buffer. This isn't right, right? Likewise, is the memory returned from vkAllocateMemory guaranteed to be aligned to at least the nonCoherentAtomSize? If not the memory might begin only at a 16-byte alignment, and if I round down then I'm flushing a range before the memory, right?

Edit: Sorry, it's impossible in the case of rounding down, because the argument to flush and invalidate is an offset, anything rounded down to its alignment cannot be less than 0. But in the case of rounding up it's still a problem I can see.

Upvotes: 3

Views: 796

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473447

There is never a reason to map a range of an allocation which is not aligned to nonCoherentAtomSize. If you do this, then you will find that you will be unable to properly flush or invalidate part of that range.

Indeed, there is no reason to ever map only part of an allocation you intend to map. Just map the whole thing, immediately after allocating it. At which point, you can use VK_WHOLE_SIZE to specify a size if the nonCoherentAtomSize aligned size exceeds the allocation range.

Upvotes: 3

Related Questions