Vulkan 中 maxUniformBufferRange 的含义

Meaning of maxUniformBufferRange in Vulkan

我目前正在试用 Vulkan。我做的一件事是递归渲染 Menger 海绵 (https://en.wikipedia.org/wiki/Menger_sponge)。 现在 Menger 海绵的一级包含 20 个子立方体。你可以想象在第 4 阶段(第 0 阶段只是一个立方体)你最终会得到 20^4 个立方体。 为了在正确的位置显示它们,我最终创建了很多模型矩阵(每个立方体一个)并将它们写入动态统一缓冲区(按照此处的示例:https://github.com/SaschaWillems/Vulkan/tree/master/examples/dynamicuniformbuffer)。 对于第 4 阶段,您将有 20^4 个立方体,这意味着 160,000 个模型矩阵,每个矩阵 64 字节 = 10,240,000 字节。 在尝试更新动态统一缓冲区的描述符集时,我从 Vulkan 验证层收到了一些消息:

Attempted write update to buffer descriptor failed due to: 
For buffer VkBuffer 0x22df6d00000000e8[] VkDescriptorBufferInfo range is VK_WHOLE_SIZE 
but effective range (10240000) is greater than this device's maxUniformBufferRange (65536).

The Vulkan spec states: If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER 
or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of each element of pBufferInfo, 
or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to
VkPhysicalDeviceLimits::maxUniformBufferRange
(https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#VUID-VkWriteDescriptorSet-descriptorType-00332)

复制整个缓冲区也会导致类似的消息,指出我不能一次写入超过 maxUniformBufferRange(65536 字节)的内容。所以我想我会以 65536 字节的批次复制我的矩阵,这有效并且我从验证层中删除了这些消息。尽管如此,上面关于更新描述符集的消息并没有消失。

长话短说:即使有消息,梦儿海绵也能完美显示!因此,所有矩阵必须已正确传输到 GPU(RTX 3080(移动))。我什至尝试 运行 在我的笔记本集成 GPU 上进行渲染,报告的 maxUniformBufferRange 为 4294967295 字节。所以我想知道为什么我的“高端”GPU 不允许我为我的动态统一缓冲区使用比集成 GPU 更多的内存。或者也许为什么它会说它不允许它然后它工作得很好?可能只是验证层报告了错误的事情吗?

无论哪种方式,我仍然是 Vulkan 和计算机图形学的新手,所以也许我以错误的方式解决了这个问题。有没有办法在不使用动态统一缓冲区的情况下以不同的位置、比例和旋转渲染大量对象?

So I was wondering why my "high-end" GPU would not allow me to use more memory for my dynamic uniform buffer than the integrated GPU.

因为 UBO 的大小并不是使您的“'high-end' GPU”成为“高端”的原因。就是着色器核心数之类的。

Vulkan 的限制不是建议。如果你想使用它,你必须注意它们。对于 UBO,其大小的最低要求限制仅为 16KB。因此,如果您的用例自然需要访问比这更多的数据,您需要检查硬件以查看它是否支持足够大的限制或使用只读 SSBO(这是更好的选择,因为它适用于所有硬件).

至于为什么你的案例碰巧“有效”,未定义的行为是未定义的。也许您只访问了数据的可用部分,或者可能发生了其他事情。但无论如何,它不能保证工作,所以它仍然是您代码中的一个错误。