696 lines
35 KiB
Plaintext
Executable File
696 lines
35 KiB
Plaintext
Executable File
// 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>>
|
|
| 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 | <<features-features-shaderStorageImageExtendedFormats,shaderStorageImageExtendedFormats>>
|
|
| 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_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_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[]
|
|
|
|
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*
|
|
** *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_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 for the
|
|
_Result Type_ and the type of the value pointed to by _Pointer_.
|
|
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[]
|
|
|
|
|
|
[[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 is undefined.
|
|
* [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
|
|
|====
|