UBOs / SSBO如何与Vulkan的着色器内存绑定不同?

时间:2015-03-03 15:03:52

标签: opengl vulkan

article on Imagination's website中,我读过以下段落:

  

例如,Vulkan中没有glUniform*()个等效入口点;相反,写入GPU内存是将数据传递给着色器的唯一方法。

     

当您调用glUniform*()时,OpenGL ES驱动程序通常需要分配驱动程序管理缓冲区并将数据复制到其中,其管理会产生CPU开销。在Vulkan中,您只需映射内存地址并直接写入该内存位置。

它与使用统一缓冲区之间有什么区别吗?它们也是明确分配的,可以携带任意数据。由于Uniform Buffers的大小非常有限,因此Shader Storage Buffers可能是一个更好的类比。

1 个答案:

答案 0 :(得分:12)

据我所知,这不是glUniform*()具体的:glUniform*()仅仅是本文作者用来说明Vulkan在主机和GPU之间通信方式的工作方式的一个例子

  

当您调用glUniform*()时,OpenGL ES驱动程序通常需要分配驱动程序托管缓冲区并将数据复制到其中,其管理会产生CPU开销。

在这种情况下,当用户使用某些数据调用glUniform*()时,该数据首先会被复制到OpenGL实现所拥有的缓冲区中。此缓冲区可能已固定,然后驱动程序可以使用该缓冲区通过DMA将数据传输到设备。这是两个步骤:

  1. 将用户数据复制到驱动程序缓冲区;
  2. 通过DMA将缓冲区内容传输到GPU。
  3.   

    在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);