Difference between revisions of "SPIR-V"

From OpenGL Wiki
Jump to navigation Jump to search
(stub page for SPIR-V.)
 
(Sketch of the page.)
Line 1: Line 1:
 +
{{infobox feature
 +
| core = 4.6
 +
| core_extension = {{extref|spirv_extensions}}
 +
| arb_extension = {{extref|gl_spirv}}
 +
}}
 +
 
The '''Standard, Portable Intermediate Representation - V''' ('''SPIR-V''') is an intermediate language for defining shaders. It is intended to be a compiler target from a number of different languages, which allows users the freedom to write shader languages however they want, while allowing implementations to not have to deal with the parsing of more complex languages like [[GLSL]].
 
The '''Standard, Portable Intermediate Representation - V''' ('''SPIR-V''') is an intermediate language for defining shaders. It is intended to be a compiler target from a number of different languages, which allows users the freedom to write shader languages however they want, while allowing implementations to not have to deal with the parsing of more complex languages like [[GLSL]].
 +
 +
The [https://www.khronos.org/registry/spir-v/ SPIR-V registry] contains the current SPIR-V specification, along with its extensions.
  
 
{{stub}}
 
{{stub}}
 +
 +
== Mapping to GLSL ==
 +
 +
SPIR-V defines many concepts that directly match equivalents in GLSL. And the OpenGL specification still considers GLSL to be the primary OpenGL shading language. So SPIR-V concepts map to GLSL concepts. The mapping in most cases is obvious, so we will discuss the non-obvious cases here.
 +
 +
=== Interface matching ===
 +
 +
Input/output interface matching for user-defined variables in SPIR-V works by matching explicit {{code|Location}}s. As such, all variables that are used for input/output interfaces must have a location assigned. Even members of blocks (via structs) must have locations assigned.
 +
 +
An output variable for a particular {{code|Location}} and {{code|Component}} must have a corresponding input variable with the same {{code|Location}} and {{code|Component}} values.
 +
 +
If the type of an output variable is a built-in scalar or vector type, then the type of the corresponding input does not have to match exactly. The output must have the same basic type as the input, and it must provide at least as many components as the input receives.
 +
 +
If the type of the output is a struct, then the input struct must match in the types, numbers, and declaration order of their members. Output arrays match input arrays if they have the same number of array elements and the same type.
 +
 +
Decorations must match between corresponding variables, except for interpolation decorations.
 +
 +
For built-in interface variables, things are a bit more complex. In SPIR-V, you can only have one built-in input block and one built-in output block. Each such block must have all of its members decorated with {{code|BuiltIn}}, and the block cannot have any members decorated with {{code|Location}}. Lastly, the top-level members of the block must be built-in types.
 +
 +
Interface matching for built-in blocks requires an exact match, except for the fragment shader input block. That one (which contains all of the [[Fragment Shader#System inputs|built-in variables]]) does not need to match the previous [[Vertex Processing]] stage's built-in variables. But the built-in blocks between vertex processing stages do need to match exactly.
 +
 +
=== Transform feedback ===
 +
 +
Any shader stage entry-point that will output feedback information must explicitly use the {{code|Xfb}} execution mode.
 +
 +
=== Shader subroutines ===
 +
 +
SPIR-V does not support subroutines at all, so you may not use them.
 +
 +
== SPIR-V extensions ==
 +
 +
SPIR-V is extensible. And working with all of OpenGL's features requires some SPIR-V extensions.
 +
 +
== Shader compilation ==
 +
 +
SPIR-V has the concept of specialization constants. These are values provided after a module is loaded but before it is linked. They are considered constant expressions in most cases, and they allow you
 +
 +
To support this in OpenGL, a shader object populated with a SPIR-V module can be specialized with constants. This function ''must'' be called before linking with a SPIR-V shader object, even if your shader does not use specialization constants.

Revision as of 02:37, 11 September 2017

SPIR-V
Core in version 4.6
Core since version 4.6
Core ARB extension ARB_spirv_extensions
ARB extension ARB_gl_spirv

The Standard, Portable Intermediate Representation - V (SPIR-V) is an intermediate language for defining shaders. It is intended to be a compiler target from a number of different languages, which allows users the freedom to write shader languages however they want, while allowing implementations to not have to deal with the parsing of more complex languages like GLSL.

The SPIR-V registry contains the current SPIR-V specification, along with its extensions.

Mapping to GLSL

SPIR-V defines many concepts that directly match equivalents in GLSL. And the OpenGL specification still considers GLSL to be the primary OpenGL shading language. So SPIR-V concepts map to GLSL concepts. The mapping in most cases is obvious, so we will discuss the non-obvious cases here.

Interface matching

Input/output interface matching for user-defined variables in SPIR-V works by matching explicit Locations. As such, all variables that are used for input/output interfaces must have a location assigned. Even members of blocks (via structs) must have locations assigned.

An output variable for a particular Location and Component must have a corresponding input variable with the same Location and Component values.

If the type of an output variable is a built-in scalar or vector type, then the type of the corresponding input does not have to match exactly. The output must have the same basic type as the input, and it must provide at least as many components as the input receives.

If the type of the output is a struct, then the input struct must match in the types, numbers, and declaration order of their members. Output arrays match input arrays if they have the same number of array elements and the same type.

Decorations must match between corresponding variables, except for interpolation decorations.

For built-in interface variables, things are a bit more complex. In SPIR-V, you can only have one built-in input block and one built-in output block. Each such block must have all of its members decorated with BuiltIn, and the block cannot have any members decorated with Location. Lastly, the top-level members of the block must be built-in types.

Interface matching for built-in blocks requires an exact match, except for the fragment shader input block. That one (which contains all of the built-in variables) does not need to match the previous Vertex Processing stage's built-in variables. But the built-in blocks between vertex processing stages do need to match exactly.

Transform feedback

Any shader stage entry-point that will output feedback information must explicitly use the Xfb execution mode.

Shader subroutines

SPIR-V does not support subroutines at all, so you may not use them.

SPIR-V extensions

SPIR-V is extensible. And working with all of OpenGL's features requires some SPIR-V extensions.

Shader compilation

SPIR-V has the concept of specialization constants. These are values provided after a module is loaded but before it is linked. They are considered constant expressions in most cases, and they allow you

To support this in OpenGL, a shader object populated with a SPIR-V module can be specialized with constants. This function must be called before linking with a SPIR-V shader object, even if your shader does not use specialization constants.