在Imagination网站上的文章中,我读过以下段落:
例如,
glUniform*()
Vulkan 中没有等效的入口点; 相反,写入GPU内存是将数据传递到着色器的唯一方法.当您调用时
glUniform*()
,OpenGL ES驱动程序通常需要分配驱动程序托管缓冲区并将数据复制到其中,其管理会产生CPU开销.在Vulkan中,您只需映射内存地址并直接写入该内存位置.
它与使用统一缓冲区之间有什么区别吗?它们也是明确分配的,可以携带任意数据.由于Uniform Buffers的大小非常有限,因此Shader Storage Buffers可能是一个更好的类比.
use*_*016 12
根据我的理解,这不是glUniform*()
特定的:glUniform*()
仅仅是本文作者用来说明Vulkan在主机和GPU之间进行通信的方式的一个例子.
当您调用时
glUniform*()
,OpenGL ES驱动程序通常需要分配驱动程序托管缓冲区并将数据复制到其中,其管理会产生CPU开销.
在这种情况下,当用户glUniform*()
使用某些数据调用时,该数据首先被复制到OpenGL实现拥有的缓冲区中.此缓冲区可能已固定,然后驱动程序可以使用该缓冲区通过DMA将数据传输到设备.这是两个步骤:
在Vulkan中,您只需映射内存地址并直接写入该内存位置.
在这种情况下,没有用户数据的中间副本.您要求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);
Run Code Online (Sandbox Code Playgroud)