1340 lines
68 KiB
Plaintext
1340 lines
68 KiB
Plaintext
// Copyright (c) 2015-2019 Khronos Group. This work is licensed under a
|
|
// Creative Commons Attribution 4.0 International License; see
|
|
// http://creativecommons.org/licenses/by/4.0/
|
|
|
|
[appendix]
|
|
[[spirvenv]]
|
|
= Vulkan Environment for SPIR-V
|
|
|
|
Shaders for Vulkan are defined by the <<spirv-spec,Khronos SPIR-V
|
|
Specification>> as well as the <<spirv-extended,Khronos SPIR-V Extended
|
|
Instructions for GLSL>> Specification.
|
|
This appendix defines additional SPIR-V requirements applying to Vulkan
|
|
shaders.
|
|
|
|
== Versions and Formats
|
|
|
|
ifdef::VK_VERSION_1_1[]
|
|
A Vulkan 1.1 implementation must: support the 1.0, 1.1, 1.2, and 1.3
|
|
versions of SPIR-V and the 1.0 version of the SPIR-V Extended Instructions
|
|
for GLSL.
|
|
endif::VK_VERSION_1_1[]
|
|
ifndef::VK_VERSION_1_1[]
|
|
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.
|
|
endif::VK_VERSION_1_1[]
|
|
|
|
A SPIR-V module passed into flink: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.
|
|
|
|
|
|
[[spirvenv-capabilities]]
|
|
== Capabilities
|
|
|
|
The SPIR-V capabilities listed below must: be supported if the corresponding
|
|
feature or extension is enabled, or if no features or extensions are listed
|
|
for that capability.
|
|
Extensions are only listed when there is not also a feature bit associated
|
|
with that capability.
|
|
|
|
[[spirvenv-capabilities-table]]
|
|
.List of SPIR-V Capabilities and enabling features or extensions
|
|
[options="header"]
|
|
|====
|
|
| SPIR-V code:OpCapability | Vulkan feature or extension name
|
|
|
|
| code:Matrix |
|
|
| code:Shader |
|
|
| code:InputAttachment |
|
|
| code:Sampled1D |
|
|
| code:Image1D |
|
|
| code:SampledBuffer |
|
|
| code:ImageBuffer |
|
|
| code:ImageQuery |
|
|
| code:DerivativeControl |
|
|
| code:Geometry | <<features-features-geometryShader,geometryShader>>
|
|
| code:Tessellation | <<features-features-tessellationShader,tessellationShader>>
|
|
| code:Float64 | <<features-features-shaderFloat64,shaderFloat64>>
|
|
| code:Int64 | <<features-features-shaderInt64,shaderInt64>>
|
|
ifdef::VK_KHR_shader_atomic_int64[]
|
|
[[spirvenv-capabilities-table-int64atomics]]
|
|
| code:Int64Atomics | <<VK_KHR_shader_atomic_int64,VK_KHR_shader_atomic_int64>>
|
|
endif::VK_KHR_shader_atomic_int64[]
|
|
| code:Int16 | <<features-features-shaderInt16,shaderInt16>>
|
|
| code:TessellationPointSize | <<features-features-shaderTessellationAndGeometryPointSize,shaderTessellationAndGeometryPointSize>>
|
|
| code:GeometryPointSize | <<features-features-shaderTessellationAndGeometryPointSize,shaderTessellationAndGeometryPointSize>>
|
|
| code:ImageGatherExtended | <<features-features-shaderImageGatherExtended,shaderImageGatherExtended>>
|
|
| code:StorageImageMultisample | <<features-features-shaderStorageImageMultisample,shaderStorageImageMultisample>>
|
|
| code:UniformBufferArrayDynamicIndexing | <<features-features-shaderUniformBufferArrayDynamicIndexing,shaderUniformBufferArrayDynamicIndexing>>
|
|
| code:SampledImageArrayDynamicIndexing | <<features-features-shaderSampledImageArrayDynamicIndexing,shaderSampledImageArrayDynamicIndexing>>
|
|
| code:StorageBufferArrayDynamicIndexing | <<features-features-shaderStorageBufferArrayDynamicIndexing,shaderStorageBufferArrayDynamicIndexing>>
|
|
| code:StorageImageArrayDynamicIndexing | <<features-features-shaderStorageImageArrayDynamicIndexing,shaderStorageImageArrayDynamicIndexing>>
|
|
| code:ClipDistance | <<features-features-shaderClipDistance,shaderClipDistance>>
|
|
| code:CullDistance | <<features-features-shaderCullDistance,shaderCullDistance>>
|
|
| code:ImageCubeArray | <<features-features-imageCubeArray,imageCubeArray>>
|
|
| code:SampleRateShading | <<features-features-sampleRateShading,sampleRateShading>>
|
|
| code:SparseResidency | <<features-features-shaderResourceResidency,shaderResourceResidency>>
|
|
| code:MinLod | <<features-features-shaderResourceMinLod,shaderResourceMinLod>>
|
|
| code:SampledCubeArray | <<features-features-imageCubeArray,imageCubeArray>>
|
|
| code:ImageMSArray | <<features-features-shaderStorageImageMultisample,shaderStorageImageMultisample>>
|
|
| code:StorageImageExtendedFormats |
|
|
| code:InterpolationFunction | <<features-features-sampleRateShading,sampleRateShading>>
|
|
| code:StorageImageReadWithoutFormat | <<features-features-shaderStorageImageReadWithoutFormat,shaderStorageImageReadWithoutFormat>>
|
|
| code:StorageImageWriteWithoutFormat | <<features-features-shaderStorageImageWriteWithoutFormat,shaderStorageImageWriteWithoutFormat>>
|
|
| code:MultiViewport | <<features-features-multiViewport,multiViewport>>
|
|
ifdef::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[]
|
|
| code:DrawParameters |
|
|
ifdef::VK_VERSION_1_1[]
|
|
<<features-features-shaderDrawParameters,shaderDrawParameters>>
|
|
endif::VK_VERSION_1_1[]
|
|
ifdef::VK_KHR_shader_draw_parameters+VK_VERSION_1_1[]
|
|
or
|
|
endif::VK_KHR_shader_draw_parameters+VK_VERSION_1_1[]
|
|
ifdef::VK_KHR_shader_draw_parameters[]
|
|
<<VK_KHR_shader_draw_parameters>>
|
|
endif::VK_KHR_shader_draw_parameters[]
|
|
endif::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_multiview[]
|
|
[[spirvenv-capabilities-multiview]]
|
|
| code:MultiView |
|
|
ifndef::VK_VERSION_1_1[]
|
|
<<VK_KHR_multiview,VK_KHR_multiview>>
|
|
endif::VK_VERSION_1_1[]
|
|
endif::VK_VERSION_1_1,VK_KHR_multiview[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_device_group[]
|
|
| code:DeviceGroup |
|
|
ifndef::VK_VERSION_1_1[]
|
|
<<VK_KHR_device_group,VK_KHR_device_group>>
|
|
endif::VK_VERSION_1_1[]
|
|
endif::VK_VERSION_1_1,VK_KHR_device_group[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
[[spirvenv-capabilities-table-variablepointers]]
|
|
| code:VariablePointersStorageBuffer | <<features-features-variablePointersStorageBuffer,variablePointersStorageBuffer>>
|
|
| code:VariablePointers | <<features-features-variablePointers,variablePointers>>
|
|
endif::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
ifdef::VK_EXT_shader_stencil_export[]
|
|
[[spirvenv-capabilities-table-shaderstencilexportext]]
|
|
| code:StencilExportEXT | `<<VK_EXT_shader_stencil_export>>`
|
|
endif::VK_EXT_shader_stencil_export[]
|
|
ifdef::VK_EXT_shader_subgroup_ballot[]
|
|
[[spirvenv-capabilities-table-subgroupballot]]
|
|
| code:SubgroupBallotKHR | `<<VK_EXT_shader_subgroup_ballot>>`
|
|
endif::VK_EXT_shader_subgroup_ballot[]
|
|
ifdef::VK_EXT_shader_subgroup_vote[]
|
|
[[spirvenv-capabilities-table-subgroupvote]]
|
|
| code:SubgroupVoteKHR | `<<VK_EXT_shader_subgroup_vote>>`
|
|
endif::VK_EXT_shader_subgroup_vote[]
|
|
ifdef::VK_AMD_shader_image_load_store_lod[]
|
|
[[spirvenv-capabilities-table-imagereadwritelodamd]]
|
|
| code:ImageReadWriteLodAMD | `<<VK_AMD_shader_image_load_store_lod>>`
|
|
endif::VK_AMD_shader_image_load_store_lod[]
|
|
ifdef::VK_AMD_texture_gather_bias_lod[]
|
|
[[spirvenv-capabilities-table-imagegatherbiaslodamd]]
|
|
| code:ImageGatherBiasLodAMD | `<<VK_AMD_texture_gather_bias_lod>>`
|
|
endif::VK_AMD_texture_gather_bias_lod[]
|
|
ifdef::VK_AMD_shader_fragment_mask[]
|
|
[[spirvenv-capabilities-table-fragmentmaskamd]]
|
|
| code:FragmentMaskAMD | `<<VK_AMD_shader_fragment_mask>>`
|
|
endif::VK_AMD_shader_fragment_mask[]
|
|
ifdef::VK_NV_sample_mask_override_coverage[]
|
|
[[spirvenv-capabilities-table-samplemaskoverridecoverage]]
|
|
| code:SampleMaskOverrideCoverageNV | `<<VK_NV_sample_mask_override_coverage>>`
|
|
endif::VK_NV_sample_mask_override_coverage[]
|
|
ifdef::VK_NV_geometry_shader_passthrough[]
|
|
[[spirvenv-capabilities-table-geometryshaderpassthrough]]
|
|
| code:GeometryShaderPassthroughNV | `<<VK_NV_geometry_shader_passthrough>>`
|
|
endif::VK_NV_geometry_shader_passthrough[]
|
|
ifdef::VK_EXT_shader_viewport_index_layer[]
|
|
[[spirvenv-capabilities-table-shader-viewport-index-layer]]
|
|
| code:ShaderViewportIndexLayerEXT | `<<VK_EXT_shader_viewport_index_layer>>`
|
|
endif::VK_EXT_shader_viewport_index_layer[]
|
|
ifdef::VK_NV_viewport_array2[]
|
|
[[spirvenv-capabilities-table-viewportarray2]]
|
|
| code:ShaderViewportIndexLayerNV | `<<VK_NV_viewport_array2>>`
|
|
| code:ShaderViewportMaskNV | `<<VK_NV_viewport_array2>>`
|
|
endif::VK_NV_viewport_array2[]
|
|
ifdef::VK_NVX_multiview_per_view_attributes[]
|
|
[[spirvenv-capabilities-table-perviewattributes]]
|
|
| code:PerViewAttributesNV | `<<VK_NVX_multiview_per_view_attributes>>`
|
|
endif::VK_NVX_multiview_per_view_attributes[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
[[spirvenv-capabilities-table-16bitstorage]]
|
|
| code:StorageBuffer16BitAccess | <<features-features-storageBuffer16BitAccess, StorageBuffer16BitAccess>>
|
|
| code:UniformAndStorageBuffer16BitAccess | <<features-features-uniformAndStorageBuffer16BitAccess,UniformAndStorageBuffer16BitAccess>>
|
|
| code:StoragePushConstant16 | <<features-features-storagePushConstant16,storagePushConstant16>>
|
|
| code:StorageInputOutput16 | <<features-features-storageInputOutput16,storageInputOutput16>>
|
|
endif::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
ifdef::VK_VERSION_1_1[]
|
|
[[spirvenv-capabilities-table-subgroup]]
|
|
| code:GroupNonUniform | <<features-features-subgroup-basic,VK_SUBGROUP_FEATURE_BASIC_BIT>>
|
|
| code:GroupNonUniformVote | <<features-features-subgroup-vote,VK_SUBGROUP_FEATURE_VOTE_BIT>>
|
|
| code:GroupNonUniformArithmetic | <<features-features-subgroup-arithmetic,VK_SUBGROUP_FEATURE_ARITHMETIC_BIT>>
|
|
| code:GroupNonUniformBallot | <<features-features-subgroup-ballot,VK_SUBGROUP_FEATURE_BALLOT_BIT>>
|
|
| code:GroupNonUniformShuffle | <<features-features-subgroup-shuffle,VK_SUBGROUP_FEATURE_SHUFFLE_BIT>>
|
|
| code:GroupNonUniformShuffleRelative | <<features-features-subgroup-shuffle-relative,VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT>>
|
|
| code:GroupNonUniformClustered | <<features-features-subgroup-clustered,VK_SUBGROUP_FEATURE_CLUSTERED_BIT>>
|
|
| code:GroupNonUniformQuad | <<features-features-subgroup-quad,VK_SUBGROUP_FEATURE_QUAD_BIT>>
|
|
ifdef::VK_NV_shader_subgroup_partitioned[]
|
|
| code:GroupNonUniformPartitionedNV | <<features-features-subgroup-partitioned,VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV>>
|
|
endif::VK_NV_shader_subgroup_partitioned[]
|
|
endif::VK_VERSION_1_1[]
|
|
ifdef::VK_EXT_post_depth_coverage[]
|
|
[[spirvenv-capabilities-table-postdepthcoverage]]
|
|
| code:SampleMaskPostDepthCoverage | `<<VK_EXT_post_depth_coverage>>`
|
|
endif::VK_EXT_post_depth_coverage[]
|
|
ifdef::VK_EXT_descriptor_indexing[]
|
|
[[spirvenv-capabilities-table-descriptorindexing]]
|
|
| code:ShaderNonUniformEXT | `<<VK_EXT_descriptor_indexing>>`
|
|
| code:RuntimeDescriptorArrayEXT | <<features-features-runtimeDescriptorArray,runtimeDescriptorArray>>
|
|
| code:InputAttachmentArrayDynamicIndexingEXT | <<features-features-shaderInputAttachmentArrayDynamicIndexing,shaderInputAttachmentArrayDynamicIndexing>>
|
|
| code:UniformTexelBufferArrayDynamicIndexingEXT | <<features-features-shaderUniformTexelBufferArrayDynamicIndexing,shaderUniformTexelBufferArrayDynamicIndexing>>
|
|
| code:StorageTexelBufferArrayDynamicIndexingEXT | <<features-features-shaderStorageTexelBufferArrayDynamicIndexing,shaderStorageTexelBufferArrayDynamicIndexing>>
|
|
| code:UniformBufferArrayNonUniformIndexingEXT | <<features-features-shaderUniformBufferArrayNonUniformIndexing,shaderUniformBufferArrayNonUniformIndexing>>
|
|
| code:SampledImageArrayNonUniformIndexingEXT | <<features-features-shaderSampledImageArrayNonUniformIndexing,shaderSampledImageArrayNonUniformIndexing>>
|
|
| code:StorageBufferArrayNonUniformIndexingEXT | <<features-features-shaderStorageBufferArrayNonUniformIndexing,shaderStorageBufferArrayNonUniformIndexing>>
|
|
| code:StorageImageArrayNonUniformIndexingEXT | <<features-features-shaderStorageImageArrayNonUniformIndexing,shaderStorageImageArrayNonUniformIndexing>>
|
|
| code:InputAttachmentArrayNonUniformIndexingEXT | <<features-features-shaderInputAttachmentArrayNonUniformIndexing,shaderInputAttachmentArrayNonUniformIndexing>>
|
|
| code:UniformTexelBufferArrayNonUniformIndexingEXT | <<features-features-shaderUniformTexelBufferArrayNonUniformIndexing,shaderUniformTexelBufferArrayNonUniformIndexing>>
|
|
| code:StorageTexelBufferArrayNonUniformIndexingEXT | <<features-features-shaderStorageTexelBufferArrayNonUniformIndexing,shaderStorageTexelBufferArrayNonUniformIndexing>>
|
|
endif::VK_EXT_descriptor_indexing[]
|
|
ifdef::VK_KHR_shader_float16_int8,VK_AMD_gpu_shader_half_float[]
|
|
| code:Float16 |
|
|
ifdef::VK_KHR_shader_float16_int8[]
|
|
<<features-features-shaderFloat16,shaderFloat16>>
|
|
endif::VK_KHR_shader_float16_int8[]
|
|
ifdef::VK_KHR_shader_float16_int8+VK_AMD_gpu_shader_half_float[or]
|
|
ifdef::VK_AMD_gpu_shader_half_float[]
|
|
`<<VK_AMD_gpu_shader_half_float>>`
|
|
endif::VK_AMD_gpu_shader_half_float[]
|
|
endif::VK_KHR_shader_float16_int8,VK_AMD_gpu_shader_half_float[]
|
|
ifdef::VK_KHR_shader_float16_int8[]
|
|
| code:Int8 | <<features-features-shaderInt8,shaderInt8>>
|
|
endif::VK_KHR_shader_float16_int8[]
|
|
ifdef::VK_KHR_8bit_storage[]
|
|
[[spirvenv-capabilities-table-8bitstorage]]
|
|
| code:StorageBuffer8BitAccess | <<features-features-storageBuffer8BitAccess,StorageBuffer8BitAccess>>
|
|
| code:UniformAndStorageBuffer8BitAccess | <<features-features-uniformAndStorageBuffer8BitAccess,UniformAndStorageBuffer8BitAccess>>
|
|
| code:StoragePushConstant8 | <<features-features-storagePushConstant8,StoragePushConstant8>>
|
|
endif::VK_KHR_8bit_storage[]
|
|
ifdef::VK_KHR_vulkan_memory_model[]
|
|
[[spirvenv-capabilities-table-memorymodel]]
|
|
| code:VulkanMemoryModelKHR | <<features-features-vulkanMemoryModel,vulkanMemoryModel>>
|
|
| code:VulkanMemoryModelDeviceScopeKHR | <<features-features-vulkanMemoryModel,vulkanMemoryModelDeviceScope>>
|
|
endif::VK_KHR_vulkan_memory_model[]
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
[[spirvenv-capabilities-table-shaderfloatcontrols]]
|
|
| code:DenormPreserve | <<features-features-shaderDenormPreserveFloat16,shaderDenormPreserveFloat16>>, <<features-features-shaderDenormPreserveFloat32,shaderDenormPreserveFloat32>>, <<features-features-shaderDenormPreserveFloat64,shaderDenormPreserveFloat64>>
|
|
| code:DenormFlushToZero | <<features-features-shaderDenormFlushToZeroFloat16,shaderDenormFlushToZeroFloat16>>, <<features-features-shaderDenormFlushToZeroFloat32,shaderDenormFlushToZeroFloat32>>, <<features-features-shaderDenormFlushToZeroFloat64,shaderDenormFlushToZeroFloat64>>
|
|
| code:SignedZeroInfNanPreserve | <<features-features-shaderSignedZeroInfNanPreserveFloat16,shaderSignedZeroInfNanPreserveFloat16>>, <<features-features-shaderSignedZeroInfNanPreserveFloat32,shaderSignedZeroInfNanPreserveFloat32>>, <<features-features-shaderSignedZeroInfNanPreserveFloat64,shaderSignedZeroInfNanPreserveFloat64>>
|
|
| code:RoundingModeRTE | <<features-features-shaderRoundingModeRTEFloat16,shaderRoundingModeRTEFloat16>>, <<features-features-shaderRoundingModeRTEFloat32,shaderRoundingModeRTEFloat32>>, <<features-features-shaderRoundingModeRTEFloat64,shaderRoundingModeRTEFloat64>>
|
|
| code:RoundingModeRTZ | <<features-features-shaderRoundingModeRTZFloat16,shaderRoundingModeRTZFloat16>>, <<features-features-shaderRoundingModeRTZFloat32,shaderRoundingModeRTZFloat32>>, <<features-features-shaderRoundingModeRTZFloat64,shaderRoundingModeRTZFloat64>>
|
|
endif::VK_KHR_shader_float_controls[]
|
|
ifdef::VK_NV_compute_shader_derivatives[]
|
|
[[spirvenv-capabilities-table-computederivatives-quads]]
|
|
| code:ComputeDerivativeGroupQuadsNV | <<features-features-computeShaderDerivativesQuads,computeDerivativeGroupQuads>>
|
|
[[spirvenv-capabilities-table-computederivatives-linear]]
|
|
| code:ComputeDerivativeGroupLinearNV | <<features-features-computeShaderDerivativesLinear,computeDerivativeGroupLinear>>
|
|
endif::VK_NV_compute_shader_derivatives[]
|
|
ifdef::VK_NV_fragment_shader_barycentric[]
|
|
[[spirvenv-capabilities-fragment-barycentric]]
|
|
| code:FragmentBarycentricNV | <<features-features-fragmentShaderBarycentric,fragmentShaderBarycentric>>
|
|
endif::VK_NV_fragment_shader_barycentric[]
|
|
ifdef::VK_NV_shader_image_footprint[]
|
|
[[spirvenv-capabilities-table-imagefootprint]]
|
|
| code:ImageFootprintNV | <<features-features-imageFootprint,imageFootprint>>
|
|
endif::VK_NV_shader_image_footprint[]
|
|
ifdef::VK_NV_shading_rate_image[]
|
|
| code:ShadingRateImageNV | <<features-features-shadingRateImage,shadingRateImage>>
|
|
endif::VK_NV_shading_rate_image[]
|
|
ifdef::VK_NV_mesh_shader[]
|
|
[[spirvenv-capabilities-table-meshshading]]
|
|
| code:MeshShadingNV | `<<VK_NV_mesh_shader>>`
|
|
endif::VK_NV_mesh_shader[]
|
|
ifdef::VK_NV_ray_tracing[]
|
|
[[spirvenv-capabilities-table-raytracing]]
|
|
| code:RayTracingNV | `<<VK_NV_ray_tracing>>`
|
|
endif::VK_NV_ray_tracing[]
|
|
ifdef::VK_EXT_transform_feedback[]
|
|
| code:TransformFeedback | <<features-features-transformFeedback,transformFeedback>>
|
|
| code:GeometryStreams | <<features-features-geometryStreams,geometryStreams>>
|
|
endif::VK_EXT_transform_feedback[]
|
|
ifdef::VK_EXT_fragment_density_map[]
|
|
[[spirvenv-capabilities-table-fragmentdensity]]
|
|
| code:FragmentDensityEXT | <<features-features-fragmentdensitymap,fragmentDensityMap>>
|
|
endif::VK_EXT_fragment_density_map[]
|
|
ifdef::VK_EXT_buffer_device_address[]
|
|
[[spirvenv-capabilities-table-physicalstoragebufferaddresses]]
|
|
| code:PhysicalStorageBufferAddressesEXT | <<features-features-bufferDeviceAddress,bufferDeviceAddress>>
|
|
endif::VK_EXT_buffer_device_address[]
|
|
|====
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_variable_pointers` SPIR-V extension.
|
|
endif::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
|
|
ifdef::VK_AMD_shader_explicit_vertex_parameter[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_shader_explicit_vertex_parameter` SPIR-V extension.
|
|
endif::VK_AMD_shader_explicit_vertex_parameter[]
|
|
|
|
ifdef::VK_AMD_gcn_shader[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_gcn_shader` SPIR-V extension.
|
|
endif::VK_AMD_gcn_shader[]
|
|
|
|
ifdef::VK_AMD_gpu_shader_half_float[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_gpu_shader_half_float` SPIR-V extension.
|
|
endif::VK_AMD_gpu_shader_half_float[]
|
|
|
|
ifdef::VK_AMD_gpu_shader_int16[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_gpu_shader_int16` SPIR-V extension.
|
|
endif::VK_AMD_gpu_shader_int16[]
|
|
|
|
ifdef::VK_AMD_shader_ballot[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_shader_ballot` SPIR-V extension.
|
|
endif::VK_AMD_shader_ballot[]
|
|
|
|
ifdef::VK_AMD_shader_fragment_mask[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_shader_fragment_mask` SPIR-V extension.
|
|
endif::VK_AMD_shader_fragment_mask[]
|
|
|
|
ifdef::VK_AMD_shader_image_load_store_lod[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_shader_image_load_store_lod` SPIR-V extension.
|
|
endif::VK_AMD_shader_image_load_store_lod[]
|
|
|
|
ifdef::VK_AMD_shader_trinary_minmax[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_shader_trinary_minmax` SPIR-V extension.
|
|
endif::VK_AMD_shader_trinary_minmax[]
|
|
|
|
ifdef::VK_AMD_texture_gather_bias_lod[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_AMD_texture_gather_bias_lod` SPIR-V extension.
|
|
endif::VK_AMD_texture_gather_bias_lod[]
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_shader_draw_parameters` SPIR-V extension.
|
|
endif::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[]
|
|
|
|
ifdef::VK_KHR_8bit_storage[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_8bit_storage` SPIR-V extension.
|
|
endif::VK_KHR_8bit_storage[]
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the
|
|
https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_16bit_storage.html[`SPV_KHR_16bit_storage`]
|
|
SPIR-V extension.
|
|
endif::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the
|
|
https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_float_controls.html[`SPV_KHR_float_controls`]
|
|
SPIR-V extension.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the
|
|
https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_storage_buffer_storage_class.html[`SPV_KHR_storage_buffer_storage_class`]
|
|
SPIR-V extension.
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
|
|
ifdef::VK_EXT_post_depth_coverage[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_post_depth_coverage` SPIR-V extension.
|
|
endif::VK_EXT_post_depth_coverage[]
|
|
|
|
ifdef::VK_EXT_shader_stencil_export[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_EXT_shader_stencil_export` SPIR-V extension.
|
|
endif::VK_EXT_shader_stencil_export[]
|
|
|
|
ifdef::VK_EXT_shader_subgroup_ballot[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_shader_ballot` SPIR-V extension.
|
|
endif::VK_EXT_shader_subgroup_ballot[]
|
|
|
|
ifdef::VK_EXT_shader_subgroup_vote[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_subgroup_vote` SPIR-V extension.
|
|
endif::VK_EXT_shader_subgroup_vote[]
|
|
|
|
ifdef::VK_NV_sample_mask_override_coverage[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_sample_mask_override_coverage` SPIR-V extension.
|
|
endif::VK_NV_sample_mask_override_coverage[]
|
|
|
|
ifdef::VK_NV_geometry_shader_passthrough[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_geometry_shader_passthrough` SPIR-V extension.
|
|
endif::VK_NV_geometry_shader_passthrough[]
|
|
|
|
ifdef::VK_NV_mesh_shader[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_mesh_shader` SPIR-V extension.
|
|
endif::VK_NV_mesh_shader[]
|
|
|
|
ifdef::VK_NV_viewport_array2[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_viewport_array2` SPIR-V extension.
|
|
endif::VK_NV_viewport_array2[]
|
|
|
|
ifdef::VK_EXT_shader_viewport_index_layer[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_EXT_shader_viewport_index_layer` SPIR-V extension.
|
|
endif::VK_EXT_shader_viewport_index_layer[]
|
|
|
|
ifdef::VK_NVX_multiview_per_view_attributes[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NVX_multiview_per_view_attributes` SPIR-V extension.
|
|
endif::VK_NVX_multiview_per_view_attributes[]
|
|
|
|
ifdef::VK_EXT_descriptor_indexing[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_EXT_descriptor_indexing` SPIR-V extension.
|
|
endif::VK_EXT_descriptor_indexing[]
|
|
|
|
ifdef::VK_KHR_vulkan_memory_model[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_KHR_vulkan_memory_model` SPIR-V extension.
|
|
endif::VK_KHR_vulkan_memory_model[]
|
|
|
|
ifdef::VK_NV_compute_shader_derivatives[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_compute_shader_derivatives` SPIR-V extension.
|
|
endif::VK_NV_compute_shader_derivatives[]
|
|
|
|
ifdef::VK_NV_fragment_shader_barycentric[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_fragment_shader_barycentric` SPIR-V extension.
|
|
endif::VK_NV_fragment_shader_barycentric[]
|
|
|
|
ifdef::VK_NV_shader_image_footprint[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_shader_image_footprint` SPIR-V extension.
|
|
endif::VK_NV_shader_image_footprint[]
|
|
|
|
ifdef::VK_NV_shading_rate_image[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_shading_rate` SPIR-V extension.
|
|
endif::VK_NV_shading_rate_image[]
|
|
|
|
ifdef::VK_NV_ray_tracing[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NV_ray_tracing` SPIR-V extension.
|
|
endif::VK_NV_ray_tracing[]
|
|
|
|
ifdef::VK_GOOGLE_hlsl_functionality1[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_GOOGLE_hlsl_functionality1` SPIR-V extension.
|
|
endif::VK_GOOGLE_hlsl_functionality1[]
|
|
|
|
ifdef::VK_GOOGLE_decorate_string[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_GOOGLE_decorate_string` SPIR-V extension.
|
|
endif::VK_GOOGLE_decorate_string[]
|
|
|
|
ifdef::VK_EXT_fragment_density_map[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_EXT_fragment_invocation_density` SPIR-V extension.
|
|
endif::VK_EXT_fragment_density_map[]
|
|
|
|
ifdef::VK_EXT_buffer_device_address[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_EXT_physical_storage_buffer` SPIR-V extension.
|
|
endif::VK_EXT_buffer_device_address[]
|
|
|
|
The application must: not pass a SPIR-V module containing any of the
|
|
following to flink: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.
|
|
|
|
|
|
[[spirvenv-module-validation]]
|
|
== Validation Rules within a Module
|
|
|
|
A SPIR-V module passed to flink:vkCreateShaderModule must: conform to the
|
|
following rules:
|
|
|
|
* 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* addressing model must: be selected.
|
|
* *Scope* for execution must: be limited to:
|
|
** *Workgroup*
|
|
** *Subgroup*
|
|
* *Scope* for memory must: be limited to:
|
|
** *Device*
|
|
ifdef::VK_KHR_vulkan_memory_model[]
|
|
*** If <<features-features-vulkanMemoryModel,pname:vulkanMemoryModel>> is
|
|
enabled and
|
|
<<features-features-vulkanMemoryModelDeviceScope,pname:vulkanMemoryModelDeviceScope>>
|
|
is not enabled, *Device* scope must: not be used.
|
|
*** If <<features-features-vulkanMemoryModel,pname:vulkanMemoryModel>> is
|
|
not enabled, *Device* scope only extends to the queue family, not the
|
|
whole device.
|
|
endif::VK_KHR_vulkan_memory_model[]
|
|
ifndef::VK_KHR_vulkan_memory_model[]
|
|
*** *Device* scope only extends to the queue family, not the whole device.
|
|
endif::VK_KHR_vulkan_memory_model[]
|
|
ifdef::VK_KHR_vulkan_memory_model[]
|
|
** *QueueFamilyKHR*
|
|
*** If <<features-features-vulkanMemoryModel,pname:vulkanMemoryModel>> is
|
|
not enabled, *QueueFamilyKHR* must: not be used.
|
|
endif::VK_KHR_vulkan_memory_model[]
|
|
** *Workgroup*
|
|
ifdef::VK_VERSION_1_1[]
|
|
** *Subgroup*
|
|
endif::VK_VERSION_1_1[]
|
|
** *Invocation*
|
|
ifdef::VK_VERSION_1_1[]
|
|
* *Scope* for *Non Uniform Group Operations* must: be limited to:
|
|
** *Subgroup*
|
|
endif::VK_VERSION_1_1[]
|
|
* *Storage Class* must: be limited to:
|
|
** *UniformConstant*
|
|
** *Input*
|
|
** *Uniform*
|
|
** *Output*
|
|
** *Workgroup*
|
|
** *Private*
|
|
** *Function*
|
|
** *PushConstant*
|
|
** *Image*
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
** *StorageBuffer*
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
ifdef::VK_NV_ray_tracing[]
|
|
** *RayPayloadNV*
|
|
** *IncomingRayPayloadNV*
|
|
** *HitAttributeNV*
|
|
** *CallableDataNV*
|
|
** *IncomingCallableDataNV*
|
|
** *ShaderRecordBufferNV*
|
|
endif::VK_NV_ray_tracing[]
|
|
ifdef::VK_EXT_buffer_device_address[]
|
|
** *PhysicalStorageBufferEXT*
|
|
endif::VK_EXT_buffer_device_address[]
|
|
* Memory semantics must: obey the following rules:
|
|
** *Acquire* must: not be used with code:OpAtomicStore.
|
|
** *Release* must: not be used with code:OpAtomicLoad.
|
|
** *AcquireRelease* must: not be used with code:OpAtomicStore or
|
|
code:OpAtomicLoad.
|
|
** Sequentially consistent atomics and barriers are not supported and
|
|
*SequentiallyConsistent* is treated as *AcquireRelease*.
|
|
*SequentiallyConsistent* should: not be used.
|
|
** code:OpMemoryBarrier must: use one of *Acquire*, *Release*,
|
|
*AcquireRelease*, or *SequentiallyConsistent* and must: include at
|
|
least one storage class.
|
|
** If the semantics for code:OpControlBarrier includes one of *Acquire*,
|
|
*Release*, *AcquireRelease*, or *SequentiallyConsistent*, then it must:
|
|
include at least one storage class.
|
|
** *SubgroupMemory*, *CrossWorkgroupMemory*, and *AtomicCounterMemory* are
|
|
ignored.
|
|
ifdef::VK_KHR_shader_float16_int8+!VK_KHR_8bit_storage[]
|
|
* Any code:OpVariable with the result type pointing to an 8-bit integer
|
|
object or an object containing an 8-bit integer element must: not have
|
|
one of the following as its code:Storage code:Class operand:
|
|
** *Uniform*
|
|
** *PushConstant*
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
** *StorageBuffer*
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
endif::VK_KHR_shader_float16_int8+!VK_KHR_8bit_storage[]
|
|
ifdef::VK_KHR_shader_float16_int8+!VK_KHR_16bit_storage[]
|
|
* Any code:OpVariable with the result type pointing to a 16-bit
|
|
floating-point object or an object containing a 16-bit floating-point
|
|
element must: not have one of the following as its code:Storage
|
|
code:Class operand:
|
|
** *Uniform*
|
|
** *PushConstant*
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
** *StorageBuffer*
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
endif::VK_KHR_shader_float16_int8+!VK_KHR_16bit_storage[]
|
|
* Any code:OpVariable with an code:Initializer operand must: have one of
|
|
the following as its *Storage Class* operand:
|
|
** *Output*
|
|
** *Private*
|
|
** *Function*
|
|
* The code:OriginLowerLeft execution mode must: not be used; fragment
|
|
entry points must: declare code:OriginUpperLeft.
|
|
* The code:PixelCenterInteger execution mode must: not be used.
|
|
Pixels are always centered at half-integer coordinates.
|
|
* Images and Samplers
|
|
** code:OpTypeImage must: declare a scalar 32-bit float or 32-bit integer
|
|
type for the "`Sampled Type`".
|
|
(code:RelaxedPrecision can: be applied to a sampling instruction and to
|
|
the variable holding the result of a sampling instruction.)
|
|
** code:OpTypeImage must: have a "`Sampled`" operand of 1 (sampled image)
|
|
or 2 (storage image).
|
|
** If
|
|
<<features-features-shaderStorageImageReadWithoutFormat,shaderStorageImageReadWithoutFormat>>
|
|
is not enabled and an code:OpTypeImage has "`Image Format`" operand of
|
|
code:Unknown, any variables created with the given type must be
|
|
decorated with code:NonReadable.
|
|
** If
|
|
<<features-features-shaderStorageImageWriteWithoutFormat,shaderStorageImageWriteWithoutFormat>>
|
|
is not enabled and an code:OpTypeImage has "`Image Format`" operand of
|
|
code:Unknown, any variables created with the given type must be
|
|
decorated with code:NonWritable.
|
|
** code:OpImageQuerySizeLod, and code:OpImageQueryLevels must: only
|
|
consume an "`Image`" operand whose type has its "`Sampled`" operand set
|
|
to 1.
|
|
** The [eq]#(u,v)# coordinates used for a code:SubpassData must: be the
|
|
<id> of a constant vector [eq]#(0,0)#, or if a layer coordinate is
|
|
used, must: be a vector that was formed with constant 0 for the [eq]#u#
|
|
and [eq]#v# components.
|
|
** The "`Depth`" operand of code:OpTypeImage is ignored.
|
|
** Objects of types code:OpTypeImage, code:OpTypeSampler,
|
|
code:OpTypeSampledImage, and arrays of these types must: not be stored
|
|
to or modified.
|
|
* Decorations
|
|
** Any code:BuiltIn decoration not listed in
|
|
<<interfaces-builtin-variables>> must: not be used.
|
|
** Any code:BuiltIn decoration that corresponds only to Vulkan features or
|
|
extensions that have not been enabled must: not be used.
|
|
** The code:GLSLShared and code:GLSLPacked decorations must: not be used.
|
|
** The code:Flat, code:NoPerspective, code:Sample, and code:Centroid
|
|
decorations must: not be used on variables with storage class other
|
|
than code:Input or on variables used in the interface of non-fragment
|
|
shader entry points.
|
|
** The code:Patch decoration must: not be used on variables in the
|
|
interface of a vertex, geometry, or fragment shader stage's entry
|
|
point.
|
|
ifdef::VK_NV_viewport_array2[]
|
|
** The code:ViewportRelativeNV decoration must: only be used on a variable
|
|
decorated with code:Layer in the vertex, tessellation evaluation, or
|
|
geometry shader stages.
|
|
** The code:ViewportRelativeNV decoration must: not be used unless a
|
|
variable decorated with one of code:ViewportIndex or
|
|
code:ViewportMaskNV is also statically used by the same
|
|
code:OpEntryPoint.
|
|
** The code:ViewportMaskNV and code:ViewportIndex decorations must: not
|
|
both be statically used by one or more code:OpEntryPoint's that form
|
|
the vertex processing stages of a graphics pipeline.
|
|
endif::VK_NV_viewport_array2[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
** Only the round-to-nearest-even and the round-to-zero rounding modes
|
|
can: be used for the code:FPRoundingMode decoration.
|
|
** The code:FPRoundingMode decoration can: only be used for the
|
|
floating-point conversion instructions as described in the
|
|
https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_16bit_storage.html[`SPV_KHR_16bit_storage`]
|
|
SPIR-V extension.
|
|
endif::VK_VERSION_1_1,VK_KHR_16bit_storage[]
|
|
** code:DescriptorSet and code:Binding decorations must: obey the
|
|
constraints on storage class, type, and descriptor type described in
|
|
<<interfaces-resources-setandbinding,DescriptorSet and Binding
|
|
Assignment>>
|
|
* code:OpTypeRuntimeArray must: only be used for:
|
|
** the last member of an code:OpTypeStruct
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
that is in the code:StorageBuffer storage class decorated as
|
|
code:Block, or
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
ifdef::VK_EXT_buffer_device_address[]
|
|
that is in the code:PhysicalStorageBufferEXT storage class decorated as
|
|
code:Block, or
|
|
endif::VK_EXT_buffer_device_address[]
|
|
that is in the code:Uniform storage class decorated as
|
|
code:BufferBlock.
|
|
ifdef::VK_EXT_descriptor_indexing[]
|
|
** If the code:RuntimeDescriptorArrayEXT capability is supported, an array
|
|
of variables with storage class code:Uniform,
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
code:StorageBuffer,
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
or code:UniformConstant, or for the outermost dimension of an array of
|
|
arrays of such variables.
|
|
endif::VK_EXT_descriptor_indexing[]
|
|
* Linkage: See <<interfaces,Shader Interfaces>> for additional linking and
|
|
validation rules.
|
|
ifdef::VK_VERSION_1_1[]
|
|
* If code:OpControlBarrier is used in fragment, vertex, tessellation
|
|
evaluation, or geometry stages, the execution Scope must: be
|
|
code:Subgroup.
|
|
endif::VK_VERSION_1_1[]
|
|
* Compute Shaders
|
|
** For each compute shader entry point, either a code:LocalSize execution
|
|
mode or an object decorated with the code:WorkgroupSize decoration
|
|
must: be specified.
|
|
ifdef::VK_NV_compute_shader_derivatives[]
|
|
** For compute shaders using the code:DerivativeGroupQuadsNV execution
|
|
mode, the first two dimensions of the local workgroup size must: be a
|
|
multiple of two.
|
|
** For compute shaders using the code:DerivativeGroupLinearNV execution
|
|
mode, the product of the dimensions of the local workgroup size must:
|
|
be a multiple of four.
|
|
endif::VK_NV_compute_shader_derivatives[]
|
|
ifdef::VK_VERSION_1_1[]
|
|
* "`Result Type`" for *Non Uniform Group Operations* must: be limited to
|
|
32-bit float, 32-bit integer, boolean, or vectors of these types.
|
|
If the code:Float64 capability is enabled, double and vectors of double
|
|
types are also permitted.
|
|
* If code:OpGroupNonUniformBallotBitCount is used, the group operation
|
|
must: be one of:
|
|
** *Reduce*
|
|
** *InclusiveScan*
|
|
** *ExclusiveScan*
|
|
endif::VK_VERSION_1_1[]
|
|
* Atomic instructions must: declare a scalar 32-bit integer type,
|
|
ifdef::VK_KHR_shader_atomic_int64[]
|
|
or a scalar 64-bit integer type if the code:Int64Atomics capability is
|
|
enabled,
|
|
endif::VK_KHR_shader_atomic_int64[]
|
|
for the value pointed to by _Pointer_.
|
|
ifdef::VK_KHR_shader_atomic_int64[]
|
|
** <<features-features-shaderBufferInt64Atomics,shaderBufferInt64Atomics>>
|
|
must: be enabled for 64-bit integer atomic operations to be supported
|
|
on a _Pointer_ with a *Storage Class* of
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
*StorageBuffer* or
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
*Uniform*.
|
|
** <<features-features-shaderSharedInt64Atomics,shaderSharedInt64Atomics>>
|
|
must: be enabled for 64-bit integer atomic operations to be supported
|
|
on a _Pointer_ with a *Storage Class* of *Workgroup*.
|
|
endif::VK_KHR_shader_atomic_int64[]
|
|
* The _Pointer_ operand of all atomic instructions must: have a *Storage
|
|
Class* limited to:
|
|
** *Uniform*
|
|
** *Workgroup*
|
|
** *Image*
|
|
ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
** *StorageBuffer*
|
|
endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[]
|
|
ifdef::VK_EXT_descriptor_indexing[]
|
|
* If an instruction loads from or stores to a resource (including atomics
|
|
and image instructions) and the resource descriptor being accessed is
|
|
not dynamically uniform, then the operand corresponding to that resource
|
|
(e.g. the pointer or sampled image operand) must: be decorated with
|
|
code:NonUniformEXT.
|
|
endif::VK_EXT_descriptor_indexing[]
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
* If
|
|
<<features-features-separateDenormSettings,pname:separateDenormSettings>>
|
|
is ename:VK_FALSE, then the entry point must: use the same denormals
|
|
execution mode for both 16-bit and 64-bit floating-point types.
|
|
* If
|
|
<<features-features-separateRoundingModeSettings,pname:separateRoundingModeSettings>>
|
|
is ename:VK_FALSE, then the entry point must: use the same rounding
|
|
execution mode for both 16-bit and 64-bit floating-point types.
|
|
* If
|
|
<<features-features-shaderSignedZeroInfNanPreserveFloat16,pname:shaderSignedZeroInfNanPreserveFloat16>>
|
|
is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 16-bit
|
|
floating-point type must: not be used.
|
|
* If
|
|
<<features-features-shaderSignedZeroInfNanPreserveFloat32,pname:shaderSignedZeroInfNanPreserveFloat32>>
|
|
is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 32-bit
|
|
floating-point type must: not be used.
|
|
* If
|
|
<<features-features-shaderSignedZeroInfNanPreserveFloat64,pname:shaderSignedZeroInfNanPreserveFloat64>>
|
|
is ename:VK_FALSE, then code:SignedZeroInfNanPreserve for 64-bit
|
|
floating-point type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormPreserveFloat16,pname:shaderDenormPreserveFloat16>>
|
|
is ename:VK_FALSE, then code:DenormPreserve for 16-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormPreserveFloat32,pname:shaderDenormPreserveFloat32>>
|
|
is ename:VK_FALSE, then code:DenormPreserve for 32-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormPreserveFloat64,pname:shaderDenormPreserveFloat64>>
|
|
is ename:VK_FALSE, then code:DenormPreserve for 64-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormFlushToZeroFloat16,pname:shaderDenormFlushToZeroFloat16>>
|
|
is ename:VK_FALSE, then code:DenormFlushToZero for 16-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormFlushToZeroFloat32,pname:shaderDenormFlushToZeroFloat32>>
|
|
is ename:VK_FALSE, then code:DenormFlushToZero for 32-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderDenormFlushToZeroFloat64,pname:shaderDenormFlushToZeroFloat64>>
|
|
is ename:VK_FALSE, then code:DenormFlushToZero for 64-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTEFloat16,pname:shaderRoundingModeRTEFloat16>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTE for 16-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTEFloat32,pname:shaderRoundingModeRTEFloat32>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTE for 32-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTEFloat64,pname:shaderRoundingModeRTEFloat64>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTE for 64-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTZFloat16,pname:shaderRoundingModeRTZFloat16>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTZ for 16-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTZFloat32,pname:shaderRoundingModeRTZFloat32>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTZ for 32-bit floating-point
|
|
type must: not be used.
|
|
* If
|
|
<<features-features-shaderRoundingModeRTZFloat64,pname:shaderRoundingModeRTZFloat64>>
|
|
is ename:VK_FALSE, then code:RoundingModeRTZ for 64-bit floating-point
|
|
type must: not be used.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
ifdef::VK_EXT_transform_feedback[]
|
|
* The code:Offset plus size of the type of each variable, in the output
|
|
interface of the entry point being compiled, decorated with
|
|
code:XfbBuffer must: not be greater than
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataSize
|
|
* For any given code:XfbBuffer value, define the buffer data size to be
|
|
smallest number of bytes such that, for all outputs decorated with the
|
|
same code:XfbBuffer value, the size of the output interface variable
|
|
plus the code:Offset is less than or equal to the buffer data size.
|
|
For a given code:Stream, the sum of all the buffer data sizes for all
|
|
buffers writing to that stream the must: not exceed
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreamDataSize
|
|
* Output variables or block members decorated with code:Offset that have a
|
|
64-bit type, or a composite type containing a 64-bit type, must: specify
|
|
an code:Offset value aligned to a 8 byte boundary
|
|
* Any output block or block member decorated with code:Offset containing a
|
|
64-bit type consumes a multiple of 8 bytes
|
|
* The size of any output block, that contains any member decorated with
|
|
code:Offset that is a 64-bit type, must: be a multiple of 8
|
|
* The first member of an output block that specifies a code:Offset
|
|
decoration must: specify a code:Offset value that is aligned to an 8
|
|
byte boundary if that block contains any member decorated with
|
|
code:Offset and is a 64-bit type
|
|
* Output variables or block members decorated with code:Offset that have a
|
|
32-bit type, or a composite type contains a 32-bit type, must: specify
|
|
an code:Offset value aligned to a 4 byte boundary
|
|
* Output variables, blocks or block members decorated with code:Offset
|
|
must: only contain base types that have components that are either
|
|
32-bit or 64-bit in size
|
|
* The Stream value to code:OpEmitStreamVertex and
|
|
code:OpEndStreamPrimitive must: be less than
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams
|
|
* If the geometry shader emits to more than one vertex stream and
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:transformFeedbackStreamsLinesTriangles
|
|
is ename:VK_FALSE, then execution mode must: be code:OutputPoints
|
|
* Only variables or block members in the output interface decorated with
|
|
code:Offset can: be captured for transform feedback, and those variables
|
|
or block memebers must: also be decorated with code:XfbBuffer and
|
|
code:XfbStride, or inherit code:XfbBuffer and code:XfbStride decorations
|
|
from a block that contains them
|
|
* All variables or block members in the output interface of the entry
|
|
point being compiled decorated with a specific code:XfbBuffer value
|
|
must: all be decorated with identical code:XfbStride values
|
|
* If any variables or block members in the output interface of the entry
|
|
point being compiled are decorated with code:Stream, then all variables
|
|
belonging to the same code:XfbBuffer must specify the same code:Stream
|
|
value
|
|
* Output variables, blocks or block members that are not decorated with
|
|
code:Stream default to vertex stream zero
|
|
* For any two variables or block members in the output interface of the
|
|
entry point being compiled with the same code:XfbBuffer value, the
|
|
ranges determined by the code:Offset decoration and the size of the type
|
|
must: not overlap
|
|
* The stream number value to code:Stream must: be less than
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackStreams
|
|
* The XFB Stride value to code:XfbStride must be less than or equal to
|
|
sname:VkPhysicalDeviceTransformFeedbackPropertiesEXT::pname:maxTransformFeedbackBufferDataStride
|
|
endif::VK_EXT_transform_feedback[]
|
|
ifdef::VK_NV_ray_tracing[]
|
|
* code:RayPayloadNV storage class must: only be used in ray generation,
|
|
any-hit, closest hit or miss shaders.
|
|
* code:IncomingRayPayloadNV storage class must: only be used in closest
|
|
hit, any-hit, or miss shaders.
|
|
* code:HitAttributeNV storage class must: only be used in intersection,
|
|
any-hit, or closest hit shaders.
|
|
* code:CallableDataNV storage class must: only be used in ray generation,
|
|
closest hit, miss, and callable shaders.
|
|
* code:IncomingCallableDataNV storage class must only be used in callable
|
|
shaders.
|
|
endif::VK_NV_ray_tracing[]
|
|
ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers,VK_EXT_buffer_device_address[]
|
|
* The code:Base operand of code:OpPtrAccessChain must: point to one of the
|
|
following storage classes:
|
|
ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
** *Workgroup*, if code:VariablePointers is enabled.
|
|
** *StorageBuffer*, if code:VariablePointers or
|
|
code:VariablePointersStorageBuffer is enabled.
|
|
endif::VK_VERSION_1_1,VK_KHR_variable_pointers[]
|
|
** *PhysicalStorageBufferEXT*, if the code:PhysicalStorageBuffer64EXT
|
|
addressing model is enabled.
|
|
endif::VK_VERSION_1_1,VK_KHR_variable_pointers,VK_EXT_buffer_device_address[]
|
|
ifdef::VK_EXT_buffer_device_address[]
|
|
* If the code:PhysicalStorageBuffer64EXT addressing model is enabled:
|
|
** Any load or store through a physical pointer type must: be aligned to a
|
|
multiple of the size of the largest scalar type in the pointed-to type.
|
|
** All instructions that support memory access operands and that use a
|
|
physical pointer must: include the code:Aligned operand.
|
|
** The pointer value of a memory access instruction must be at least as
|
|
aligned as specified by the code:Aligned memory access operand.
|
|
** Any access chain instruction that accesses into a code:RowMajor matrix
|
|
must: only be used as the code:Pointer operand to code:OpLoad or
|
|
code:OpStore.
|
|
** code:OpConvertUToPtr and code:OpConvertPtrToU must: use an integer type
|
|
whose code:Width is 64.
|
|
endif::VK_EXT_buffer_device_address[]
|
|
|
|
|
|
[[spirvenv-precision-operation]]
|
|
== Precision and Operation of SPIR-V Instructions
|
|
|
|
ifndef::VK_KHR_shader_float_controls[]
|
|
The following rules apply to both single and double-precision floating point
|
|
instructions:
|
|
|
|
* Positive and negative infinities and positive and negative zeros are
|
|
generated as dictated by <<ieee-754,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,IEEE 754>> infinity.
|
|
* Any denormalized value input into a shader or potentially generated by
|
|
any instruction in a shader may: be flushed to 0.
|
|
* The rounding mode cannot: be set, and results will be <<Correctly
|
|
Rounded>>, as described below.
|
|
* [eq]##NaN##s may: not be generated.
|
|
Instructions that operate on a [eq]#NaN# may: not result in a [eq]#NaN#.
|
|
* Support for signaling [eq]##NaN##s is optional: and exceptions are never
|
|
raised.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
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,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,IEEE 754>> infinity.
|
|
* Signaling [eq]##NaN##s are not required to be generated and exceptions
|
|
are never raised.
|
|
Signaling [eq]##NaN## may: be converted to quiet [eq]##NaN##s values by
|
|
any floating point instruction.
|
|
* By default, the implementation may: perform optimizations on half,
|
|
single, or double-precision floating-point instructions respectively
|
|
that ignore sign of a zero, or assume that arguments and results are not
|
|
[eq]##Nan##s or latexmath:[\pm\infty], this doesn't apply to
|
|
code:OpIsNan and code:OpIsInf, which must: always correctly detect
|
|
[eq]##Nan##s and latexmath:[\pm\infty].
|
|
If the entry point is declared with the code:SignedZeroInfNanPreserve
|
|
execution mode, then sign of a zero, [eq]##Nan##s, and
|
|
latexmath:[\pm\infty] must: not be ignored.
|
|
** The following core SPIR-V instructions must: respect the
|
|
code:SignedZeroInfNanPreserve execution mode: code:OpPhi,
|
|
code:OpSelect, code:OpReturnValue, code:OpVectorExtractDynamic,
|
|
code:OpVectorInsertDynamic, code:OpVectorShuffle,
|
|
code:OpCompositeConstruct, code:OpCompositeExtract,
|
|
code:OpCompositeInsert, code:OpCopyObject, code:OpTranspose,
|
|
code:OpFConvert, code:OpFNegate, code:OpFAdd, code:OpFSub, code:OpFMul,
|
|
code:OpStore.
|
|
This execution mode must: also be respected by code:OpLoad except for
|
|
loads from the code:Input storage class in the fragment shader stage
|
|
with the floating-point result type.
|
|
Other SPIR-V instruction may: also respect the
|
|
code:SignedZeroInfNanPreserve execution mode.
|
|
* Denormalized values are supported.
|
|
** By default, any half, single, or double-precision denormalized value
|
|
input into a shader or potentially generated by any instruction or any
|
|
extended instructions for GLSL in a shader may: be flushed to zero.
|
|
** If the entry point is declared with the code: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
|
|
code:DenormFlushToZero execution mode: code:OpSpecConstantOp (except
|
|
when the opcode is code:OpQuantizeToF16), code:OpFConvert,
|
|
code:OpFNegate, code:OpFAdd, code:OpFSub, code:OpFMul, code:OpFDiv,
|
|
code:OpFRem, code:OpFMod, code:OpVectorTimesScalar,
|
|
code:OpMatrixTimesScalar, code:OpVectorTimesMatrix,
|
|
code:OpMatrixTimesVector, code:OpMatrixTimesMatrix,
|
|
code:OpOuterProduct, code:OpDot; and the following extended
|
|
instructions for GLSL: code:Round, code:RoundEven, code:Trunc,
|
|
code:FAbs, code:Floor, code:Ceil, code:Fract, code:Radians,
|
|
code:Degrees, code:Sin, code:Cos, code:Tan, code:Asin, code:Acos,
|
|
code:Atan, code:Sinh, code:Cosh, code:Tanh, code:Asinh, code:Acosh,
|
|
code:Atanh, code:Atan2, code:Pow, code:Exp, code:Log, code:Exp2,
|
|
code:Log2, code:Sqrt, code:InverseSqrt, code:Determinant,
|
|
code:MatrixInverse, code:Modf, code:ModfStruct, code:FMin, code:FMax,
|
|
code:FClamp, code:FMix, code:Step, code:SmoothStep, code:Fma,
|
|
code:UnpackHalf2x16, code:UnpackDouble2x32, code:Length, code:Distance,
|
|
code:Cross, code:Normalize, code:FaceForward, code:Reflect,
|
|
code:Refract, code:NMin, code:NMax, code:NClamp.
|
|
Other SPIR-V instruction may: also respect the code:DenormFlushToZero
|
|
execution mode.
|
|
** The following core SPIR-V instructions must: respect the
|
|
code:DenormPreserve execution mode: code:OpPhi, code:OpSelect,
|
|
code:OpReturnValue, code:OpVectorExtractDynamic,
|
|
code:OpVectorInsertDynamic, code:OpVectorShuffle,
|
|
code:OpCompositeConstruct, code:OpCompositeExtract,
|
|
code:OpCompositeInsert, code:OpCopyObject, code:OpTranspose,
|
|
code:OpStore, code:OpSpecConstantOp, code:OpFConvert, code:OpFNegate,
|
|
code:OpFAdd, code:OpFSub, code:OpFMul, code:OpVectorTimesScalar,
|
|
code:OpMatrixTimesScalar, code:OpVectorTimesMatrix,
|
|
code:OpMatrixTimesVector, code:OpMatrixTimesMatrix,
|
|
code:OpOuterProduct, code:OpDot, code:OpFOrdEqual, code:OpFUnordEqual,
|
|
code:OpFOrdNotEqual, code:OpFUnordNotEqual, code:OpFOrdLessThan,
|
|
code:OpFUnordLessThan, code:OpFOrdGreaterThan,
|
|
code:OpFUnordGreaterThan, code:OpFOrdLessThanEqual,
|
|
code:OpFUnordLessThanEqual, code:OpFOrdGreaterThanEqual,
|
|
code:OpFUnordGreaterThanEqual; and the following extended instructions
|
|
for GLSL: code:FAbs, code:FSign, code:Radians, code:Degrees, code:FMin,
|
|
code:FMax, code:FClamp, code:FMix, code:Fma, code:PackHalf2x16,
|
|
code:PackDouble2x32, code:UnpackHalf2x16, code:UnpackDouble2x32,
|
|
code:NMin, code:NMax, code:NClamp.
|
|
This execution mode must: also be respected by code:OpLoad except for
|
|
loads from the code:Input storage class in the fragment shader stage
|
|
with the floating-point result type.
|
|
Other SPIR-V instruction may: also respect the code:DenormPreserve
|
|
execution mode.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
|
|
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, [eq]#x#, rounded so as to be representable in
|
|
floating-point.
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
The rounding mode is not specified, unless the entry point is declared with
|
|
the code:RoundingModeRTE or the code:RoundingModeRTZ execution mode.
|
|
These execution modes affect only correctly rounded SPIR-V instructions.
|
|
These execution modes do not affect code:OpQuantizeToF16.
|
|
If the rounding mode is not specified then this rounding is implementation
|
|
specific, subject to the following rules.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
ifndef::VK_KHR_shader_float_controls[]
|
|
The rounding mode used is not defined but must: obey the following rules.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
If [eq]#x# is exactly representable then [eq]#x# will be returned.
|
|
Otherwise, either the floating-point value closest to and no less than
|
|
[eq]#x# or the value closest to and no greater than [eq]#x# will be
|
|
returned.
|
|
|
|
.ULP
|
|
Where an error bound of [eq]#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
|
|
[eq]#a {leq} x {leq} b# then #ulp(x)# is the minimum possible distance
|
|
between such numbers, latexmath:[ulp(x) = \mathrm{min}_{a,b} | b - a |].
|
|
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 return an infinity 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 [eq]#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 [eq]#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 [eq]#F~max~# and the smallest be [eq]#F~min~#.
|
|
The operation must return a value in the range [eq]#[x - E, x + E]# where
|
|
latexmath:[E = \mathrm{max} \left( | x - F_{\mathrm{min}} |, | x -
|
|
F_{\mathrm{max}} | \right) ].
|
|
ifdef::VK_KHR_shader_float_controls[]
|
|
If the entry point is declared with the code: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 code:DenormPreserve execution mode,
|
|
then denormals must: be preserved throughout the formula.
|
|
endif::VK_KHR_shader_float_controls[]
|
|
|
|
ifdef::VK_KHR_shader_float16_int8[]
|
|
For half- (16 bit) and single- (32 bit) precision instructions, precisions
|
|
are required: to be at least as follows:
|
|
|
|
.Precision of core SPIR-V Instructions
|
|
[options="header", cols=",,"]
|
|
|====
|
|
| Instruction
|
|
| Single precision, unless decorated with RelaxedPrecision | Half precision
|
|
| code:OpFAdd
|
|
2+| Correctly rounded.
|
|
| code:OpFSub
|
|
2+| Correctly rounded.
|
|
| code:OpFMul, code:OpVectorTimesScalar, code:OpMatrixTimesScalar
|
|
2+| Correctly rounded.
|
|
| code:OpDot(x, y)
|
|
2+| Inherited from latexmath:[\sum_{i = 0}^{n - 1} x_{i} \times y_{i}].
|
|
| code:OpFOrdEqual, code:OpFUnordEqual
|
|
2+| Correct result.
|
|
| code:OpFOrdLessThan, code:OpFUnordLessThan
|
|
2+| Correct result.
|
|
| code:OpFOrdGreaterThan, code:OpFUnordGreaterThan
|
|
2+| Correct result.
|
|
| code:OpFOrdLessThanEqual, code:OpFUnordLessThanEqual
|
|
2+| Correct result.
|
|
| code:OpFOrdGreaterThanEqual, code:OpFUnordGreaterThanEqual
|
|
2+| Correct result.
|
|
| code:OpFDiv(x,y)
|
|
| 2.5 ULP for y in the range [2^-126^, 2^126^]. | 2.5 ULP for y in the range [2^-14^, 2^14^].
|
|
| code:OpFRem(x,y)
|
|
| Inherited from [eq]#x - y {times} trunc(x/y)#, for y in the range [2^-126^, 2^126^].
|
|
| Inherited from [eq]#x - y {times} trunc(x/y)#, for y in the range [2^-14^, 2^14^].
|
|
| code:OpFMod(x,y)
|
|
| Inherited from [eq]#x - y {times} floor(x/y)#, for y in the range [2^-126^, 2^126^].
|
|
| Inherited from [eq]#x - y {times} floor(x/y)#, for y in the range [2^-14^, 2^14^].
|
|
| conversions between types
|
|
2+| Correctly rounded.
|
|
|====
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
The code:OpFRem and code: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.
|
|
====
|
|
|
|
.Precision of GLSL.std.450 Instructions
|
|
[options="header", cols=",,"]
|
|
|====
|
|
|Instruction
|
|
| Single precision, unless decorated with RelaxedPrecision | Half precision
|
|
| code:fma()
|
|
2+| Inherited from code:OpFMul followed by code:OpFAdd.
|
|
| code:exp(x), code:exp2(x)
|
|
| [eq]#3 + 2 {times} {vert}x{vert}# ULP. | [eq]#1 + 2 {times} {vert}x{vert}# ULP.
|
|
| code:log(), code:log2()
|
|
| 3 ULP outside the range [eq]#[0.5, 2.0]#. Absolute error < [eq]#2^-21^# inside the range [eq]#[0.5, 2.0]#.
|
|
| 3 ULP outside the range [eq]#[0.5, 2.0]#. Absolute error < [eq]#2^-7^# inside the range [eq]#[0.5, 2.0]#.
|
|
| code:pow(x, y)
|
|
2+| Inherited from code:exp2(y {times} code:log2(x)).
|
|
| code:sqrt()
|
|
2+| Inherited from 1.0 / code:inversesqrt().
|
|
| code:inversesqrt()
|
|
2+| 2 ULP.
|
|
| code:radians(x)
|
|
2+| Inherited from latexmath:[\frac{x \times \pi}{180}].
|
|
| code:degrees(x)
|
|
2+| Inherited from latexmath:[\frac{x \times 180}{\pi}].
|
|
| code:sin()
|
|
| Absolute error latexmath:[\leq 2^{-11}] inside the range latexmath:[[-\pi, \pi\]]. | Absolute error latexmath:[\leq 2^{-7}] inside the range latexmath:[[-\pi, \pi\]].
|
|
| code:cos()
|
|
| Absolute error latexmath:[\leq 2^{-11}] inside the range latexmath:[[-\pi, \pi\]]. | Absolute error latexmath:[\leq 2^{-7}] inside the range latexmath:[[-\pi, \pi\]].
|
|
| code:tan()
|
|
2+| Inherited from latexmath:[\frac{sin()}{cos()}].
|
|
| code:asin(x)
|
|
2+| Inherited from latexmath:[atan2(x, sqrt(1.0 - x^2))].
|
|
| code:acos(x)
|
|
2+| Inherited from latexmath:[atan2(sqrt(1.0 - x^2), x)].
|
|
| code:atan(), code:atan2()
|
|
| 4096 ULP | 5 ULP.
|
|
| code:sinh(x)
|
|
2+| Inherited from latexmath:[(exp(x) - exp(-x)) \times 0.5].
|
|
| code:cosh(x)
|
|
2+| Inherited from latexmath:[(exp(x) + exp(-x)) \times 0.5].
|
|
| code:tanh()
|
|
2+| Inherited from latexmath:[\frac{sinh()}{cosh()}].
|
|
| code:asinh(x)
|
|
2+| Inherited from latexmath:[log(x + sqrt(x^2 + 1.0))].
|
|
| code:acosh(x)
|
|
2+| Inherited from latexmath:[log(x + sqrt(x^2 - 1.0))].
|
|
| code:atanh(x)
|
|
2+| Inherited from latexmath:[log(\frac{1.0 + x}{1.0 - x}) \times 0.5].
|
|
| code:frexp()
|
|
2+| Correctly rounded.
|
|
| code:ldexp()
|
|
2+| Correctly rounded.
|
|
| code:length(x)
|
|
2+| Inherited from latexmath:[sqrt(dot(x, x))].
|
|
| code:distance(x, y)
|
|
2+| Inherited from latexmath:[length(x - y)].
|
|
| code:cross()
|
|
2+| Inherited from [eq]#code:OpFSub(code:OpFMul, code:OpFMul)#.
|
|
| code:normalize(x)
|
|
2+| Inherited from latexmath:[\frac{x}{length(x)}].
|
|
| code:faceforward
|
|
2+| Correctly rounded.
|
|
| code:reflect(x, y)
|
|
2+| Inherited from [eq]#x - 2.0 {times} code:dot(y, x) {times} y#.
|
|
| code:refract(I, N, eta)
|
|
2+| Inherited from [eq]#eta {times} I - (eta {times} code:dot(N, I) + code:sqrt(k)) {times} N#.
|
|
| code:round
|
|
2+| Correctly rounded.
|
|
| code:roundEven
|
|
2+| Correctly rounded.
|
|
| code:trunc
|
|
2+| Correctly rounded.
|
|
| code:fabs
|
|
2+| Correctly rounded.
|
|
| code:fsign
|
|
2+| Correctly rounded.
|
|
| code:floor
|
|
2+| Correctly rounded.
|
|
| code:ceil
|
|
2+| Correctly rounded.
|
|
| code:fract
|
|
2+| Correctly rounded.
|
|
| code:modf
|
|
2+| Correctly rounded.
|
|
| code:fmin
|
|
2+| Correctly rounded.
|
|
| code:fmax
|
|
2+| Correctly rounded.
|
|
| code:fclamp
|
|
2+| Correctly rounded.
|
|
| code:fmix(x, y, a)
|
|
2+| Inherited from [eq]#x {times} (1.0 - a) + y {times} a#.
|
|
| code:step
|
|
2+| Correctly rounded.
|
|
| code:smoothStep(edge0, edge1, x)
|
|
2+| Inherited from [eq]#t {times} t {times} (3.0 - 2.0 {times} t)#,
|
|
where latexmath:[t = clamp(\frac{x - edge0}{edge1 - edge0}, 0.0, 1.0)].
|
|
| code:nmin
|
|
2+| Correctly rounded.
|
|
| code:nmax
|
|
2+| Correctly rounded.
|
|
| code:nclamp
|
|
2+| Correctly rounded.
|
|
|====
|
|
endif::VK_KHR_shader_float16_int8[]
|
|
|
|
ifndef::VK_KHR_shader_float16_int8[]
|
|
For single precision (32 bit) instructions, precisions are required: to be
|
|
at least as follows, unless decorated with RelaxedPrecision:
|
|
|
|
.Precision of core SPIR-V Instructions
|
|
[options="header"]
|
|
|====
|
|
| Instruction | Precision
|
|
| code:OpFAdd | Correctly rounded.
|
|
| code:OpFSub | Correctly rounded.
|
|
| code:OpFMul, code:OpVectorTimesScalar, code:OpMatrixTimesScalar | Correctly rounded.
|
|
| code:OpFOrdEqual, code:OpFUnordEqual | Correct result.
|
|
| code:OpFOrdLessThan, code:OpFUnordLessThan | Correct result.
|
|
| code:OpFOrdGreaterThan, code:OpFUnordGreaterThan | Correct result.
|
|
| code:OpFOrdLessThanEqual, code:OpFUnordLessThanEqual | Correct result.
|
|
| code:OpFOrdGreaterThanEqual, code:OpFUnordGreaterThanEqual | Correct result.
|
|
| code:OpFDiv | 2.5 ULP for b in the range [2^-126^, 2^126^].
|
|
| conversions between types | Correctly rounded.
|
|
|====
|
|
|
|
.Precision of GLSL.std.450 Instructions
|
|
[options="header"]
|
|
|====
|
|
|Instruction | Precision
|
|
| code:fma() | Inherited from code:OpFMul followed by code:OpFAdd.
|
|
| code:exp(x), code:exp2(x) | [eq]#3 {plus} 2 {times} {vert}x{vert}# ULP.
|
|
| code:log(), code:log2() | 3 ULP outside the range [eq]#[0.5, 2.0]#. Absolute error < [eq]#2^-21^# inside the range [eq]#[0.5, 2.0]#.
|
|
| code:pow(x, y) | Inherited from code:exp2(y {times} code:log2(x)).
|
|
| code:sqrt() | Inherited from 1.0 / code:inversesqrt().
|
|
| code:inversesqrt() | 2 ULP.
|
|
|====
|
|
endif::VK_KHR_shader_float16_int8[]
|
|
|
|
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.
|
|
These include, for example, the trigonometric functions and determinant.
|
|
|
|
For the code:OpSRem and code:OpSMod instructions, if either operand is
|
|
negative the result is undefined:.
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
While the code:OpSRem and code:OpSMod instructions are supported by the
|
|
Vulkan environment, they require non-negative values and thus do not enable
|
|
additional functionality beyond what code:OpUMod provides.
|
|
====
|
|
|
|
|
|
[[spirvenv-image-formats]]
|
|
== Compatibility Between SPIR-V Image Formats And Vulkan Formats
|
|
|
|
Images which are read from or written to by shaders must: have SPIR-V image
|
|
formats compatible with the Vulkan image formats backing the image under the
|
|
circumstances described for <<textures-operation-validation,texture image
|
|
validation>>.
|
|
The compatibile formats are:
|
|
|
|
.SPIR-V and Vulkan Image Format Compatibility
|
|
[cols="2*", options="header"]
|
|
|====
|
|
|SPIR-V Image Format |Compatible Vulkan Format
|
|
|code:Rgba32f |ename:VK_FORMAT_R32G32B32A32_SFLOAT
|
|
|code:Rgba16f |ename:VK_FORMAT_R16G16B16A16_SFLOAT
|
|
|code:R32f |ename:VK_FORMAT_R32_SFLOAT
|
|
|code:Rgba8 |ename:VK_FORMAT_R8G8B8A8_UNORM
|
|
|code:Rgba8Snorm |ename:VK_FORMAT_R8G8B8A8_SNORM
|
|
|code:Rg32f |ename:VK_FORMAT_R32G32_SFLOAT
|
|
|code:Rg16f |ename:VK_FORMAT_R16G16_SFLOAT
|
|
|code:R11fG11fB10f |ename:VK_FORMAT_B10G11R11_UFLOAT_PACK32
|
|
|code:R16f |ename:VK_FORMAT_R16_SFLOAT
|
|
|code:Rgba16 |ename:VK_FORMAT_R16G16B16A16_UNORM
|
|
|code:Rgb10A2 |ename:VK_FORMAT_A2B10G10R10_UNORM_PACK32
|
|
|code:Rg16 |ename:VK_FORMAT_R16G16_UNORM
|
|
|code:Rg8 |ename:VK_FORMAT_R8G8_UNORM
|
|
|code:R16 |ename:VK_FORMAT_R16_UNORM
|
|
|code:R8 |ename:VK_FORMAT_R8_UNORM
|
|
|code:Rgba16Snorm |ename:VK_FORMAT_R16G16B16A16_SNORM
|
|
|code:Rg16Snorm |ename:VK_FORMAT_R16G16_SNORM
|
|
|code:Rg8Snorm |ename:VK_FORMAT_R8G8_SNORM
|
|
|code:R16Snorm |ename:VK_FORMAT_R16_SNORM
|
|
|code:R8Snorm |ename:VK_FORMAT_R8_SNORM
|
|
|code:Rgba32i |ename:VK_FORMAT_R32G32B32A32_SINT
|
|
|code:Rgba16i |ename:VK_FORMAT_R16G16B16A16_SINT
|
|
|code:Rgba8i |ename:VK_FORMAT_R8G8B8A8_SINT
|
|
|code:R32i |ename:VK_FORMAT_R32_SINT
|
|
|code:Rg32i |ename:VK_FORMAT_R32G32_SINT
|
|
|code:Rg16i |ename:VK_FORMAT_R16G16_SINT
|
|
|code:Rg8i |ename:VK_FORMAT_R8G8_SINT
|
|
|code:R16i |ename:VK_FORMAT_R16_SINT
|
|
|code:R8i |ename:VK_FORMAT_R8_SINT
|
|
|code:Rgba32ui |ename:VK_FORMAT_R32G32B32A32_UINT
|
|
|code:Rgba16ui |ename:VK_FORMAT_R16G16B16A16_UINT
|
|
|code:Rgba8ui |ename:VK_FORMAT_R8G8B8A8_UINT
|
|
|code:R32ui |ename:VK_FORMAT_R32_UINT
|
|
|code:Rgb10a2ui |ename:VK_FORMAT_A2B10G10R10_UINT_PACK32
|
|
|code:Rg32ui |ename:VK_FORMAT_R32G32_UINT
|
|
|code:Rg16ui |ename:VK_FORMAT_R16G16_UINT
|
|
|code:Rg8ui |ename:VK_FORMAT_R8G8_UINT
|
|
|code:R16ui |ename:VK_FORMAT_R16_UINT
|
|
|code:R8ui |ename:VK_FORMAT_R8_UINT
|
|
|====
|