Получить выравнивание смещения для однородного буфера на данном устройстве

#graphics #shader #vulkan

#графика #шейдер #vulkan

Вопрос:

Есть ли какой-либо способ получить выравнивание в байтах смещения в пределах распределения, требуемого для буфера с использованием VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT на данном VkDevice ?

Если я уже получил такое VkBuffer , то это значение можно извлечь из size поля VkMemoryRequirements структуры, полученной от вызова vkGetBufferMemoryRequirements .

Но если я хочу получить это значение с заданным буфером, нужно ли мне создавать «фиктивный» буфер с размером 1 (указание размера 0 приводит к ошибке проверки, когда уровень проверки включен)?

Комментарии:

1. Вы имели в виду VkMemoryRequirements::alignment вместо VkMemoryRequirements::size ?

2. Кроме того, в последнем абзаце вы имеете в виду «получить это значение без заданного буфера»?

Ответ №1:

Требование выравнивания для UBO — это ограничение устройства : VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment . Причина этого в том, что это относится не только к требованию для смещения, используемого при привязке буфера к выделению памяти, но и к любым смещениям, используемым в буфере для начала данных UBO при использовании этого буфера в качестве дескриптора UBO.

Ответ №2:

Если я правильно понял ваш вопрос, вы ищете выравнивание для memoryOffset параметра vkBindBufferMemory , который будет действителен для любого VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT VkBuffer , который вы создадите позже. По сути, вам нужно наихудшее / наиболее строгое выравнивание, которое вы получите VkMemoryRequirements::alignment для любого такого буфера. Правильно?

Я не думаю, что вы можете напрямую запросить такое выравнивание в наихудшем случае. VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment близко, но является нижней границей требований к выравниванию буфера и памяти, а не верхней границей ([1]):

alignment Элемент удовлетворяет требованиям к выравниванию смещения дескриптора буфера, связанным с VkBuffer использованием:

  • Если usage включено VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT , alignment должно быть целым числом, кратным VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment .

(Это означает, что любой minUniformBufferOffsetAlignment выровненный фрагмент внутри VkBuffer может использоваться для дескриптора однородного буфера. Но базовое смещение VkBuffer может потребоваться выровнять более строго, чем смещения дескрипторов внутри него).

Однако, если вы создаете прокси VkBuffer -сервер и запрашиваете его выравнивание, вам гарантируется, что выравнивание other VkBuffers с тем же использованием и флагами будет иметь те же требования к выравниванию:

  • alignment Элемент идентичен для всех VkBuffer объектов, созданных с одинаковой комбинацией значений для элементов usage и flags в VkBufferCreateInfo структуре, переданной vkCreateBuffer .

Поскольку размер буфера не может повлиять на выравнивание, можно использовать крошечный прокси-буфер, как вы предложили.