Vulkan Specification(Vulkan规范):第十四章 14.1 着色器输入输出接口

14. 着色器接口

当创建了一个管线,在对应的 Vk*PipelineCreateInfo数据结构中指定的着色器集合被隐式的链接到一系列不同的接口。

接口定义使用下列SPIR-V 修饰符:

  • DescriptorSet 和 Binding

  • LocationComponent, and Index

  • FlatNoPerspectiveCentroid, and Sample

  • Block and BufferBlock

  • InputAttachmentIndex

  • OffsetArrayStride, and MatrixStride

  • BuiltIn

本规范文档描述了Vulkan 正确的使用这些修饰符。

14.1. 着色器输入输出接口

当一个管线内有多个阶段时,一个阶段的输出和下一个阶段的输入形成了一个接口。 当这个接口涉及到着色器时,着色器输出和下一个阶段的输入相匹配,着色器输入和上一个阶段的输出相匹配。

有两类变量可以在着色器阶段间匹配:内置变量,用户自定义变量。 每一类都有不同的匹配条件。通常,当不同阶段之间的是非着色器阶段,用户自定义的变量基本上是内置变量,在着色器 阶段之间形成接口。

形成输入、输出 接口 的变量被当作 OpEntryPoint 指令的操作对象, 在SPIR-V模块中各以Input 或 Output 存储描述符所修饰。

一个着色器阶段的Output 变量在着色器写入它们或者使用Initializer来声明操作对象之前,它们的值是未知的。

14.1.1. 内置的接口Block

着色器内置 变量须满足以下定义 内置接口block 要求:

  • 被显式的声明(并没有隐式的内置变量)

  • 被 BuiltIn 修饰,

  • 形成如Built-in Variables 一节所描述的变量类型

  • 在顶层成员都是内置类型的block中被声明。

如果在这样的block中被声明了,内置变量只参与接口匹配。 它们不能有 Location 或 Component修饰符。 在每一个着色器接口内,不能有多个内置接口block。

14.1.2. 用户自定义变量接口

被以Input 或 Output 存储修饰符列举的OpEntryPoint 变量形成了 用户自定义变量接口 。 这些变量必须以Location 修饰符指定,也可以被 Component 修饰符指定。

14.1.3. 接口匹配

一个用户自定义输出变量被认为与下一个阶段的输入变量匹配,若两个变量被相同Location 和 Component 描述符修饰,并类型匹配,除了interpolation decorations 没有要求被匹配。 为了做到接口匹配,没有以Component修饰的变量被认为有以 值为0的Component 来修饰。

若数据结构成员在类型、修饰符、数量、声明顺序上是匹配的,变量或者被声明为数据结构的块成员被认为是类型匹配的, 若声明中元素类型与个数相同,则变量或者声明为数组的块成员被认为是匹配的。

细分控制着色器逐顶点输出变量与块,细分控制、细分求值、几何着色器的逐顶点输入变量与块要求必须被声明为数组,其每一个元素表示输入或者输出值是一个顶点或者多顶点的图元。 为了接口匹配,变量或者块最外层的数组维度被忽略了。

在两个非片元着色器阶段的接口,内置的接口block 必须严格匹配,如上所述。 在涉及到片元着色器输入的接口,内置的输出变量的出现或者缺失并不影响接口匹配。

absence of any built-in output does not affect the interface matching.

在两个着色器阶段接口之间,用户自定义的接口必须准确匹配,如上所述。

对于着色器阶段的任何输入值,只要在前一个阶段写入到匹配的输出中,这个输入值就是良好定义的,如上所述。

另外,标量和向量输入,如果对应输入符合一下条件,那么它们就是良好定义的:

  • 输入与输出变量在修饰符上准确匹配。

  • 输出是一个vector,其元素类型是基础类型,且和输入便俩个的成员个数相同,且

  • 输入与输出变量的共同的成员类型 是32-bit 的整型或者浮点型(64-bit元素类型被排除在外)。

在此种情形下,输入变量的元素将会从输出的第一个元素中获取,输出中 另外的元素将会被忽略。

