4

编辑 2有人指出,我真正要问的一个问题是:“规范中规定的向上兼容性(关于核心配置文件)是否具有传递性?” 我确实很乐意得到这个问题的答案。如果它确实是传递的,那么如何解释明显的矛盾呢?

编辑:这不是使用哪些 GLSL 版本以获得最大兼容性的副本

这不是重复的,因为:那个问题是关于一般使用哪些版本的 GLSL。这个问题是关于规范中关于何时支持 GLSL 1.30 的非常具体的矛盾案例。我也更改了标题以澄清。


似乎从 3.1 开始的所有 OpenGL 版本都向后兼容。从规格:

OpenGL 4.2 兼容性和核心配置文件分别向上兼容 OpenGL 4.1 兼容性和核心配置文件

OpenGL 4.1 兼容性和核心配置文件分别向上兼容 OpenGL 4.0 兼容性和核心配置文件

OpenGL 4.0 兼容性和核心配置文件分别向上兼容 OpenGL 3.3 兼容性和核心配置文件

OpenGL 3.3 兼容性和核心配置文件分别向上兼容 OpenGL 3.2 兼容性和核心配置文件

OpenGL 3.2 核心配置文件向上兼容 OpenGL 3.1,但不兼容早期版本

太好了,所以我可以针对 OpenGL 3.1 编写代码,它可以在 OpenGL 4.2 实现上运行。

但 4.2 核心规范也说:

OpenGL 4.2 的核心配置文件也保证支持所有以前版本的 OpenGL 着色语言回到 1.40 版。

3.1规范说:

保证 OpenGL 3.1 实现至少支持 1.30 版的着色语言。

那么,OpenGL 4.2 可能不支持 OpenGL 3.1 支持的 GLSL 1.30,它怎么能声称与 OpenGL 3.1 向上兼容呢?

4

1 回答 1

3

我对发现的规格不一致感到困惑,并试图进行一些研究。我个人的结论是,确实,OpenGL规范在这方面使用了模棱两可/不好的措辞,从OpenGL 3.2+开始就引入了(从OpenGL 4.2 Core引用的片段首先在OpenGL 3.2 Core中引入并且保持不变)。

OpenGL 3.2 要求实现仅支持 GLSL 1.40 (OpenGL 3.1) 和 GLSL 1.50 (OpenGL 3.2),同时指定它与 OpenGL 3.1 兼容,但不删除已弃用的功能。

OpenGL 3.2实现保证支持 OpenGL 着色语言的 1.40 和 1.50 版本。所有对该规范部分的引用均指版本 1.50。
... OpenGL 4.6
的核心配置文件也保证支持所有以前版本 的OpenGL 着色语言回到版本 1.40 ... OpenGL 3.2 核心配置文件向上兼容 OpenGL 3.1,但不兼容早期版本。

同时,OpenGL 3.0 和 3.1 明确将 GLSL 1.10 (OpenGL 2.0) 和 GLSL 1.20 (OpenGL 2.1) 标记为已弃用(并在 OpenGL 3.1 中删除):

保证OpenGL 3.1实现至少支持 1.30 版的着色语言。
...
OpenGL 3.0 中不推荐使用的功能: ... OpenGL 着色语言版本 1.10 和 1.20。这些版本的着色语言依赖于许多已被弃用的 API 功能。

但是规范没有在弃用上下文中提及 GLSL 1.30 (OpenGL 3.0),因此没有明显的理由认为 GLSL 1.30 被弃用(因为专用的 GLSL 1.30 规范本身详细说明了弃用的功能)。

还可以注意到,OpenGL 3.1 不需要支持 GLSL 1.40(尽管它是由本规范引入的)!因此,在没有 GLSL 1.30 支持(OpenGL 3.1 规范强制支持的唯一版本)的情况下,将 OpenGL 3.2 “向上兼容”到 OpenGL 3.1 让我感到困惑。

我猜 OpenGL 规范作者在“向上兼容”部分中隐含地提到了非 GLSL 功能,并设计了专用部分“保证实现......着色语言”阐明对 GLSL 版本的要求,以便后者优于第一个一。

我试图检查手头的 OpenGL 实现,看看它们会告诉 Core Profile 中不同 GLSL 版本(110、120、130、140、150)的内容,记录 GLSL 编译警告并启用调试上下文:

  • 英伟达(456.71)、英特尔Mesa (20.2.6)
    • GLSL 1.10+ -对任何已知的 GLSL 版本一言不发
  • AMD
    • GLSL 1.10/GLSL 1.20 - 着色器编译器生成警告
      WARNING: warning(#271) Explicit version number 120 not supported by GL3 forward compatible context
    • GLSL 1.30+ - 没有警告;
  • 苹果(金属 71.0.7)
    • GLSL 1.10/1.20/1.30 - 生成着色器编译错误
      ERROR: 0:1: '' : version '130' is not supported
    • GLSL 1.40+ - 没问题。

因此, OpenGL 供应商似乎在阅读这部分规范方面没有定论。

NVIDIA 只是不在乎(众所周知,他们的 GLSL -> Cg 翻译器会跳过大部分 GLSL 验证),英特尔也是(但他们的 OpenGL 驱动程序从来都不是很好),以及 Mesa。但这并不违反 OpenGL 规范,因为他们说 OpenGL 实现可能支持除强制性版本之外的任何其他 GLSL 版本。

众所周知, AMD拥有良好的 GLSL 验证器,并且显然他们的工程师阅读了规范的部分内容,即“OpenGL 3.2 Core Profile 应该支持与 OpenGL 3.1 相同的功能,但不推荐使用的功能”。但它是否温和 - 没有编译错误,因为只有着色器编译日志表明不应使用 GLSL 1.20(但 GLSL 1.30 是可以的!)。

众所周知, Apple在遵循 OpenGL 规范时偏执,并且通常会在每次偏离它时产生错误。在这里,我们看到 Apple 工程师阅读了 OpenGL 3.2 规范的另一部分,其中列出了支持的 GLSL 版本为 1.40 和 1.50——因此它不接受 GLSL 1.30。

需要注意的是,大部分厂商都是在实现了OpenGL 3.0和3.1之后才实现了OpenGL 3.2,所以从1.10开始支持所有的GLSL版本对他们来说真的没什么大不了的。

相比之下,Apple 从来没有 OpenGL 3.0/3.1 并且直接实现了 OpenGL 3.2 Core Profile(对实现 Compatible Profiles 没有任何兴趣)。这就是为什么,我猜,他们更喜欢阅读不支持 GLSL 1.30 (OpenGL 3.1) 的规范。

OpenGL 规范中的一般措辞表明支持的 GLSL 版本的范围可能更广,并建议查询GL_SHADING_LANGUAGE_VERSION,但显然,此查询对于检索最小 GLSL 版本或支持版本的完整列表是无用的,并且没有为此目的提供其他 API。因此,一个人可能只“探测”着色器编译器以查看是否支持特定版本(在强制性列表之外)。

另一方面,独立于 OpenGL 的单独 GLSL 版本控制看起来是多余的,因为较新的 GLSL 版本也与早期版本兼容(保存已弃用的功能) - 因此在使用 OpenGL 4.2 时没有太多理由不强制 GLSL 4.20,只要您不仅仅是在尝试验证 GLSL 与旧 OpenGL 版本的兼容性。

实际上,OpenGL 3.2 和它的 GLSL 1.50 看起来像是一个更合理的开发基准,因为我真的不知道支持 OpenGL 3.1 但不支持 OpenGL 3.2 Core Profile 的最新实现。

于 2021-07-07T20:15:13.557 回答