VK_EXT_shader_replicated_composites.proposal
This document proposes adding support for new SPIR-V instructions to construct composites with a replicated value.
Problem Statement
Several recent or in-development extensions require a way of constructing SPIR-V
composite values whose top-level constituents all have the same value. Doing
so with current SPIR-V requires the desired value to be repeated once for each
constituent of the composite value. This is undesirable from a succinctness
and code size point of view. As a result extensions have been modifying
existing core SPIR-V instructions. For example, SPV_KHR_cooperative_matrix
modifies the behavior of the core OpConstantComposite instruction
for cooperative matrix types. Other extensions in development face the same
issue and will likely adopt a similar solution if SPIR-V does not introduce
standard support for this in time.
These modifications go against some of the key design principles for SPIR-V: that instructions should not behave differently depending on the types they operate on.
Furthermore, there are scenarios in which the number of constituents of a composite is not known at SPIR-V module production time (e.g. an array whose Length is a specialization constant) and providing a value for each of the constituents is not only undesirable in that case but simply impossible.
Lastly, high-level languages often allow the initialization of composite objects from a replicated value. Compilers currently have to duplicate those initialisers when generating SPIR-V modules.
Solution Space
- Do nothing. Some extensions can modify the behavior of core SPIR-V, in a way that is undesirable, or accept the code size issues. Some patterns are not expressible.
- Provide new SPIR-V instructions to create composites with a replicated value. This is the proposed solution.
Proposal
SPIR-V
Add three new instructions to SPIR-V that enable creating composite values from a replicated value:
- OpConstantCompositeReplicateEXT can be used to declare a new composite constant whose constituents all have the same value.
- OpSpecConstantCompositeReplicateEXT can be used to declare a new composite specialization constant whose constituents all have the same value.
- OpCompositeConstructReplicateEXT can be used to construct a new composite object whose constituents all have the same value.
A new ReplicatedCompositesEXT capability enables the three new instructions.
Vulkan API
Add a VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT
structure that comprises
a single shaderReplicatedComposites
feature that specifies whether the ReplicatedCompositesEXT
capability can be used in shader modules:
typedef struct VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT { VkStructureType sType; void* pNext; VkBool32 shaderReplicatedComposites; } VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT;
Examples
Declare a constant vector of 4 integers with the value 42:
%uint = OpTypeInt 32 0 %uint_42 = OpConstant %uint 42 %vector = OpTypeVector %uint 4 %vector_of_42 = OpConstantCompositeReplicateEXT %vector %uint_42
Construct a structure object whose all constituents have the value 1:
%uint = OpTypeInt 32 0 %uint_1 = OpConstant %uint 1 %struct = OpTypeStruct %uint %uint %uint %struct_all_ones = OpCompositeConstructReplicateEXT %struct %uint_1
Declare an array constant whose length is a specicialisation constant and all elements have the value 15:
%uint = OpTypeInt 32 0 %uint_1 = OpConstant %uint 1 %uint_15 = OpConstant %uint 15 %length = OpSpecConstant %uint %uint_1 %array = OpTypeArray %uint %length %array_of_15 = OpSpecConstantCompositeReplicateEXT %array %uint_15
Issues
None.