14.1.4. Location 指配

本节描述一个给定的类型会消耗多少locations。 如前所述,几何着色器输入、细分控制着色器输入与输出、细分求值的输入,如其他着色器的输入输出相比,都带有一些额外的数组信息。 在计算输出数组类型消耗多少个location之前,输出中数组中数组信息已经被抹除。

Location 值指定了一个接口槽,其由一个32位的四分量数组组成,在不同的阶段中传送。 Component 指定了在这些数组中分量。 着色器接口只支持位宽32或者64bit的类型。

输入、输出中如下类型消耗一个接口 location:

  • 32-bit 标量与向量类型,与

  • 64-bit 标量和2元素向量类型。

64-bit 3- 和 4- 成员向量消耗两个连续location。

若一个输入输出声明是大小为 n 的数组,且每个元素占 m 个location,它将被赋予 m × n 个连续的location,从指定的location开始。

若一个输入输出声明是一个 n × m 的 32- 或 64-bit 矩阵,它将被赋予指定的location起始的多个location。 每个矩阵所分配的location个数 和 一个 n-个数组元素且元素为_m_个成员的数组所消耗的location个数一样。

Input or Output 的数据结构类型的布局依赖于它是否是一个Block(即,是否有Block 修饰符)。

若它不是Block,那么数据结构类型必须有一个Location 修饰符。 它的成员将依它们被声明的顺序被赋予连续的location,第一个成员被赋予该数据类型所指定的location。 它的成员,和它们的嵌套类型,不能有Location描述符。

若数据结构是一个Block,但是没有Location描述符,那么它的每个成语必须有一个 Location 描述符。 若它是一个Block且带有一个Location 描述符,那么它的成员依声明顺序被赋予连续的location,从第一个成员开始, 第一个成员被赋予该Block所指定的location。 每个带有自己的Location的成员都被赋予该location,每个剩余的成员都️依它们声明顺序被立即赋予location。

一个块、数据结构成员消耗的location由应用上述的规则进行深度优先遍历实例化的成员所决定,如同数据结构或块的成员被声明为一个同类型的输入、输出变量。

Any two inputs listed as operands on the same OpEntryPoint must not be assigned the same location, either explicitly or implicitly. Any two outputs listed as operands on the same OpEntryPoint must not be assigned the same location, either explicitly or implicitly.

一个着色器可用的输入与输出location数量是有限制的,取决于着色器阶段,如Shader Input and Output Locations所述。

Table 11. Shader Input and Output Locations
Shader InterfaceLocations Available

vertex input

maxVertexInputAttributes

vertex output

maxVertexOutputComponents / 4

tessellation control input

maxTessellationControlPerVertexInputComponents / 4

tessellation control output

maxTessellationControlPerVertexOutputComponents / 4

tessellation evaluation input

maxTessellationEvaluationInputComponents / 4

tessellation evaluation output

maxTessellationEvaluationOutputComponents / 4

geometry input

maxGeometryInputComponents / 4

geometry output

maxGeometryOutputComponents / 4

fragment input

maxFragmentInputComponents / 4

fragment output

maxFragmentOutputAttachments

14.1.5. 成员赋值

Component 修饰符允许 Location 更精细的被指定为标量和向量,精细到location内每个独立分量的消耗。 一个location内的分量分别是 are 0, 1, 2, 和 3. 从分量N开始的一个变量或块成员,将消耗分量N, N+1, N+2, …​,up through its size. 对于单精度类型,若此分量序列大于3,那么它就是无效的。 一个标量64位将消耗此序列中两个分量,一个 2-分量的64位数组类型将消耗一个location内可用的四个分量。 一个 3-分量或4-分量的的64位数组类型不能指定Component 修饰符。 一个 3-分量64-位数组类型将消耗第一个location所有四个分量,且消耗第二个location的分量0和1。 这导致分量2和3对于其他的分量限定的声明可用。

一个标量或者两个分量64位数据类型不能指定 Component描述1或者3. 一个Component 声明不能对不是标量或者数组类型 Component 修饰符只能能用于标量或数组。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值