glUseProgram()如何在硬件级别工作?

时间:2015-06-21 20:53:05

标签: opengl

  1. 我认为(我不确定),每当我们调用glUseProgram()时,顶点着色器,frag着色器,几何着色器等被加载到GPU中相应类型处理器的程序存储器中(例如,顶点着色器 - >顶点着色处理器) 但我也发现这种“装载”发生的速度令人惊讶。尽管拥有复杂的渲染管道和多个着色器,但游戏通常能够提供非常好的FPS( 1 ),这意味着程序加载可能每秒发生数千次。
    我是否正确地思考这是如何运作的?如果是的话,我真的低估了GPU的功能吗?
  2. (与( 1 )相关的迷你问题)在哪里可以找到有关内部GPU总线带宽与性能(或FPS)之间相关性的更多信息?
  3. 另一个迷你问题)是在客户端还是在设备上编译着色器?
  4. 后编译,是存储在GPU(共享)内存中的着色器程序,还是大到足以容纳许多着色器的处理器缓存?

1 个答案:

答案 0 :(得分:5)

  

加载到GPU中各个类型处理器的程序存储器中

我很确定已编译的着色器保持足够接近"到阴影单元,使装载本身非常有效。指令缓存包含必要的数据,并且很容易用VRAM中的数据重写它们。毕竟,不需要CPU同步,一切都完全在GPU内完成。

这里要注意的一件重要事情是,现代GPU没有相应的类型处理器"了;它们实际上只使用可以运行各种计算的通用着色单元,包括但不限于片段和顶点着色。

  

尽管有一个复杂的渲染管道和多个着色器,游戏通常能够提供非常好的FPS(1),这意味着程序加载可能每秒发生数千次。

是的,现代游戏可以有数千个管道设置来绘制框架。 GPU 快。现代OpenGL使得更多程序更容易使用Separate Shader Objects扩展,这有助于使渲染更加模块化。

  
      
  1. (与(1)相关的迷你问题)在哪里可以找到有关内部GPU总线带宽与性能(或FPS)之间相关性的更多信息?
  2.   

这太过宽泛而无法回答,并且在很大程度上取决于工作量。但是,This is an interesting document可能会对你的问题有所启发,并可能激励你做进一步的研究。

总而言之,glUseProgram本身通常会在现代驱动程序(就性能而言)上做很多...... nothing 。这是因为驱动程序使用一种惰性求值形式,并且只有在确定drawcall将使用它们时才实际提交状态更改。现在,驱动程序在优化不必要的调用,重新排序等方面的效率完全取决于实现。

  
      
  1. 是在客户端还是在设备上编译着色器?
  2.   

它们是在OpenGL的条款下在服务器上编译的,但这并不一定意味着物理设备。通常,它是执行着色器编译的驱动程序的OS驻留部分。

  
      
  1. 后编译,是存储在GPU(共享)内存中的着色器程序,还是大到足以容纳许多着色器的处理器缓存?
  2.   

两者。程序存储在全局存储器中,并且如果可能的话,存储在每个处理器的指令高速缓存中,这是几千字节。这取决于着色器的大小和缓存的大小,但通常应该适合几个。缓存在运行时以LRU方式填充。