GLSL spirv_instruction Syntax for SPIR-V IDs
The spirv_instruction qualifier enables developers to
invoke specific SPIR-V opcodes directly within GLSL through the
GL_EXT_spirv_intrinsics extension. By binding custom GLSL
function prototypes to core SPIR-V instructions or extended instruction
sets via numerical IDs, developers can emit exact SPIR-V instructions
without writing external assembly or relying on standard compiler
intrinsic mappings.
Prerequisites and Enabling the Extension
To use spirv_instruction, the
GL_EXT_spirv_intrinsics extension must first be declared
and required at the top of the GLSL shader:
#version 450
#extension GL_EXT_spirv_intrinsics : requireCore SPIR-V Instruction Syntax
To invoke a core SPIR-V instruction, prepend the
spirv_instruction attribute directly to a function
declaration, using the id argument assigned to the numeric
opcode defined in the SPIR-V specification.
spirv_instruction(id = <opcode_number>)
<return_type> <function_name>(<parameters>);id: The decimal or hexadecimal numerical opcode corresponding to the SPIR-V instruction (e.g.,12forOpNop,128forOpIAdd).<return_type>: Maps directly to the instruction's Result <id> Type. If the SPIR-V instruction does not return a value (has no Result <id>), the return type must bevoid.<parameters>: Map directly to the instruction's input operands in the exact sequence expected by the SPIR-V specification.
Example: Core Instruction Mapping
The core instruction OpIAdd has the SPIR-V opcode
128. In SPIR-V, it takes a result type, a result ID, and
two operand IDs. In GLSL, it is declared as:
spirv_instruction(id = 128)
int spirv_iadd(int a, int b);When spirv_iadd(x, y) is invoked in code, the compiler
emits an OpIAdd instruction consuming x and
y and producing an integer result.
Extended Instruction Set Syntax
SPIR-V instructions that belong to extended instruction sets (such as
GLSL.std.450 or NonSemantic.DebugPrintf)
require identifying both the instruction set name and the specific
instruction ID within that set. This is done by adding the
set string argument inside
spirv_instruction:
spirv_instruction(set = "<set_name>", id = <instruction_number>)
<return_type> <function_name>(<parameters>);set: A string literal representing the extended instruction set name as imported byOpExtInstImport.id: The integer identifier of the instruction within that specific extended instruction set.
Example: Extended Instruction Mapping
Instruction number 4 in the GLSL.std.450
extended set is Exp (exponential). This instruction is
bound using:
spirv_instruction(set = "GLSL.std.450", id = 4)
float spirv_ext_exp(float x);When invoked, the compiler automatically handles the
OpExtInstImport "GLSL.std.450" header and emits an
OpExtInst targeting instruction ID 4.
Passing Constants and Literals
Certain SPIR-V instructions require literal values or capabilities rather than variable operand IDs. Literals can be defined using standard GLSL constant expressions or specialized constant intrinsic attributes where required:
spirv_instruction(id = 61 /* OpLoad */)
vec4 spirv_load(inout vec4 pointer);The arguments provided to functions decorated with
spirv_instruction correspond positionally to the operands
required by the target SPIR-V opcode.