## Appendix A: Vulkan Environment for SPIR-V

Shaders for Vulkan are defined by the Khronos SPIR-V Specification as well as the Khronos SPIR-V Extended Instructions for GLSL Specification. This appendix defines additional SPIR-V requirements applying to Vulkan shaders.

### Versions and Formats

A Vulkan 1.0 implementation must support the 1.0 version of SPIR-V and the 1.0 version of the SPIR-V Extended Instructions for GLSL. If the VK_KHR_spirv_1_4 extension is enabled, the implementation must additionally support the 1.4 version of SPIR-V.

A SPIR-V module passed into vkCreateShaderModule is interpreted as a series of 32-bit words in host endianness, with literal strings packed as described in section 2.2 of the SPIR-V Specification. The first few words of the SPIR-V module must be a magic number and a SPIR-V version number, as described in section 2.3 of the SPIR-V Specification.

### Capabilities

The table below lists the set of SPIR-V capabilities that may be supported in Vulkan implementations. The application must not use any of these capabilities in SPIR-V 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.

• The corresponding core version is supported (as returned by VkPhysicalDeviceProperties::apiVersion).

Table 65. List of SPIR-V Capabilities and corresponding Vulkan features, extensions, or core version
SPIR-V OpCapability Vulkan feature, extension, or core version

Matrix

Shader

InputAttachment

Sampled1D

Image1D

SampledBuffer

ImageBuffer

ImageQuery

DerivativeControl

Geometry

geometryShader

Tessellation

tessellationShader

Float64

shaderFloat64

Int64

Int64Atomics

Int16

shaderInt16

TessellationPointSize

shaderTessellationAndGeometryPointSize

GeometryPointSize

shaderTessellationAndGeometryPointSize

ImageGatherExtended

shaderImageGatherExtended

StorageImageMultisample

shaderStorageImageMultisample

UniformBufferArrayDynamicIndexing

shaderUniformBufferArrayDynamicIndexing

SampledImageArrayDynamicIndexing

shaderSampledImageArrayDynamicIndexing

StorageBufferArrayDynamicIndexing

shaderStorageBufferArrayDynamicIndexing

StorageImageArrayDynamicIndexing

shaderStorageImageArrayDynamicIndexing

ClipDistance

shaderClipDistance

CullDistance

shaderCullDistance

ImageCubeArray

imageCubeArray

SampleRateShading

sampleRateShading

SparseResidency

shaderResourceResidency

MinLod

shaderResourceMinLod

SampledCubeArray

imageCubeArray

ImageMSArray

shaderStorageImageMultisample

StorageImageExtendedFormats

InterpolationFunction

sampleRateShading

StorageImageReadWithoutFormat

shaderStorageImageReadWithoutFormat

StorageImageWriteWithoutFormat

shaderStorageImageWriteWithoutFormat

MultiViewport

DrawParameters

VK_KHR_shader_draw_parameters

MultiView

multiview

DeviceGroup

VariablePointersStorageBuffer

variablePointersStorageBuffer

VariablePointers

ShaderClockKHR

VK_KHR_shader_clock

StorageBuffer16BitAccess

StorageBuffer16BitAccess

UniformAndStorageBuffer16BitAccess

UniformAndStorageBuffer16BitAccess

StoragePushConstant16

storagePushConstant16

StorageInputOutput16

storageInputOutput16

Float16

shaderFloat16

Int8

StorageBuffer8BitAccess

StorageBuffer8BitAccess

UniformAndStorageBuffer8BitAccess

UniformAndStorageBuffer8BitAccess

StoragePushConstant8

VulkanMemoryModel

vulkanMemoryModel

VulkanMemoryModelDeviceScope

DenormPreserve

DenormFlushToZero

SignedZeroInfNanPreserve

RoundingModeRTE

RoundingModeRTZ

RayTracingProvisionalKHR

rayTracing

RayQueryProvisionalKHR

rayQuery

RayTraversalPrimitiveCullingProvisionalKHR

PhysicalStorageBufferAddresses

bufferDeviceAddress

The application must not pass a SPIR-V 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.

#### SPIR-V Extensions

The application can pass a SPIR-V module to vkCreateShaderModule that uses the following SPIR-V extensions if 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).

Table 66. List of SPIR-V Extensions and corresponding Vulkan extensions or core version
SPIR-V OpExtension Vulkan extension or core version

