Reputation: 1890
So I am using dynamic uniform buffers in Vulkan to upload the transformation matrix of a bunch of objects for each frame to one big buffer. I have two "virtual frames" with two descriptor sets that I alternate between the frames. They both use the same big buffer at different offsets. When I log all the values that I use to bind the buffer to the descriptor sets, all seems well. The two sets are updated with the following infos:
VkDescriptorBufferInfo{ .offset = 0, .range = 704, .buffer = ... }
VkDescriptorBufferInfo{ .offset = 704, .range = 704, .buffer = ... }
The buffer in question is 1408
bytes in size. I draw 11 objects each frame, where each object consumes 64 bytes for 1 4x4 floating point matrix (note 11 x 64 = 704, it all checks out). So the dynamic offsets I use increase with 64
bytes per draw call.
I have triple checked all my offsets, however Vulkan still throws this error on the second frame (with the bound buffer offset of 704), for any dynamic offset > 0:
Validation Error: [ VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979 ] Object 0: handle = 0x55cc0d782010, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xa21a4e0000000030, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; Object 2: handle = 0x2e2941000000001f, type = VK_OBJECT_TYPE_BUFFER; | MessageID = 0xa159a763 | vkCmdBindDescriptorSets(): pDynamicOffsets[0] is 0x40 which when added to the buffer descriptor's range (0x2c0) is greater than the size of the buffer (0x580) 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.3.204.1/linux/1.3-extensions/vkspec.html#VUID-vkCmdBindDescriptorSets-pDescriptorSets-01979)
Except as far as I can tell this error literally contradicts itself. It says the dynamic offset of 0x40
(i.e. 64
), when added to the bound buffer's range of 0x2c0
(i.e. 704
) is greater than the size 0x580
(i.e. 1408
). Which it is not, 0x40 + 0x2c0 = 0x300
and 0x300 < 0x580
.
The actual effective offset within the buffer (ignoring its own base offset into the VkDeviceMemory object), as far as I'm aware, should be 704 + 64
, as the buffer is bound at 704 and the dynamic offset is 64. Which is still less than 1408
, the actual buffer's size.
Any clue as to what is going on here?
Upvotes: 0
Views: 482
Reputation: 1890
Ok after an entire afternoon of debugging and searching, according to the Vulkan spec on VkDescriptorBufferInfo:
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.
and
For VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC descriptor types, offset is the base offset from which the dynamic offset is applied and range is the static size used for all dynamic offsets.
range
denotes the uploaded size, so for each offset that's only the size used for that draw call. I was giving it the range of the entire dynamic buffer. So range should be 64
not 704
:)
Upvotes: 1