本栏目我们将介绍OpenCL与OpenGL的交互操作。将先后描述OpenCL与OpenGL共享上下文,OpenCL存储器对象与缓存对象、纹理对象以及渲染缓存对象的共享,OpenGL事件对象与OpenCL事件共享。
OpenCL与OpenGL的互操作能给我们带来什么?尽管OpenGL 4.3版本以及OpenGL ES 3.1版本均引入了计算着色器(compute shader)用于做通用计算,但是一方面OpenGL中的计算着色器所提供的通用计算能力仍然十分有限,另外,现在还有不少系统尚无法支持OpenGL 4.3或OpenGL ES 3.1。因此,利用OpenCL来做用于粒子物理碰撞等通用计算还是非常不错的选择。另外,OpenCL与OpenGL的存储器对象共享也避免了两者之间的数据传输,因此不会引入太多的额外性能损耗。
不过,这里也要给OpenCL泼点冷水。如果各位读者仅仅是对纹理或者对绘制出来的图形做些简单的图像处理操作,如一些滤镜、高斯模糊等操作,那么直接用片段着色器(fragment shader)的效率往往会比借助OpenCL高。因为片段着色器阶段过后就能立即做图形渲染流水线最后阶段的后处理,然后就把最终渲好的图输出到显示设备上了。而OpenCL内核程序的执行还需要另外开辟一道计算流水线,会引入一些额外的开销。除此之外, OpenCL内核程序也缺乏对矩阵类型的支持,包括原生对向量与矩阵乘法、矩阵之间的乘法计算的支持。相比于OpenCL内核程序,专用于图形渲染流水线的着色器往往能生成更优化的目标代码。因此,我们所采取的方针是:如果当前OpenGL环境能支持顶点着色器(vrtex sader)、细分曲面控制着色器(tessellation control shader)、细分曲面计算着色器(tessellation evaluation shader)、几何着色器(geometry shader)以及片段着色器(fragment shader),并且能用以上的某种着色器解决当前问题的,那么我们优先考虑使用OpenGL自带的着色器。倘若当前OpenGL能支持计算着色器,那么我们也优先考虑计算着色器,如果不够用,我们再考虑使用OpenCL做程序加速。
这里再给大家一个提示,当前在大部分嵌入式移动GPU上,其通用计算性能非常弱,使得某些稍复杂的计算利用GPU的效率还不如CPU高。此时,作为开发人员,我们应该先对当前环境做些性能测试,然后再选择使用哪种优化方案,而不是盲目地去使用OpenCL。