在article on Imagination's website中,我读过以下段落:
例如,Vulkan中没有
glUniform*()
个等效入口点;相反,写入GPU内存是将数据传递给着色器的唯一方法。当您调用
glUniform*()
时,OpenGL ES驱动程序通常需要分配驱动程序管理缓冲区并将数据复制到其中,其管理会产生CPU开销。在Vulkan中,您只需映射内存地址并直接写入该内存位置。
它与使用统一缓冲区之间有什么区别吗?它们也是明确分配的,可以携带任意数据。由于Uniform Buffers的大小非常有限,因此Shader Storage Buffers可能是一个更好的类比。
答案 0 :(得分: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);