SPV_KHR_variable_pointers

VK_KHR_variable_pointers

SPV_KHR_shader_draw_parameters

VK_KHR_shader_draw_parameters

SPV_KHR_8bit_storage

VK_KHR_8bit_storage

SPV_KHR_16bit_storage

VK_KHR_16bit_storage

SPV_KHR_shader_clock

VK_KHR_shader_clock

SPV_KHR_float_controls

VK_KHR_shader_float_controls

SPV_KHR_storage_buffer_storage_class

VK_KHR_storage_buffer_storage_class

SPV_KHR_vulkan_memory_model

VK_KHR_vulkan_memory_model

SPV_KHR_ray_tracing

VK_KHR_ray_tracing

SPV_KHR_ray_query

VK_KHR_ray_tracing

SPV_KHR_physical_storage_buffer

VK_KHR_buffer_device_address

SPV_KHR_non_semantic_info

VK_KHR_shader_non_semantic_info

### Validation Rules within a Module

A SPIR-V module passed to vkCreateShaderModule must conform to the following rules:

#### Standalone SPIR-V Validation

Rules which can be validated with only the SPIR-V module itself and do not depend on knowledge of the implementation and its capabilities or knowledge of runtime information such as enabled features.

• Every entry point must have no return value and accept no arguments.

• Recursion: The static function-call graph for an entry point must not contain cycles.

• The Logical or PhysicalStorageBuffer64 addressing model must be selected.

• Scope for execution must be limited to:

• Workgroup

• The Workgroup scope must only be used in the tessellation control, and compute execution models.

• Subgroup

• Scope for memory must be limited to:

• Device

• QueueFamily

• Workgroup

• The WorkGroup scope must only be used in the compute execution model(s).

• ShaderCallKHR

• The ShaderCallKHR scope must only be used in the ray generation, intersection, closest hit, any-hit, miss, and callable execution models.

• Invocation

• Only valid if memory semantics is None

• Storage Class must be limited to:

• UniformConstant

• Input

• Uniform

• Output

• The Output storage class must not be used in the RayGenerationKHR, IntersectionKHR, AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR execution models.

• Workgroup

• The Workgroup storage class must only be used in the compute execution model(s).

• Private

• Function

• PushConstant

• Image

• StorageBuffer

• RayPayloadKHR

• IncomingRayPayloadKHR

• HitAttributeKHR

• CallableDataKHR

• IncomingCallableDataKHR

• ShaderRecordBufferKHR

• PhysicalStorageBuffer

• Memory semantics must obey the following rules:

• Acquire must not be used with OpAtomicStore.

• Release must not be used with OpAtomicLoad.

• AcquireRelease must not be used with OpAtomicStore or OpAtomicLoad.

• Sequentially consistent atomics and barriers are not supported and SequentiallyConsistent is treated as AcquireRelease. SequentiallyConsistent should not be used.

• OpMemoryBarrier must use one of Acquire, Release, AcquireRelease, or SequentiallyConsistent and must include at least one storage class.

• If the semantics for OpControlBarrier includes one of Acquire, Release, AcquireRelease, or SequentiallyConsistent, then it must include at least one storage class.

• SubgroupMemory, CrossWorkgroupMemory, and AtomicCounterMemory are ignored.

• Any OpVariable with an Initializer operand must have one of the following as its Storage Class operand:

• Output

• Private

• Function

• Scope for OpReadClockKHR must be limited to:

• Subgroup

• Device

• The OriginLowerLeft execution mode must not be used; fragment entry points must declare OriginUpperLeft.

• The PixelCenterInteger execution mode must not be used. Pixels are always centered at half-integer coordinates.

• Any variable in the UniformConstant storage class must be typed as either:

• OpTypeImage

• OpTypeSampler

• OpTypeSampledImage

• OpTypeAccelerationStructureKHR,

• An array of one of these types.

• Images and Samplers

• OpTypeImage must declare a scalar 32-bit float or 32-bit integer type for the “Sampled Type”. (RelaxedPrecision can be applied to a sampling instruction and to the variable holding the result of a sampling instruction.)

• OpTypeImage must have a “Sampled” operand of 1 (sampled image) or 2 (storage image).

