Я создаю основанный на Vulkan рендерер для моей игровой среды.На данный момент я загружаю в меш около 10 000 уникальных треугольников (не проиндексированных - все отдельные), где каждая вершина имеет значение позиции, значение RGB, никаких нормалей и текстурных координат.Это получается как 72 байта на треугольник, т.е.1 * xyz float + 1 * RGB float = 6 операций с плавающей точкой на вершину.6 * 3 вершины = 18 поплавков на треугольник.18 * 4 = 72 байта на треугольник.Данные Vertex хранятся в локальном буфере графического процессора с установленным флагом VK_BUFFER_USAGE_VERTEX_BUFFER_BIT.
В настоящее время я также использую одни и те же шейдеры vert и frag для всех сеток с константами push для вычисляемой ЦП матрицы MVP.
Если я использую значения, кратные 72, как для параметра смещения в vkCmdBindVertexBuffers (), то моя сетка распадается, так как первые треугольники в буфере никогда не рисуются.Я увеличил смещение на 72 кадра за кадром, что привело к исчезновению сетки без ошибок или ошибок.Стандартная проверка LunarG включена без сообщений об ошибках проверки (у меня много ошибок при проверке и регистрации в моем коде).
Кстати, если я не использую кратные 72, я получаю очень интересные рендеры, но не вылетает!Я также получаю частоту кадров 650 кадров в секунду на шестилетнем компьютере, работающем в renderdoc.
Этот код связывает буфер вершин ...
vkCmdBindVertexBuffers, (cmd[swapindex], 0, 1, vertexBuffers, offsets)
Теперь простопотому что это нормально работает на моем ПК, это не значит, что это правильно.Одна вещь, в которой я запутался, это область спецификации Vulkan, касающаяся требований выравнивания памяти, в частности, в VkPhysicalDeviceLimits.
В VkPhysicalDeviceLimits есть несколько: minTexelBufferOffsetAlignment, minUniformBuffer * OffsetAlignmentговорит: Элемент выравнивания удовлетворяет требованиям выравнивания смещения дескриптора буфера, связанным с использованием VkBuffer:
Если включено использование VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT или VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BEGF_LIFE_LIBRING_BLT_HD_HD_WR_T_L_T_C_T_L_S_FL_S_S_F_L_F_S_FL_C_F_C_L_Sиспользование включает VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, выравнивание должно быть целочисленным кратным VkPhysicalDeviceLimits :: minUniformBufferOffsetAlignment.
Если используется использование VK_BUFFER_USOR_STORAGE_STORAGE_STAGE_STAGE_STAGE_STAL_STAL_STAL_STRING_BING_BHE_BIFF_Beffer_BefferЯ создаю буфер вершин в локальной памяти устройства с vkCreateBuffer () с помощью bufferCreateInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT (А VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT).
1025 * Вопрос ... Как я не создание буфера с VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT или VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, означает ли это, что нет требований к выравниванию памяти для параметра смещения, когда я вызываю vkCmdB * 0, я думаю, что это не так?Я хочу сохранить более одного меша в одном выделенном буфере vkCreateBuffer () с установленным флагом VK_BUFFER_USAGE_VERTEX_BUFFER_BIT.Затем я могу смещаться в этот «супер вершинный буфер» для каждой уникальной сетки, которую мне нужно нарисовать, не имея нескольких распределений буфера вершин.Я знаю, что предел для выделения буферов Vertex обычно составляет 4096 (VkPhysicalDeviceLimits :: maxMemoryAllocationCount), но вместо того, чтобы выделять несколько буферов Vertex, я бы предпочел использовать один «супер буфер» для производительности.
Имеет ли это смысл?
ОБНОВЛЕНИЕ: я изменил свой код, чтобы не использовать смещение в vkCmdBindVertexBuffers (), и вместо этого использую параметр firstVertex в vkCmdDraw () в качестве смещения модели сетки, что приводит к немного более высокому и стабильному FPS.