Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uncertainties with sparse resource memory type requirements #2506

Open
Robert-Hilmes opened this issue Mar 8, 2025 · 0 comments
Open

uncertainties with sparse resource memory type requirements #2506

Robert-Hilmes opened this issue Mar 8, 2025 · 0 comments

Comments

@Robert-Hilmes
Copy link

I've asked about this on the Vulkan Discord already, but havent recieved an answer yet, so i'm asking here a bit more in depth now.

Issue
do sparse resources require to be bound to a memory type reported by VkMemoryRequirements::memoryTypeBits?

Explanation
the memoryTypeBitsmember description in VkMemoryRequirements

memoryTypeBits is a bitmask and contains one bit set for every supported memory type for the resource. Bit i is set if and only if the memory type i in the VkPhysicalDeviceMemoryProperties structure for the physical device is supported for the resource.

i interpret this as a given resources must be bound to a valid memory type or memory types(in case of sparse resources)
this is the only general resource memory type requirement i found, however for non-sparse resource binding functions and info structures there is an additional explicit valid usage point reinforcing this description, there are also valid usage points reinforcing the other VkMemoryRequirements members.

these reinforcing valid usage points are partially present with vkQueueBindSparse and its info structures for
VkMemoryRequirements::size
VkMemoryRequirements::alignment
but not the VkMemoryRequirements::memoryTypeBits

For binding non-sparse resources
with vkBindBufferMemory

VUID-vkBindBufferMemory-memory-01035
memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

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

VUID-vkBindBufferMemory-size-01037
The size member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or equal to the size of memory minus memoryOffset

in vkBindBufferMemory2 with VkBindBufferMemoryInfo

VUID-VkBindBufferMemoryInfo-memory-01035
memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer

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

VUID-VkBindBufferMemoryInfo-size-01037
The size member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or equal to the size of memory minus memoryOffset

with vkBindImageMemory

VUID-vkBindImageMemory-memory-01047
memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image

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

VUID-vkBindImageMemory-size-01049
The difference of the size of memory and memoryOffset must be greater than or equal to the size member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with the same image

with vkBindImageMemory2 in VkBindImageMemoryInfo

VUID-VkBindImageMemoryInfo-pNext-01615
If the pNext chain does not include a VkBindImagePlaneMemoryInfo structure, memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements2 with image

VUID-VkBindImageMemoryInfo-pNext-01616
If the pNext chain does not include a VkBindImagePlaneMemoryInfo structure, memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements2 with image

VUID-VkBindImageMemoryInfo-pNext-01617
If the pNext chain does not include a VkBindImagePlaneMemoryInfo structure, the difference of the size of memory and memoryOffset must be greater than or equal to the size member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements2 with the same image

Note: all these non-sparse binding functions have explicit valid usage points for
VkMemoryRequirements::size
VkMemoryRequirements::alignment
VkMemoryRequirements::memoryTypeBits

For binding sparse resources with vkQueueBindSparse
in VkSparseMemoryBind

*in the description*
If flags does not contain VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range must be within the range [0,VkMemoryRequirements::size).

VUID-VkSparseMemoryBind-memory-01096
If memory is not VK_NULL_HANDLE, memory and memoryOffset must match the memory requirements of the resource, as described in section https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#resources-association

VUID-VkSparseMemoryBind-resourceOffset-09491
If the resource being bound is a VkBuffer, resourceOffset, memoryOffset and size must be an integer multiple of the alignment of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with the buffer resource

VUID-VkSparseMemoryBind-resourceOffset-09492
If the resource being bound is a VkImage, resourceOffset and memoryOffset must be an integer multiple of the alignment of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with the image resource

Note: the description and valid usage points here only cover
VkMemoryRequirements::size
VkMemoryRequirements::alignment
but not the VkMemoryRequirements::memoryTypeBits

in VkSparseImageMemoryBind

VUID-VkSparseImageMemoryBind-memory-01105
memory and memoryOffset must match the memory requirements of the calling command’s image, as described in section https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#resources-association

Note: here the memory layout/alignment requirements are queried through the vkGetImageSparseMemoryRequirements or vkGetImageSparseMemoryRequirements2 functions, and and the corresponding valid usage points were quite a lot which is why i didnt list them.
Note: no valid usage points regarding VkMemoryRequirements::memoryTypeBits

in both VkSparseMemoryBind and VkSparseImageMemoryBind there is nothing explicitly requiring the memory type of the memory allocation to be one of VkMemoryRequirements::memoryTypeBits
the only valid usage point indicating such requirement for both is this

[...] memory and memoryOffset must match the memory requirements of the resource/calling command’s image, as described in section https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#resources-association

however in the Resource Memory Association and Sparse Resource sections i could not find anything explicit regarding memory to be allocated with a valid memory type from VkMemoryRequirements::memoryTypeBits when binding to a given sparse resource, except the member description of VkMemoryRequirements::memoryTypeBits.
which is weird because for non-sparse resource binding functions there is an explicit mention about this ...

Additional Info
i have tested creating a sparse buffer and binding it with incompatible memory types on NVIDIA and AMD drivers and with worked without any validation errors or exceptions or crashes, which doesnt mean that its valid, just that it works ...

Conclusion
at the moment i am not sure if this is just overlooked, intentional, or i have missed something ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant