Appendix A: Vulkan Environment for SPIRV
Shaders for Vulkan are defined by the Khronos SPIRV Specification as well as the Khronos SPIRV Extended Instructions for GLSL Specification. This appendix defines additional SPIRV requirements applying to Vulkan shaders.
Versions and Formats
A Vulkan 1.1 implementation must support the 1.0, 1.1, 1.2, and 1.3 versions of SPIRV and the 1.0 version of the SPIRV Extended Instructions for GLSL.
A SPIRV module passed into vkCreateShaderModule is interpreted as a series of 32bit words in host endianness, with literal strings packed as described in section 2.2 of the SPIRV Specification. The first few words of the SPIRV module must be a magic number and a SPIRV version number, as described in section 2.3 of the SPIRV Specification.
Capabilities
The table below lists the set of SPIRV
capabilities that may be supported in Vulkan implementations.
The application must not use any of these capabilities in SPIRV passed to
vkCreateShaderModule unless one of the following conditions is met for
the VkDevice specified in the device
parameter of
vkCreateShaderModule:

The corresponding field in the table is blank.

Any corresponding Vulkan feature is enabled.

Any corresponding Vulkan extension is enabled.

Any corresponding Vulkan property is supported.

The corresponding core version is supported (as returned by VkPhysicalDeviceProperties::
apiVersion
).
The application must not pass a SPIRV module containing any of the following to vkCreateShaderModule:

any
OpCapability
not listed above, 
an unsupported capability, or

a capability which corresponds to a Vulkan feature or extension which has not been enabled.
SPIRV Extensions
The following table lists SPIRV extensions
that implementations may support.
The application must not pass a SPIRV module to vkCreateShaderModule
that uses the following SPIRV extensions unless one of the following
conditions is met for the VkDevice specified in the device
parameter of vkCreateShaderModule:

Any corresponding Vulkan extension is enabled.

The corresponding core version is supported (as returned by VkPhysicalDeviceProperties::
apiVersion
).
SPIRV OpExtension Vulkan extension or core version 






Validation Rules within a Module
A SPIRV module passed to vkCreateShaderModule must conform to the following rules:
Standalone SPIRV Validation
The following rules can be validated with only the SPIRV module itself. They do not depend on knowledge of the implementation and its capabilities or knowledge of runtime information, such as enabled features.
Runtime SPIRV Validation
The following rules must be validated at runtime. These rules depend on knowledge of the implementation and its capabilities and knowledge of runtime information, such as enabled features.

The converted bit width, signedness, and numeric type of the
Image
Format
operand of anOpTypeImage
must match theSampled
Type
, as defined in Image Format and Type Matching. 
If shaderStorageImageWriteWithoutFormat is not enabled and an
OpTypeImage
has “Image Format” operand ofUnknown
, any variables created with the given type must be decorated withNonWritable
. 
If shaderStorageImageReadWithoutFormat is not enabled and an
OpTypeImage
has “Image Format” operand ofUnknown
, any variables created with the given type must be decorated withNonReadable
. 
Any
BuiltIn
decoration that corresponds only to Vulkan features or extensions that have not been enabled must not be used. 
The
Location
decoration value must be less than the value for the matchingExecution
Model
defined in Shader Input and Output Locations 
Result
Type
for Non Uniform Group Operations must be limited to 32bit floatingpoint, 32bit integer, boolean, or vectors of these types.
If the
Float64
capability is enabled, 64bit floatingpoint and vector of 64bit floatingpoint types are also permitted.


shaderBufferFloat32Atomics or shaderBufferFloat32AtomicAdd or shaderBufferFloat64Atomics or shaderBufferFloat64AtomicAdd must be enabled for floatingpoint atomic operations to be supported on a Pointer with a Storage Class of StorageBuffer.

