简介
本文档仅指定 OpenGL 着色语言 (GLSL) 的 4.60 版本。它要求 __VERSION__ 替换为 460,并且要求 #version 仅接受 460
。如果 #version 声明的数字较小,则接受的语言是着色语言的先前版本,具体支持情况取决于 API 中的版本和上下文类型。有关支持的语言版本的详细信息,请参阅规范性引用。
OpenGL 着色语言的先前版本以及 OpenGL ES 着色语言并非此处指定的版本的严格子集,尤其是在精度、名称隐藏规则和接口变量的处理方面。有关特定于该语言版本的详细信息,请参阅与特定语言版本相对应的规范。
在整个过程中,当生成供 Vulkan API 使用的 SPIR-V 时(请参阅规范性引用),这将被称为面向 Vulkan。
虽然本规范和 OpenGL 规范是 OpenGL 着色语言的规范性依据,但对于 SPIR-V 生成,SPIR-V 规范和 SPIR-V 客户端 API 规范仍然是生成的 SPIR-V 的规范性依据。有关更多详细信息,请参阅规范性引用。
对于 SPIR-V 生成,SPIR-V 客户端 API 指定了用于操作 SPIR-V 着色器的命令。
独立的离线工具链将 GLSL 编译为 SPIR-V 中间语言。SPIR-V 生成不是通过 #extension、#version 或配置文件启用的。相反,GLSL 用于 SPIR-V 是由离线工具链的使用决定的。请参阅此类工具的文档,了解如何请求为其客户端 API 生成 SPIR-V。
必须指示 GLSL → SPIR-V 编译器哪些 SPIR-V Capabilities 在运行时是合法的,并且对于超出这些功能的 GLSL 特性使用给出错误。对于可以通过前端针对 GLSL 源中存在的内置常量进行错误检查的与实现相关的限制也是如此:可以告知前端此类限制,并在超出限制时报告错误。
不受 SPIR-V 功能控制但具有等效 GLSL 对应项(阶段、内置函数、类型、限制等)的 SPIR-V 功能预计仅在支持 GLSL 对应项的 OpenGL 驱动程序上工作。
除非另有指定,否则本规范中所有对OpenGL 规范的引用均指 4.6 版本核心配置文件。
更改
GLSL 4.6 修订版 8 的更改
-
公共 GLSL 问题 #198:澄清逻辑运算符仅对标量进行操作。
-
私有 GLSL 问题 #59:修复 atanh 函数的错误域。
-
私有 GLSL 问题 #66:添加注释,澄清未初始化的 out 参数将被复制,导致函数参数变为未定义。
-
私有 GLSL 问题 #68:澄清对“数组”部分的更改。本节经过重新组织,以便于编辑,并澄清了某些规则。即使未声明,ES 也包含无大小数组的规则,因为它们适用于某些预先声明的用途。
GLSL 4.6 修订版 7 的更改
-
私有 GLSL 问题 #57:澄清 imageLoad 精度(如果适用)仅由图像参数的精度确定。
-
公共 GLSL 问题 #164:澄清 mod 的预期精度。
-
公共 GLSL 问题 #8:澄清何时可以访问计算着色器变量。
-
公共 GLSL 问题 #13:澄清位置别名的位宽要求。
-
公共 GLSL 问题 #161:修复不正确的布局限定符示例。
-
私有 GLSL 问题 #30:澄清结构成员的精度始终在结构类型声明中固定。
-
私有 GLSL 问题 #49:澄清对一元 + 的支持。
-
私有 GLSL 问题 #43:澄清构造函数的精度。
-
私有 GLSL 问题 #53:澄清 接口块上允许哪些限定符。
-
私有 GLSL 问题 #31:删除应用于“in”变量的不正确的“invariant”示例。
-
修复公共 GLSL 问题 #83:只有不透明类型变量才需要在传递给用户定义的函数时保留其内存限定符(例如,readonly)。
-
澄清声明原子计数器时的错误条件。
-
次正规值可能会被 intBitsToFloat() 刷新为 0.0。
-
澄清“precise”不能限定结构定义。
-
私有 Bugzilla #15755:澄清应用程序可见内存中精度限定 接口块成员的存储大小。
GLSL 4.6 修订版 6 的更改
-
合并 GL_KHR_vulkan_glsl 规范。
-
在引言中添加关于驱动程序中 SPIR-V 功能的存在(与 GLSL 功能相关)的注释。
-
澄清触发默认统一块匹配规则的相同位置。请参阅统一变量布局限定符。
GLSL 4.6 修订版 5 的更改
-
私有 GLSL 问题 #34:澄清/合并从 int → uint 的隐式转换规则,使其与显式构造相同。
-
私有 GLSL 问题 #24:澄清 barrier() 本身足以同步对 shared 变量和细分控制输出变量的控制流和内存访问。对于其他内存访问,仍然需要额外的内存屏障。
-
规范性地引用 IEEE-754 来定义浮点格式。
-
私有 GLSL 问题 36:double 类型上的 refract 函数要求 eta 参数具有 double 类型。
-
澄清细分和几何阶段中输入变量的限制。
-
私有 GLSL 问题 15:澄清数组的数组的绑定的顺序。
-
私有 GLSL 问题 14:只有在静态使用时,Uniform 变量才需要在链接时匹配。
-
对于精确计算,控制流和三元运算符(?:)的控制表达式不包括在内。
GLSL 4.6 版本 4 的更改
-
私有 bug 13012:澄清了内置 uniform 变量可能仅在片段着色器阶段可用。
-
私有 bug 13837:三元和序列运算符可以对 void 类型进行操作。
-
澄清了预处理引起的错误必须在编译时返回。
-
澄清了访问变量的任何部分都构成静态使用。
-
私有 GLSL 问题 19:在 switch 末尾的任何标签之后都需要一个语句。
-
私有 GLSL 问题 26:为 SPIR-V 编译时,noise 无效。
-
私有 GLSL 问题 20:返回常数值的 length() 表达式可能不包含副作用。
-
公共 OpenGL-API 问题 7:变量可以同时声明为 readonly 和 writeonly。
-
私有 GLSL 问题 16:在 #line 指令中使用常量表达式是未定义的。
-
更正了 float 图像上 imageAtomicExchange 的返回类型。
-
私有 GLSL 问题 32:删除 length() 方法矛盾:非运行时大小的数组仅支持在显式大小的数组上使用 length()。
-
私有 GLSL 问题 21:澄清了对 interpolateAt 的左值限制。
-
私有 OpenGL-API 问题 53:澄清了位置别名的位宽要求。
-
公共 GLSL 问题 15:gl_in 可以使用未定大小的数组语法重新声明。
-
澄清了深度/模板纹理的 DEPTH_COMPONENT 和 STENCIL_COMPONENT 所需的格式。
-
在 布局限定符部分中,将图像格式添加到布局限定符表中。
GLSL 4.6 版本 3 的更改
-
私有 GLSL 问题 13:修复了 allInvocationsEqual() 的拼写错误。(表中的一个被错误地列为 anyInvocationsEqual(),其他拼写是正确的。)
GLSL 4.50 版本 7 的更改摘要
-
纳入了 GL_ARB_shader_atomic_counter_ops 扩展。
-
纳入了 GL_ARB_shader_draw_parameters 扩展。
-
纳入了 GL_ARB_shader_group_vote 扩展。
-
纳入了 GL_ARB_gl_spirv 扩展。
-
私有 Bug 16070:允许在全局范围内使用额外的分号。
-
私有 GLSL 问题 5:明确指出 “链接失败” 实际上是 “编译时或链接时错误”,对于某些形式的错误。
-
私有 GLSL 问题 7:将 gl_MaxComputeUniformComponents 更改为 1024。
-
私有 OpenGL API 问题 35:要求 SPIR-V 的透明独立 uniform 变量具有位置。
-
私有 GLSL 问题 8:更清楚地说明 interpolateAt() 插值可以是结构成员。
-
私有 GLSL 问题 9:指定 xfb_buffer 如何与块数组交互:捕获缓冲区为每个块数组元素递增。
概述
本文档描述了OpenGL 着色语言,版本 4.60。
用这种语言编写的独立编译单元称为着色器。程序是一组经过编译和链接在一起的着色器,完全创建 API 管道的一个或多个可编程阶段。单个可编程阶段的所有着色器必须在同一个程序中。一组完整的可编程阶段可以放入一个程序中,或者可以将阶段分布在多个程序中。本文档的目的是彻底指定编程语言。 规范性参考文献将指定用于操作程序和着色器并与之通信的 API 入口点。
错误处理
一般来说,编译器会接受格式不正确的程序,因为不可能检测到所有格式不正确的程序。可移植性仅对格式良好的程序有保证,本规范对此进行了描述。鼓励编译器检测格式不正确的程序并发出诊断消息,但不是必须对所有情况都这样做。必须为词法或语法不正确的着色器返回编译时错误。其他错误在编译时或链接时报告,如指示的那样。“死” 代码仍然必须进行错误检查。例如
if (false) // changing false to true cannot uncover additional errors
statement; // statement must be error checked regardless
排版约定
本规范中主要使用斜体、粗体和字体选择来提高可读性。代码片段使用固定宽度字体。嵌入在文本中的标识符使用斜体。嵌入在文本中的关键字使用粗体。运算符通过其名称调用,后跟括号中的粗体符号。文本中的澄清语法片段对文字使用粗体,对非终结符使用斜体。“着色语言语法”中的官方语法对终结符使用全部大写字母,对非终结符使用小写字母。
弃用
OpenGL 着色语言已弃用某些功能。在本规范中,这些功能被明确地称为 “已弃用”。它们仍然存在于此版本的语言中,但目标是在着色语言的未来版本中删除。OpenGL API 具有向前兼容模式,该模式将不允许使用已弃用的功能。如果在不允许使用已弃用功能的模式下编译,则使用它们会导致编译时或链接时错误。有关什么原因导致接受已弃用的语言功能或返回错误的详细信息,请参见 OpenGL 规范。