Я пытаюсь понять концептуальную разницу между унифицированными буферами и константами push. Из того, что я могу почерпнуть, прочитав спецификацию, основные отличия:
- Однородные буферы могут быть намного больше, чем константы push.
- UBO используют std140, ПК используют std430.
- UBO могут быть обновлены в любое время с помощью vkCmdUpdateBuffer (или сопоставления хоста) и сохраняют свои значения, в противном случае ПК необходимо повторно выдвигать для каждого прохода рендеринга. (Что меня удивило - основываясь на названии. Я думал, что буквально буду обновлять константы в конвейере на месте, и эти изменения сохранятся)
В моем сценарии у меня есть данные размером ~ 200 байтов, которые, как я ожидаю, будут в основном постоянными . То есть я буду менять их очень редко. Было бы лучше (при условии, что размер разрешает) использовать константы push, даже если мне нужно повторно отправлять их в каждый буфер команд? Или лучше использовать 200-байтовый UBO и редко обновлять его с помощью vkCmdUpdatebuffer?
Также. что если у меня есть, например, то, float random_seed
что я буду обновлять каждый раз при запуске шейдера? Предполагая, что у меня уже есть UBO, было бы лучше объединить это с UBO, даже если остальная часть UBO постоянна, или я бы получил выгоду от использования констант push для конкретно этой переменной, поэтому я могу избежать необходимости vkCmdUpdateBuffer перед каждым проходом рендеринга?
Ответы:
Из спецификации: «vkCmdUpdateBuffer разрешен только вне прохода рендеринга». Так что «в любое время» это не так.
Даже если это было разрешено внутри прохода рендеринга, это все равно операция передачи. Это означает, что вам нужно синхронизировать передачу памяти с командами, которые ее используют. Что замедляет производительность.
Для общей вещи Push Constant против Uniform, используйте свое суждение. Под «суждением» я имею в виду просто посмотреть, как они работают. Push-константы позволяют вам изменять их данные в любое время, не выполняя тяжеловесных процессов, таких как операции с памятью, синхронизация или изменение состояния дескриптора. Очевидно, они предназначены для часто меняющихся данных. Как часто это «часто»? Ну, это решение суда.
В противном случае профилируйте разницу в производительности.
источник
Если данные изменяются нечасто, вы можете использовать константы специализации . Они устанавливаются при создании конвейера, и для изменения значений необходимо создать новый конвейер. Для нечастого события, такого как изменение размера окна, это может быть приемлемой стоимостью.
Это идеальный вариант использования Push Constants. Вы можете сохранить все остальные данные в UBO (или в константах специализации) и изменить это значение с помощью
VkCmdPushConstants
.источник