-
Notifications
You must be signed in to change notification settings - Fork 722
Inline SPIR‐V
The inline SPIR-V intrinsics, attributes, and types allow developers to make new SPIR-V features available without updating HLSL. When a new extension is added to SPIR-V, the feature could be defined in an HLSL header file, and developers could use the feature without changing the compiler. We provide a quick rundown of the features.
Small examples are provided in the Inline SPIR-V proposal, and in the DXC tests.
- Steven Perron, Google LLC
-
vk::ext_extension(string extension_name)
- An attribute that can be applied to
- functions with the
vk::ext_instruction
attribute, - a shader entry pointer,
- a variable, parameter variable, or member variable variable of type
vk::SpirvType
, or - a template type specialization of
vk::SpirvType
orvk::SpirvOpaqueType
viausing.
- functions with the
- This attribute tells the compiler that if the function, variable, or type is used, then the extension must be added to the SPIR-V module.
- An attribute that can be applied to
-
vk::ext_capability(uint capability)
- An attribute that can be applied in the same places as
vk::ext_extension
. - This attribute tells the compiler that if the function, variable, or type is used, then the capability must be added to the SPIR-V module.
- An attribute that can be applied in the same places as
-
void vk::ext_execution_mode(ExecutionMode mode, …)
- A call to this function will be turned into an
OpExecutionMode
instruction where the entry point will be the entry point currently being processed. The parameters will become the operands to the instruction. - All operands must be literals.
- Note that if the function is not called directly in the entry point it is unclear which entry point it will apply to. When there is a single entry point being compiled, it will apply to that entry point. If using a
lib_6_x
target profile with multiple entry points, it will only be applied to one of them. - Note that DXC never implemented the extra arguments.
- A call to this function will be turned into an
-
void vk::ext_execution_mode_id(uint execution_mode, ...)
- This is the same as
vk:ext_execution_mode
except that it will generate anOpExecutionModeId
instruction instead.
- This is the same as
-
vk::spvexecutionmode(ExecutionMode)
- This is an attribute that can be applied only to entry points.
- It will generate an
OpExecutionMode
instruction that applies to the entry point with the attribute and the given execution mode.
-
vk::ext_instruction(uint opcode, string extended_instruction_set)
- An attribute that applies to a function prototype. There must not be a definition of the function.
- The attribute indicates to the compiler that the definition of the function is a single SPIR-V instruction. If the
extended_instruction_set
is the empty string, then an instruction with the given opcode is generated. Otherwise, anOpExtInst
instruction is generated for the given extended instruction set, andopcode
becomes theinstruction
operand. - The function parameters become the operands to the instruction. By default, operands will be the id of the value provided. If it is a literal, then the id of the
OpConstant
will be used. If it is a variable, the id ofOpLoad
of the variable will be used. Thevk::ext_reference
andvk::ext_literal
attributes can modify this. See below.. - The return type for the instruction will be the return type of the function following the convention for return values used in the compiler.[1]
-
vk::ext_reference
- An attribute that applies to a parameter of a function with the
vk::ext_instruction
attribute. - Parameters of this type must be variables. The operand to the instruction will be the pointer to the variable.
- We do not place any restriction on the storage class of the variable used as the parameter. It is the user's responsibility to ensure the correct storage class is used.
- An attribute that applies to a parameter of a function with the
-
vk::ext_literal
- An attribute that applies to a parameter of a function with the
vk::ext_instruction
attribute. - Parameters of this type must be literal, and the operand to the instruction will be encoded as a literal operand.
- An attribute that applies to a parameter of a function with the
-
vk::ext_result_id<T>
- This is a type that can be used as a parameter or return type in a function with the
vk::ext_instruction
attribute. - It can be used to avoid the implied store of the return value, and the subsequent load of the operand.
- Note: It is discouraged to use this type. In general, the optimizer will be able to remove the stores and loads. Also, the type can be used only in very specific situations, so it does not fit in well with HLSL. For this reason, it may be considered for deprecation in the future.
- This is a type that can be used as a parameter or return type in a function with the
-
vk::SpirvOpaqueType<uint OpCode, typename... Operands>
- A type defined by a SPIR-V instruction with the given opcode.
- The operands to the type are given in order in
Operands
. - If the typename is the type
vk::integral_constant<typename T, T v>
, then the operand will be the id of theOpConstant
with valuev
and typeT
. - If the typename is
vk::Literal<typename T>
, whereT
is avk::integral_constant
, then the operand will be encoded as a literal with the given value instead of anOpConstant
. - Otherwise, the operand will be the id of the given type.
- This will be considered an opaque type, which will have no size or alignment requirements.
- Because the compiler does not know the size and alignment, there are restrictions on where this type can be used. For example, it cannot be used in a StructureBuffer or any other external resource that is required to be fully laid out.
-
vk::SpirvType<uint OpCode, uint size, uint alignment, typename... Operands>
- The same as
vk::SpirvOpaqueType
except that the type will have the given size and alignment requirements.
- The same as
-
vk::ext_storage_class(uint storage_class)
- This attribute applies to a variable declaration. The variable will be placed in the given storage class.
-
vk::ext_builtin_input(uint BuiltinID)
- This attribute applies to file-scope static const variables.
- It indicates that the variable is a builtin input in SPIR-V. It will be placed in the input storage class, and be decorated with the given builtin id.
-
vk::ext_builtin_output(uint BuiltinID)
- This attribute applies to file-scope static variables.
- It indicates that the variable is a builtin output in SPIR-V. It will be placed in the output storage class, and be decorated with the given builtin id.
-
vk::ext_decorate(uint decorationId, … int / float / bool literal)
- An attribute that applies to a function, variable, parameter, member variable, and typedef.
- The object to which it is applied will be decorated with the given decoration using
OpDecorate
with the given decoration id. Other parameters will be added as literal operands.
-
vk::ext_decorate_id(decoration, … int / float / bool literals)
- An attribute that applies to a function, variable, parameter, and typedef.
- The object to which it is applied will be decorated with the given decoration using
OpDecorateId
with the given decoration id. The other parameters will be added using the id of the correspondingOpConstant*
instructions.
-
vk::ext_decorate_string(decoration, … string literals)
- An attribute that applies to a function, variable, parameter, and typedef.
- The object to which it is applied will be decorated with the given decoration using
OpDecorateId
with the given decoration id. The other parameters will be encoded as string literals.
[1]: There is no formal ABI for HLSL to SPIR-V. This means the calling convention is compiler defined. Developers will have to make sure their instruction follows the conventions of the compiler being used. In particular, the return value for a function will not have a specified layout in DXC. If the result of the SPIR-V instruction will produce a struct with a defined layout, then invalid code will be generated by DXC.