• If an OpImageTexelPointer is used in an atomic operation, the image type of the image parameter to OpImageTexelPointer must have an image format of R32i or R32ui.

• OpImageQuerySizeLod, and OpImageQueryLevels must only consume an “Image” operand whose type has its “Sampled” operand set to 1.

• The (u,v) coordinates used for a SubpassData must be the <id> of a constant vector (0,0), or if a layer coordinate is used, must be a vector that was formed with constant 0 for the u and v components.

• The “Depth” operand of OpTypeImage is ignored.

• Objects of types OpTypeImage, OpTypeSampler, OpTypeSampledImage, and arrays of these types must not be stored to or modified.

• Any image operation must use at most one of the Offset, ConstOffset, and ConstOffsets image operands.

• Image operand Offset must only be used with OpImage*Gather instructions.

• The “Component” operand of OpImageGather, and OpImageSparseGather must be the <id> of a constant instruction.

• Acceleration Structures

• Objects of types OpTypeAccelerationStructureKHR and arrays of this type must not be stored to or modified.

• The value of the “Hit Kind” operand of OpReportIntersectionKHR must be in the range [0,127].

• Structure types must not contain opaque types.

• Decorations

• Any BuiltIn decoration not listed in Built-In Variables must not be used.

• The GLSLShared and GLSLPacked decorations must not be used.

• The Flat, NoPerspective, Sample, and Centroid decorations must not be used on variables with storage class other than Input or on variables used in the interface of non-fragment shader entry points.

• The Patch decoration must not be used on variables in the interface of a vertex, geometry, or fragment shader stage’s entry point.

• Only the round-to-nearest-even and the round-towards-zero rounding modes can be used for the FPRoundingMode decoration.

• The FPRoundingMode decoration can only be used for the floating-point conversion instructions as described in the SPV_KHR_16bit_storage SPIR-V extension.

• Variables decorated with Invariant and variables with structure types that have any members decorated with Invariant must be in the Output or Input storage class. Invariant used on an Input storage class variable or structure member has no effect.

• OpTypeRuntimeArray must only be used for:

• the last member of an OpTypeStruct that is in the StorageBuffer storage class decorated as Block, or that is in the PhysicalStorageBuffer storage class decorated as Block, or that is in the Uniform storage class decorated as BufferBlock.

• Specialization constants:

• A type T that is an array sized with a specialization constant can be, or be contained in, the type of a Variable V only if:

• T is the (top-level) type of V, or

• V is declared in the Function, Private, or Workgroup storage classes, or

• V is an interface variable with an additional level of arrayness, as described in interface matching, in which case T is allowed to be the element type of the (top-level) type of V.

• Compute Shaders

• For each compute shader entry point, either a LocalSize execution mode or an object decorated with the WorkgroupSize decoration must be specified.

• Atomic instructions must declare a scalar 32-bit integer type, or a scalar 64-bit integer type if the Int64Atomics capability is enabled, for the value pointed to by Pointer.

• The Pointer operand of all atomic instructions must have a Storage Class limited to:

• Uniform

• Workgroup

• Image

• StorageBuffer

• RayPayloadKHR storage class must only be used in ray generation, any-hit, closest hit or miss shaders.

• IncomingRayPayloadKHR storage class must only be used in closest hit, any-hit, or miss shaders.

• HitAttributeKHR storage class must only be used in intersection, any-hit, or closest hit shaders.

• CallableDataKHR storage class must only be used in ray generation, closest hit, miss, and callable shaders.

• IncomingCallableDataKHR storage class must only be used in callable shaders.

• The Base operand of OpPtrAccessChain must point to one of the following storage classes:

• Workgroup, if VariablePointers is enabled.

• StorageBuffer, if VariablePointers or VariablePointersStorageBuffer is enabled.

• PhysicalStorageBuffer, if the PhysicalStorageBuffer64 addressing model is enabled.

• If the PhysicalStorageBuffer64 addressing model is enabled:

• All instructions that support memory access operands and that use a physical pointer must include the Aligned operand.

• Any access chain instruction that accesses into a RowMajor matrix must only be used as the Pointer operand to OpLoad or OpStore.

• OpConvertUToPtr and OpConvertPtrToU must use an integer type whose Width is 64.

#### Runtime SPIR-V Validation

Rules which must be validated at runetime as they depend on knowledge of the implementation and its capabilities or knowledge of runtime information such as enabled features.

