Ответ 1
Из того, что я понимаю, это не спецификация glUniform*()
: glUniform*()
- это просто пример, используемый автором статьи, чтобы проиллюстрировать, как Vulkan работает в отношении связи между хостом и GPU.
Когда вы вызываете
glUniform*()
, драйвер OpenGL ES обычно должен выделять буфер, управляемый драйверами, и копировать данные на него, управление которыми несет накладные расходы ЦП.
В этом случае, когда пользователь вызывает glUniform*()
с некоторыми данными, эти данные сначала копируются в буфер, принадлежащий реализации OpenGL. Этот буфер, вероятно, закреплен и затем может использоваться драйвером для передачи данных через DMA на устройство. Это два шага:
- Скопировать данные пользователя в буфер драйвера;
- Передача содержимого буфера на GPU через DMA.
В Vulkan вы просто сопоставляете адрес памяти и записываете непосредственно в эту ячейку памяти.
В этом случае промежуточная копия пользовательских данных отсутствует. Вы просите Вулкана отобразить регион в виртуальное адресное пространство хоста, на которое вы прямо пишете. Данные поступают на устройство через DMA полностью прозрачным способом для пользователя.
С точки зрения производительности преимущества очевидны: нулевая копия. Это также означает, что реализация Vulkan может быть проще, поскольку для управления промежуточным буфером не требуется.
Поскольку спецификации еще не выпущены, вот фиктивный пример того, как он может выглядеть:
// Assume Lights is some kind of handle to your buffer/data
float4* lights = vkMap(Lights);
for (int i = 0; i < light_count; ++i) {
// Goes directly to the device
lights[i] = make_light(/* stuff */);
}
vkUnmap(lights);