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
Dynamic offset validation error when buffer range is VK_WHOLE_SIZE #2846
Comments
Thanks for the issue @llyzs! It seems like the effective offset could still go past the end of the buffer, so I'm not sure 01979 can/should be completely ignored when
|
Fix offset check when VK_WHOLE_SIZE is used. Closes KhronosGroup#2846. Change-Id: I9c1c1104f808922b1a6e4168622a913673bde075
Fix offset check when VK_WHOLE_SIZE is used. Closes KhronosGroup#2846. Change-Id: I9c1c1104f808922b1a6e4168622a913673bde075
So if we have a 64 byte buffer and we set VkBuffer buffer; // 64 bytes
VkDescriptorBufferInfo info_a = {buffer, 8, VK_WHOLE_SIZE};
VkDescriptorBufferInfo info_b = {buffer, 8, 32}; With no dynamic offset,
if my
I guess the
I read the spec saying
that |
My opinion is that the spec regarding "range is the static size used for all dynamic offsets" statement is somewhat "ambiguous". The "range" value here can be treated as an "effective range" before dynamic offset is applied as you wrote, or can be treated as whatever value it contains. In your example above, one could argue that when pDynamicOffsets is 16, the actual descriptor can be shifted like this:
I think the spec needs to be more specific when the range value is VK_WHOLE_SIZE here. |
Our use case is that we create a single big 64k UBO and a single descriptor with range = VK_WHOLE_SIZE, which contains dozens of chunks of data of different sizes. When binding the UBO we use dynamic offsets with this single UBO descriptor. It worked without any issue until this validation error pops up recently (although rendering is never an issue). If we are going to follow the "effective range before dynamic offset applied" interpretation of VK_WHOLE_SIZE, we will need to create multiple descriptors of different sizes in order to avoid the error, and performance impact could also be a concern. |
Hi @llyzs - unfortunately @sfricke-samsung is interpreting the spec correctly. As far as I understand it, the end point of a buffer's range is baked into the descriptor on most GPUs - so baking multiple descriptors actually is the only option. If you're not using robust buffer access and you're staying within the actual buffer range it is likely fine most of the time. But it's one of those things that will likely blow up in unexpected ways at the worst possible moment (e.g. on an end user device). If you're targeting platforms supporting VK_KHR/EXT_buffer_device_address you might want to consider using device addresses via push constants as a way to push uniform data dynamically. That has no "end" to the range so you can just update the pointer on every draw with the new offset. |
Oh also, FWIW the spec is nowhere near as clear here as it should be so we should definitely get the spec text updated.. |
@Tobski Thanks for the clarification and the spec update proposal. We will update our application accordingly. Closing this issue. |
When buffer range is VK_WHOLE_SIZE and dynamic offset is larger than zero, the validation layer issues the following error:
Validation Error: [ VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979 ] Object 0: handle = 0x7ffe368a1ea8, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x2e237000001b59c, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; Object 2: handle = 0x1285ab0000012cb2, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xa159a763 | vkCmdBindDescriptorSets(): pDynamicOffsets[0] is 0x5700, but must be zero since the buffer descriptor's range is VK_WHOLE_SIZE in descriptorSet #0 binding #0 descriptor[0]. The Vulkan spec states: For each dynamic uniform or storage buffer binding in pDescriptorSets, the sum of the effective offset, as defined above, and the range of the binding must be less than or equal to the size of the buffer (https://vulkan.lunarg.com/doc/view/1.2.176.1/linux/1.2-extensions/vkspec.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979)
However according to the spec "range is the size in bytes that is used for this descriptor update, or VK_WHOLE_SIZE to use the range from offset to the end of the buffer.". Validation should to check the range if its value is VK_WHOLE_SIZE because its meaning is not a fixed size, but a dynamic size from the offset to the end of the buffer.
If we are forced to use a specific range number other than VK_WHOLE_SIZE to bypass the error, we will need to write different descriptor for each different dynamic offset, which makes the whole point of dynamic offset useless.
If my understanding is correct, the spec should also clarify that VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979 only apply if range is not VK_WHOLE_SIZE.
The text was updated successfully, but these errors were encountered: