bufferImageGranularity explanation is unclear

I’m finding the explanation for bufferImageGranularity and where it needs to be applied unclear. A few points in particular that seem confusing, at least to me:

Despite its name, bufferImageGranularity is really a granularity between “linear” and “non-linear” resources.

From this I would assume that all optimal images need to be on their own ‘page’ and everything else simply needs to satisfy its memory requirement alignment? Can multiple optimal images share the same page (as long as its not shared with non-optimal and they have appropriate alignment)?

Does vkGetImageMemoryRequirements() take into account bufferImageGranularity? Say I created an image with VK_IMAGE_TILING_OPTIMAL, will vkGetImageMemoryRequirements() adjust the align/size members of VkMemoryRequirements or do I need to do that?

This restriction is only needed when a linear resource and a non-linear resource are adjacent in memory and will be used simultaneously. The memory ranges of adjacent resources can be closer than bufferImageGranularity, provided they meet the alignment requirement for the objects in question.

What constitutes a ‘use’? Is that read or write, or just writes? And if they shared the same ‘page’ what sort of synchronization/memory barriers would I need?

Allocations returned by vkAllocateMemory are guaranteed to meet any alignment requirement by the implementation. For example, if an implementation requires 128 byte alignment for images and 64 byte alignment for buffers, the device memory returned through this mechanism would be 128-byte aligned. This ensures that applications can correctly suballocate objects of different types (with potentially different alignment requirements) in the same memory object.

Does this alignment take into account bufferImageGranularity? If it doesn’t how would one ensure resources are properly aligned?

“between ‘linear’ and ‘non-linear’ resources” means exactly what it says: between those two types of resources. The spec goes into detail about this immediately afterwards:

The need for satisfying the granularity constraint only apples when the emphasized portion is true.

No, it cannot. The image granuarity is about the relationship between two resources. And specifically between two different resources. vkGetImageMemoryRequirements only applies to a single resource.

The spec explains this as well. If you have two image resources which violate the granularity rule, then the two image resources are considered to alias one another. Section 11.8: Memory Aliasing covers what that means, but the short version is that you can’t do anything with one of them without rendering the contents of the other undefined.

So really, don’t violate the granularity rule.

The granularity rule only concerns itself with images in the same memory allocation, the “same VkDeviceMemory object”. Therefore, whatever potential underlying conflict the hardware creates with regard to granularity must be sorted out by the implementation. It could do this in several ways.

Maybe the implementation doesn’t allow linear and non-linear images to be in the same memory object at all. That is, some memory types are restricted to linear and some to non-linear, with no overlap. Maybe the implementation rounds up all allocations to granularity boundaries. Or maybe something else entirely.

However the implementation deals with this is irrelevant. What matters is that granularity only matters for images in the same allocation, and the implementation will sort out the details.

So I can put multiple optimal images in the same ‘page’, and non-optimal in the same page, just not mix the two, correct?