为什么很多移动 GPU 支持 OpenGL ES,而不支持 OpenGL?

Why do many mobile GPUs support OpenGL ES, but not OpenGL?

例如,在整个 ARM Mali 系列中,许多 GPU 支持 OpenGL ES 3+、Direct3D 9+(有些支持高达 11/12),有些支持 Vulkan,但 none 支持 OpenGL ,甚至不推荐使用固定管道的更新版本的 OpenGL。 Adreno 也一样。

是硬件无法支持完整的 GL(如果是,为什么?),还是驱动程序开发人员没有实现它?

因为 OpenGL ES 是专门针对 "embedded" 硬件创建的。

另一方面,创建 OpenGL ES 作为一个单独的标准而不只是 OpenGL 的 "subset"(如果你愿意,今天我们称它为 "profile")的想法是一个非常、非常、非常、非常、非常、非常、非常、非常糟糕的主意。

您在这里面临的主要含义是,为了在 OpenGL ES 之外实现 OpenGL 支持,供应商需要开发另一个相似但略有不同的 GL图书馆。这意味着额外的开发工作、测试和认证。因此,对于他们来说,将这项工作推给开发人员并要求他们创建不同的渲染器要容易得多,目标是桌面上的 OpenGL 和嵌入式上的 OpenGL ES。

(幸运的是,如果你有 OpenGL,这个混乱是由 GL_ARB_ESx_compatibility 扩展以某种方式 "simplified" 造成的,它允许你拥有一些 OpenGL ES 数据类型/调用/功能,所以你能够重新使用更多代码。)

除此之外,你是对的——如果硬件支持 Vulkan,那么它将支持 OpenGL 4.5 / DX12。粗略地说,每一行都针对不同的硬件世代:

  • OpenGL 2.1(+ FBO)| OpenGL ES 2 | Direct3D 9
  • OpenGL 3.3 | OpenGL ES 3.0/3.1 | Direct3D 10
  • OpenGL 4 | OpenGL ES 3.2 | Direct3D 11

再加上一行 "OpenGL 4.5 | Vulkan | Direct3D 12".

(是的,OpenGL ES 版本号甚至没有意义并且与 OpenGL 版本号不匹配,我假设这样供应商就不会因为必须跳转主要版本而将它们视为 "incremental" 发生变化,尽管 ES 3.2 比 3.0 需要更多的硅)

在实践中,细节决定成败,所以您已经 f.i。曲面细分在 OpenGL ES 3.2 但在 OpenGL 4.0 中,但计算着色器已经在 OpenGL ES 3.1 中,但在 OpenGL 中引入了稍后 - 4.3 - 以及其他级别的这种疯狂。

在 Desktop OpenGL 放弃 GL 3.1 的固定功能废话之前,IHV 实现它是不合理的。甚至在这之后,还有一个更大的问题:他们无法处理它。

例如,GL 3.1 需要支持统一缓冲区对象。那是在 2009 年初,直到 2014 年的 ES 3.0 之前,ES 的任何版本都没有提供这样的东西;那时,桌面版 GL 是 4.5 版。

您必须了解的是,移动和桌面硬件的发展速度和时间各不相同。 OpenGL 的版本旨在展示那个时代桌面 GPU 上可用的硬件功能。同样,OpenGL ES 版本展示了那个时代移动硬件可以做什么的一些常见子集。 ES 2.0 的长期统治主要是因为对于主要硬件提供商实际支持的内容缺乏共识。

因此,每个 API 都旨在在一组特定的硬件上实现,因此无视该重点领域之外的硬件需求。直到最近,任何移动 GPU 都可以支持桌面 GL 版本的 所有 功能。即便如此,它们仍然以截然不同的方式进化。

例如,GL 3.2 需要支持几何着色器。那是在 2009 年。直到 2015 年 ES 3.2 发布,OpenGL ES 才发现该功能成为 要求。不仅如此,曲面细分着色器(以及更多功能)成为 ES 的核心3.2,在桌面 GL 中为 4.0。

相比之下,ES 3.1 需要计算着色器和图像 load/store 功能。这些仅分别出现在 4.3 和 4.2 的桌面 GL 中。

这意味着如果仅限于 ES 3.1 功能的移动硬件想要通过桌面 GL 公开他们的硬件......他们怎么能做到呢?他们不能使用任何桌面 GL 版本 3.2 或更高版本,因为那些需要 GS 而他们的 GPU 没有这些。但是他们的 GPU 可以处理计算着色器和图像 load/store,这只是更高 GL 版本的核心。

它们将仅限于桌面 GL 3.1 + 扩展。

这两个 API 分道扬镳,以满足其特定平台的需求。他们独立的硬件发展路线最近才开始汇聚成一个合理的公共子集。

这就是为什么现在我们发现两个 API 都被 替换了 (并且由 API 设计,可以运行 通过使用功能在两组硬件上)为什么要花精力在很快就会变得无关紧要的事情上?