DescriptorSet
andBinding
decorations must obey the constraints on storage class, type, and descriptor type described in DescriptorSet and Binding Assignment 
Atomic instructions must declare a scalar 32bit integer type, or a scalar 64bit integer type if the
Int64Atomics
capability is enabled, for the value pointed to by Pointer. 
If fragmentStoresAndAtomics is not enabled, then all storage image, storage texel buffer, and storage buffer variables in the fragment stage must be decorated with the
NonWritable
decoration. 
If vertexPipelineStoresAndAtomics is not enabled, then all storage image, storage texel buffer, and storage buffer variables in the vertex, tessellation, and geometry stages must be decorated with the
NonWritable
decoration. 
If subgroupQuadOperationsInAllStages is
VK_FALSE
, then quad subgroup operations must not be used except for in fragment and compute stages. 
Group operations with subgroup scope must not be used if the shader stage is not in subgroupSupportedStages.

The first element of the
Offset
operand ofInterpolateAtOffset
must be greater than or equal to:
frag_{width} ×
minInterpolationOffset
where frag_{width} is the width of the current fragment in pixels.


The first element of the
Offset
operand ofInterpolateAtOffset
must be less than or equal to:
frag_{width} × (
maxInterpolationOffset
+ ULP )  ULPwhere frag_{width} is the width of the current fragment in pixels and ULP = 1 / 2^{subPixelInterpolationOffsetBits}.


The second element of the
Offset
operand ofInterpolateAtOffset
must be greater than or equal to:
frag_{height} ×
minInterpolationOffset
where frag_{height} is the height of the current fragment in pixels.


The second element of the
Offset
operand ofInterpolateAtOffset
must be less than or equal to:
frag_{height} × (
maxInterpolationOffset
+ ULP )  ULPwhere frag_{height} is the height of the current fragment in pixels and ULP = 1 / 2^{subPixelInterpolationOffsetBits}.


The
x
size inLocalSize
must be less than or equal toVkPhysicalDeviceLimits
::maxComputeWorkGroupSize
[0] 
The
y
size inLocalSize
must be less than or equal toVkPhysicalDeviceLimits
::maxComputeWorkGroupSize
[1] 
The
z
size inLocalSize
must be less than or equal toVkPhysicalDeviceLimits
::maxComputeWorkGroupSize
[2] 
The product of
x
size,y
size, andz
size inLocalSize
must be less than or equal toVkPhysicalDeviceLimits
::maxComputeWorkGroupInvocations

Any
OpVariable
with Workgroup as its Storage Class must not have anInitializer
operand 
If an
OpImage*Gather
operation has an image operand ofOffset
,ConstOffset
, orConstOffsets
the offset value must be greater than or equal to minTexelGatherOffset 
If an
OpImage*Gather
operation has an image operand ofOffset
,ConstOffset
, orConstOffsets
the offset value must be less than or equal to maxTexelGatherOffset
Precision and Operation of SPIRV Instructions
The following rules apply to half, single, and doubleprecision floating point instructions:

Positive and negative infinities and positive and negative zeros are generated as dictated by IEEE 754, but subject to the precisions allowed in the following table.

Dividing a nonzero by a zero results in the appropriately signed IEEE 754 infinity.

Signaling NaNs are not required to be generated and exceptions are never raised. Signaling NaN may be converted to quiet NaNs values by any floating point instruction.

By default, the implementation may perform optimizations on half, single, or doubleprecision floatingpoint instructions that ignore sign of a zero, or assume that arguments and results are not NaNs or infinities.

The following instructions must not flush denormalized values:
OpConstant
,OpConstantComposite
,OpSpecConstant
,OpSpecConstantComposite
,OpLoad
,OpStore
,OpBitcast
,OpPhi
,OpSelect
,OpFunctionCall
,OpReturnValue
,OpVectorExtractDynamic
,OpVectorInsertDynamic
,OpVectorShuffle
,OpCompositeConstruct
,OpCompositeExtract
,OpCompositeInsert
,OpCopyMemory
,OpCopyObject
. 
Any denormalized value input into a shader or potentially generated by any instruction in a shader (except those listed above) may be flushed to 0.

The rounding mode cannot be set, and results will be correctly rounded, as described below.