### Precision and Operation of SPIR-V Instructions

The following rules apply to half, single, and double-precision 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 non-zero 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 double-precision floating-point instructions that ignore sign of a zero, or assume that arguments and results are not NaNs or infinities. If the entry point is declared with the SignedZeroInfNanPreserve execution mode, then NaNs, infinities, and the sign of zero must not be ignored.

• The following core SPIR-V instructions must respect the SignedZeroInfNanPreserve execution mode: OpPhi, OpSelect, OpReturnValue, OpVectorExtractDynamic, OpVectorInsertDynamic, OpVectorShuffle, OpCompositeConstruct, OpCompositeExtract, OpCompositeInsert, OpCopyObject, OpTranspose, OpFConvert, OpFNegate, OpFAdd, OpFSub, OpFMul, OpStore. This execution mode must also be respected by OpLoad except for loads from the Input storage class in the fragment shader stage with the floating-point result type. Other SPIR-V instructions may also respect the SignedZeroInfNanPreserve execution mode.

• 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.

• Denormalized values are supported.

• By default, any half, single, or double-precision denormalized value input into a shader or potentially generated by any instruction (except those listed above) or any extended instructions for GLSL in a shader may be flushed to zero.

• If the entry point is declared with the DenormFlushToZero execution mode then for the affected instuctions the denormalized result must be flushed to zero and the denormalized operands may be flushed to zero. Denormalized values obtained via unpacking an integer into a vector of values with smaller bit width and interpreting those values as floating-point numbers must be flushed to zero.

• The following core SPIR-V instructions must respect the DenormFlushToZero execution mode: OpSpecConstantOp (with opcode OpFConvert), OpFConvert, OpFNegate, OpFAdd, OpFSub, OpFMul, OpFDiv, OpFRem, OpFMod, OpVectorTimesScalar, OpMatrixTimesScalar, OpVectorTimesMatrix, OpMatrixTimesVector, OpMatrixTimesMatrix, OpOuterProduct, OpDot; and the following extended instructions for GLSL: Round, RoundEven, Trunc, FAbs, Floor, Ceil, Fract, Radians, Degrees, Sin, Cos, Tan, Asin, Acos, Atan, Sinh, Cosh, Tanh, Asinh, Acosh, Atanh, Atan2, Pow, Exp, Log, Exp2, Log2, Sqrt, InverseSqrt, Determinant, MatrixInverse, Modf, ModfStruct, FMin, FMax, FClamp, FMix, Step, SmoothStep, Fma, UnpackHalf2x16, UnpackDouble2x32, Length, Distance, Cross, Normalize, FaceForward, Reflect, Refract, NMin, NMax, NClamp. Other SPIR-V instructions (except those excluded above) may also flush denormalized values.

• The following core SPIR-V instructions must respect the DenormPreserve execution mode: OpTranspose, OpSpecConstantOp, OpFConvert, OpFNegate, OpFAdd, OpFSub, OpFMul, OpVectorTimesScalar, OpMatrixTimesScalar, OpVectorTimesMatrix, OpMatrixTimesVector, OpMatrixTimesMatrix, OpOuterProduct, OpDot, OpFOrdEqual, OpFUnordEqual, OpFOrdNotEqual, OpFUnordNotEqual, OpFOrdLessThan, OpFUnordLessThan, OpFOrdGreaterThan, OpFUnordGreaterThan, OpFOrdLessThanEqual, OpFUnordLessThanEqual, OpFOrdGreaterThanEqual, OpFUnordGreaterThanEqual; and the following extended instructions for GLSL: FAbs, FSign, Radians, Degrees, FMin, FMax, FClamp, FMix, Fma, PackHalf2x16, PackDouble2x32, UnpackHalf2x16, UnpackDouble2x32, NMin, NMax, NClamp. Other SPIR-V instructions may also preserve denorm values.

The precision of double-precision 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.

Correctly Rounded

Operations described as “correctly rounded” will return the infinitely precise result, x, rounded so as to be representable in floating-point. The rounding mode is not specified, unless the entry point is declared with the RoundingModeRTE or the RoundingModeRTZ execution mode. These execution modes affect only correctly rounded SPIR-V instructions. These execution modes do not affect OpQuantizeToF16. If the rounding mode is not specified then this rounding is implementation specific, subject to the following rules. If x is exactly representable then x will be returned. Otherwise, either the floating-point value closest to and no less than x or the value closest to and no greater than x will be returned.

