874 lines
45 KiB
Plaintext
874 lines
45 KiB
Plaintext
// Copyright (c) 2015-2018 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_AMD_gpu_shader_half_float[]
|
|
| code:Float16 | `<<VK_AMD_gpu_shader_half_float>>`
|
|
endif::VK_AMD_gpu_shader_half_float[]
|
|
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_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_NVX_raytracing[]
|
|
[[spirvenv-capabilities-table-raytracing]]
|
|
| code:RaytracingNVX | `<<VK_NVX_raytracing>>`
|
|
endif::VK_NVX_raytracing[]
|
|
ifdef::VK_EXT_transform_feedback[]
|
|
| code:TransformFeedback | <<features-features-transformFeedback,transformFeedback>>
|
|
| code:GeometryStreams | <<features-features-geometryStreams,geometryStreams>>
|
|
endif::VK_EXT_transform_feedback[]
|
|
|====
|
|
|
|
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_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_NVX_raytracing[]
|
|
The application can: pass a SPIR-V module to flink:vkCreateShaderModule that
|
|
uses the `SPV_NVX_raytracing` SPIR-V extension.
|
|
endif::VK_NVX_raytracing[]
|
|
|
|
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[]
|
|
|
|
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[]
|
|
* 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.
|
|
* Any code:OpVariable with an code:Initializer operand must: have one of
|
|
the following as its code:Storage code: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
|
|
** 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[]
|
|
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 vector of double
|
|
types are also permitted.
|
|
* "`Mask`" for code:OpGroupNonUniformShuffleXor must: be a specialization
|
|
constant or a constant, or if the dynamic instance is called within a
|
|
loop construct it must: be one of:
|
|
. A specialization constant.
|
|
. A constant.
|
|
. An arthimetic operation whose operands are 1., 2., or 4.
|
|
. A phi node whose operands are 1., 2., or 3.
|
|
* 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 _Result Type_ and the type of 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 buffers.
|
|
** <<features-features-shaderSharedInt64Atomics,shaderSharedInt64Atomics>>
|
|
must: be enabled for 64-bit integer atomic operations to be supported
|
|
on shared variables.
|
|
endif::VK_KHR_shader_atomic_int64[]
|
|
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_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:XfbOffset
|
|
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[]
|
|
|
|
[[spirvenv-precision-operation]]
|
|
== Precision and Operation of SPIR-V Instructions
|
|
|
|
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.
|
|
|
|
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.
|
|
The rounding mode used is not defined but 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) ].
|
|
|
|
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 | 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.
|
|
|====
|
|
|
|
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
|
|
|====
|