Каково ожидаемое поведение буфера vulkan (vkCreateBuffer) для чтения и записи - PullRequest
0 голосов
/ 11 января 2019

При объединении индексов (VK_INDEX_TYPE_UINT16) и буферов вершин в один объект буфера последняя вершина не отправляется моему вершинному шейдеру при нечетном количестве индексов, вместо этого он получает все нули для вершины, цвета и UV координаты, но при четном числе индексов все работает отлично.

Единственное различие между ними состоит в том, что нечетное число индексов получает немного больший буфер и требует перемещения данных вершин, чтобы они были выровнены на 4 байта для вызова vkMemoryRequirements.

Тогда конечный результат заключается в том, что параметр размера VkBufferCreateInfo меньше фактического размера, необходимого после выравнивания памяти, когда число индексов нечетно. (это на 2 байта меньше)

Если я искусственно добавляю 2 байта в буфер, создаю размер информации, тогда все работает нормально.

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

Фактический размер памяти, которую я прикрепляю к буферу, огромен (256 мегабайт), и я обошел область вокруг всего буфера, затем проверил ее, чтобы убедиться, что какая-то потерянная душа не растоптала мою память.

Откровенно говоря, это ведет себя так, будто драйвер проверяет, не переполнит ли он конец буфера при отправке данных в шейдер, так что шейдеры не могут прочитать общую память, но он получает фактический конец неверный буфер.

Также важно отметить, что это происходит только с драйверами AMD (версия 25.20.1003.5010), драйверы Nvidia совершенно счастливы, позволяя мне перезаписывать / перегружать свои буферы весь день. (серьезно, это была одна ошибка ...)

Кажется, я помню, что где-то читал, что vulkan был в порядке в этой ситуации и автоматически настраивал требования к размеру буфера, чтобы учесть дополнительные байты выравнивания памяти, но я не могу найти это на самом деле где-либо задокументировано.

Так, каково ожидаемое поведение? Должен ли я ожидать, что vulkan действительно будет соблюдать размер буфера, который он сообщает мне через vkGetMemoryRequirements?

Итак, я начал вводить код для этого и понял, что это будут стопки, стопки и стопки кода, поэтому я не собираюсь ничего добавлять, так как хочу пощадить любую бедную душу, которая может захотеть просмотреть несколько сотен строк кода на вулканском языке, необходимых для полной реализации этой проблемы.

Фактический размер памяти, к которой прикреплен буфер, составляет 256 МБ, сам буфер представляет собой ничтожный размер данных 282 байта, выровненный размер 284 байта. Код запрашивает 282-байтовый буфер, vkGetBufferMemoryRequirements возвращает размер 284 байта с 4-байтовым выравниванием, а (под) распределитель памяти выделяет 284-байтовую область для буфера, в котором он находится.

...