ULP

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 non-equal floating-point numbers a and b such that a ≤ x ≤ b then ulp(x) is the minimum possible distance between such numbers, . If such numbers do not exist then ulp(x) is defined to be the difference between the two finite floating-point numbers nearest to x.

Where the range of allowed return values includes any value of magnitude larger than that of the largest representable finite floating-point 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.

Inherited From …​

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 SPIR-V 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 Fmax and the smallest be Fmin. The operation must return a value in the range [x - E, x + E] where . If the entry point is declared with the DenormFlushToZero execution mode, then any intermediate denormal value(s) while evaluating the formula may be flushed to zero. Denormal final results must be flushed to zero. If the entry point is declared with the DenormPreserve execution mode, then denormals must be preserved throughout the formula.

For half- (16 bit) and single- (32 bit) precision instructions, precisions are required to be at least as follows:

Table 67. Precision of core SPIR-V Instructions
Instruction Single precision, unless decorated with RelaxedPrecision Half precision

OpFAdd

Correctly rounded.

OpFSub

Correctly rounded.

OpFMul, OpVectorTimesScalar, OpMatrixTimesScalar

Correctly rounded.

OpDot(x, y)

Inherited from .

OpFOrdEqual, OpFUnordEqual

Correct result.

OpFOrdLessThan, OpFUnordLessThan

Correct result.

OpFOrdGreaterThan, OpFUnordGreaterThan

Correct result.

OpFOrdLessThanEqual, OpFUnordLessThanEqual

Correct result.

OpFOrdGreaterThanEqual, OpFUnordGreaterThanEqual

Correct result.

OpFDiv(x,y)

2.5 ULP for |y| in the range [2-126, 2126].

2.5 ULP for |y| in the range [2-14, 214].

OpFRem(x,y)

Inherited from x - y × trunc(x/y).

OpFMod(x,y)

Inherited from x - y × floor(x/y).

conversions between types

Correctly rounded.

 Note The OpFRem and OpFMod instructions use cheap approximations of remainder, and the error can be large due to the discontinuity in trunc() and floor(). This can produce mathematically unexpected results in some cases, such as FMod(x,x) computing x rather than 0, and can also cause the result to have a different sign than the infinitely precise result.
Table 68. Precision of GLSL.std.450 Instructions
Instruction Single precision, unless decorated with RelaxedPrecision Half precision

fma()

Inherited from OpFMul followed by OpFAdd.

exp(x), exp2(x)

ULP.

ULP.

log(), log2()

3 ULP outside the range . Absolute error < inside the range .

3 ULP outside the range . Absolute error < inside the range .

pow(x, y)

Inherited from exp2(y × log2(x)).

sqrt()

Inherited from 1.0 / inversesqrt().

inversesqrt()

2 ULP.

radians(x)

Inherited from .

degrees(x)

Inherited from .

sin()

Absolute error inside the range .

Absolute error inside the range .

cos()

Absolute error inside the range .

Absolute error inside the range .

tan()

Inherited from .

asin(x)

Inherited from .

acos(x)

Inherited from .

atan(), atan2()

4096 ULP

5 ULP.

sinh(x)

Inherited from .

cosh(x)

Inherited from .

tanh()

Inherited from .

asinh(x)

Inherited from .

acosh(x)

Inherited from .

atanh(x)

Inherited from .

frexp()

Correctly rounded.

ldexp()

Correctly rounded.

length(x)

Inherited from .

distance(x, y)

Inherited from .

cross()

Inherited from OpFSub(OpFMul, OpFMul).

normalize(x)

Inherited from .

faceforward(N, I, NRef)

Inherited from dot(NRef, I) < 0.0 ? N : -N.

reflect(x, y)

Inherited from x - 2.0 × dot(y, x) × y.

refract(I, N, eta)

Inherited from k < 0.0 ? 0.0 : eta × I - (eta × dot(N, I) + sqrt(k)) × N, where k = 1 - eta × eta × (1.0 - dot(N, I) × dot(N, I)).

round

Correctly rounded.

roundEven

Correctly rounded.

trunc

Correctly rounded.

fabs

Correctly rounded.