NaNs may not be generated. Instructions that operate on a NaN may not result in a NaN.
The precision of doubleprecision instructions is at least that of single precision.
The precision of operations is defined either in terms of rounding, as an error bound in ULP, or as inherited from a formula as follows.
Operations described as “correctly rounded” will return the infinitely precise result, x, rounded so as to be representable in floatingpoint. The rounding mode used is not defined but must obey the following rules. If x is exactly representable then x will be returned. Otherwise, either the floatingpoint value closest to and no less than x or the value closest to and no greater than x will be returned.
Where an error bound of n ULP (units in the last place) is given, for an operation with infinitely precise result x the value returned must be in the range [x  n × ulp(x), x + n × ulp(x)]. The function ulp(x) is defined as follows:

If there exist nonequal floatingpoint numbers a and b such that a ≤ x ≤ b then ulp(x) is the minimum possible distance between such numbers, $ulp(x)=min_{a,b}∣b−a∣$. If such numbers do not exist then ulp(x) is defined to be the difference between the two finite floatingpoint numbers nearest to x.
Where the range of allowed return values includes any value of magnitude larger than that of the largest representable finite floatingpoint number, operations may, additionally, return either an infinity of the appropriate sign or the finite number with the largest magnitude of the appropriate sign. If the infinitely precise result of the operation is not mathematically defined then the value returned is undefined.
Where an operation’s precision is described as being inherited from a formula, the result returned must be at least as accurate as the result of computing an approximation to x using a formula equivalent to the given formula applied to the supplied inputs. Specifically, the formula given may be transformed using the mathematical associativity, commutativity and distributivity of the operators involved to yield an equivalent formula. The SPIRV precision rules, when applied to each such formula and the given input values, define a range of permitted values. If NaN is one of the permitted values then the operation may return any result, otherwise let the largest permitted value in any of the ranges be F_{max} and the smallest be F_{min}. The operation must return a value in the range [x  E, x + E] where $E=max(∣x−F_{min}∣,∣x−F_{max}∣)$.
For single precision (32 bit) instructions, precisions are required to be at least as follows, unless decorated with RelaxedPrecision:
Instruction  Precision 


Correctly rounded. 

Correctly rounded. 

Correctly rounded. 

Correct result. 

Correct result. 

Correct result. 

Correct result. 

Correct result. 

2.5 ULP for y in the range [2^{126}, 2^{126}]. 
conversions between types 
Correctly rounded. 
Instruction  Precision 


Inherited from 

3 + 2 × x ULP. 

3 ULP outside the range [0.5, 2.0]. Absolute error < 2^{21} inside the range [0.5, 2.0]. 

Inherited from 

Inherited from 1.0 / 

2 ULP. 
GLSL.std.450 extended instructions specifically defined in terms of the above instructions inherit the above errors. GLSL.std.450 extended instructions not listed above and not defined in terms of the above have undefined precision.
For the OpSRem
and OpSMod
instructions, if either operand is
negative the result is undefined.
Note
While the 
Image Format and Type Matching
When specifying the Image
Format
as anything other than
Unknown
, the converted bit width, type, and signedness as shown in the
table below, must match the Sampled
Type
.
Note
Formatted accesses are always converted from a shader readable type to the resource’s format or vice versa via Format Conversion for reads and Texel Output Format Conversion for writes. As such, the bit width and format below do not necessarily match 1:1 with what might be expected for some formats. 
For a given Image
Format
, the Sampled
Type
must be the
type described in the Type column of the below table, with its
Literal
Width
set to that in the Bit Width column, and its
Literal
Signedness
to that in the Signedness column (where
applicable).
Image Format  Type  Bit Width  Signedness 


Any 
Any 
Any 


32 
N/A 








































32 
1 

















0 


















Compatibility Between SPIRV Image Formats And Vulkan Formats
SPIRV Image
Format
values are compatible with VkFormat
values as defined below:
SPIRV Image Format  Compatible Vulkan Format 


Any 













































