fsign

Correctly rounded.

floor

Correctly rounded.

ceil

Correctly rounded.

fract

Correctly rounded.

modf

Correctly rounded.

fmin

Correctly rounded.

fmax

Correctly rounded.

fclamp

Correctly rounded.

fmix(x, y, a)

Inherited from .

step

Correctly rounded.

smoothStep(edge0, edge1, x)

Inherited from , where .

nmin

Correctly rounded.

nmax

Correctly rounded.

nclamp

Correctly rounded.

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 OpSRem and OpSMod instructions are supported by the Vulkan environment, they require non-negative values and thus do not enable additional functionality beyond what OpUMod provides.

### 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

Unknown

Any

Any

Any

Rgba32f

OpTypeFloat

32

N/A

Rg32f

R32f

Rgba16f

Rg16f

R16f

Rgba16

Rg16

R16

Rgba16Snorm

Rg16Snorm

R16Snorm

Rgb10A2

R11fG11fB10f

Rgba8

Rg8

R8

Rgba8Snorm

Rg8Snorm

R8Snorm

Rgba32i

OpTypeInt

32

1

Rg32i

R32i

Rgba16i

Rg16i

R16i

Rgba8i

Rg8i

R8i

Rgba32ui

0

Rg32ui

R32ui

Rgba16ui

Rg16ui

R16ui

Rgb10a2ui

Rgba8ui

Rg8ui

R8ui

### Compatibility Between SPIR-V Image Formats And Vulkan Formats

SPIR-V Image Format values are compatible with VkFormat values as defined below:

Table 69. SPIR-V and Vulkan Image Format Compatibility
SPIR-V Image Format Compatible Vulkan Format

Unknown

Any

Rgba32f

VK_FORMAT_R32G32B32A32_SFLOAT

Rgba16f

VK_FORMAT_R16G16B16A16_SFLOAT

R32f

VK_FORMAT_R32_SFLOAT

Rgba8

VK_FORMAT_R8G8B8A8_UNORM

Rgba8Snorm

VK_FORMAT_R8G8B8A8_SNORM

Rg32f

VK_FORMAT_R32G32_SFLOAT

Rg16f

VK_FORMAT_R16G16_SFLOAT

R11fG11fB10f

VK_FORMAT_B10G11R11_UFLOAT_PACK32

R16f

VK_FORMAT_R16_SFLOAT

Rgba16

VK_FORMAT_R16G16B16A16_UNORM

Rgb10A2

VK_FORMAT_A2B10G10R10_UNORM_PACK32

Rg16

VK_FORMAT_R16G16_UNORM

Rg8

VK_FORMAT_R8G8_UNORM

R16

VK_FORMAT_R16_UNORM

R8

VK_FORMAT_R8_UNORM

Rgba16Snorm

VK_FORMAT_R16G16B16A16_SNORM

Rg16Snorm

VK_FORMAT_R16G16_SNORM

Rg8Snorm

VK_FORMAT_R8G8_SNORM

R16Snorm

VK_FORMAT_R16_SNORM

R8Snorm

VK_FORMAT_R8_SNORM

Rgba32i

VK_FORMAT_R32G32B32A32_SINT

Rgba16i

VK_FORMAT_R16G16B16A16_SINT

Rgba8i

VK_FORMAT_R8G8B8A8_SINT

R32i

VK_FORMAT_R32_SINT

Rg32i

VK_FORMAT_R32G32_SINT

Rg16i

VK_FORMAT_R16G16_SINT

Rg8i

VK_FORMAT_R8G8_SINT

R16i

VK_FORMAT_R16_SINT

R8i

VK_FORMAT_R8_SINT

Rgba32ui

VK_FORMAT_R32G32B32A32_UINT

Rgba16ui

VK_FORMAT_R16G16B16A16_UINT

Rgba8ui

VK_FORMAT_R8G8B8A8_UINT

R32ui

VK_FORMAT_R32_UINT

Rgb10a2ui

VK_FORMAT_A2B10G10R10_UINT_PACK32

Rg32ui

VK_FORMAT_R32G32_UINT

Rg16ui

VK_FORMAT_R16G16_UINT

Rg8ui

VK_FORMAT_R8G8_UINT

R16ui

VK_FORMAT_R16_UINT

R8ui

VK_FORMAT_R8_UINT