1// Copyright (c) 2015-2018 Khronos Group. This work is licensed under a 2// Creative Commons Attribution 4.0 International License; see 3// http://creativecommons.org/licenses/by/4.0/ 4 5[appendix] 6[[spirvenv]] 7= Vulkan Environment for SPIR-V 8 9Shaders for Vulkan are defined by the <<spirv-spec,Khronos SPIR-V 10Specification>> as well as the <<spirv-extended,Khronos SPIR-V Extended 11Instructions for GLSL>> Specification. 12This appendix defines additional SPIR-V requirements applying to Vulkan 13shaders. 14 15== Versions and Formats 16 17ifdef::VK_VERSION_1_1[] 18A Vulkan 1.1 implementation must: support the 1.0, 1.1, 1.2, and 1.3 19versions of SPIR-V and the 1.0 version of the SPIR-V Extended Instructions 20for GLSL. 21endif::VK_VERSION_1_1[] 22ifndef::VK_VERSION_1_1[] 23A Vulkan 1.0 implementation must: support the 1.0 version of SPIR-V and the 241.0 version of the SPIR-V Extended Instructions for GLSL. 25endif::VK_VERSION_1_1[] 26 27A SPIR-V module passed into flink:vkCreateShaderModule is interpreted as a 28series of 32-bit words in host endianness, with literal strings packed as 29described in section 2.2 of the SPIR-V Specification. 30The first few words of the SPIR-V module must: be a magic number and a 31SPIR-V version number, as described in section 2.3 of the SPIR-V 32Specification. 33 34 35[[spirvenv-capabilities]] 36== Capabilities 37 38The SPIR-V capabilities listed below must: be supported if the corresponding 39feature or extension is enabled, or if no features or extensions are listed 40for that capability. 41Extensions are only listed when there is not also a feature bit associated 42with that capability. 43 44[[spirvenv-capabilities-table]] 45.List of SPIR-V Capabilities and enabling features or extensions 46[options="header"] 47|==== 48| SPIR-V code:OpCapability | Vulkan feature or extension name 49 50| code:Matrix | 51| code:Shader | 52| code:InputAttachment | 53| code:Sampled1D | 54| code:Image1D | 55| code:SampledBuffer | 56| code:ImageBuffer | 57| code:ImageQuery | 58| code:DerivativeControl | 59| code:Geometry | <<features-features-geometryShader,geometryShader>> 60| code:Tessellation | <<features-features-tessellationShader,tessellationShader>> 61| code:Float64 | <<features-features-shaderFloat64,shaderFloat64>> 62| code:Int64 | <<features-features-shaderInt64,shaderInt64>> 63| code:Int16 | <<features-features-shaderInt16,shaderInt16>> 64| code:TessellationPointSize | <<features-features-shaderTessellationAndGeometryPointSize,shaderTessellationAndGeometryPointSize>> 65| code:GeometryPointSize | <<features-features-shaderTessellationAndGeometryPointSize,shaderTessellationAndGeometryPointSize>> 66| code:ImageGatherExtended | <<features-features-shaderImageGatherExtended,shaderImageGatherExtended>> 67| code:StorageImageMultisample | <<features-features-shaderStorageImageMultisample,shaderStorageImageMultisample>> 68| code:UniformBufferArrayDynamicIndexing | <<features-features-shaderUniformBufferArrayDynamicIndexing,shaderUniformBufferArrayDynamicIndexing>> 69| code:SampledImageArrayDynamicIndexing | <<features-features-shaderSampledImageArrayDynamicIndexing,shaderSampledImageArrayDynamicIndexing>> 70| code:StorageBufferArrayDynamicIndexing | <<features-features-shaderStorageBufferArrayDynamicIndexing,shaderStorageBufferArrayDynamicIndexing>> 71| code:StorageImageArrayDynamicIndexing | <<features-features-shaderStorageImageArrayDynamicIndexing,shaderStorageImageArrayDynamicIndexing>> 72| code:ClipDistance | <<features-features-shaderClipDistance,shaderClipDistance>> 73| code:CullDistance | <<features-features-shaderCullDistance,shaderCullDistance>> 74| code:ImageCubeArray | <<features-features-imageCubeArray,imageCubeArray>> 75| code:SampleRateShading | <<features-features-sampleRateShading,sampleRateShading>> 76| code:SparseResidency | <<features-features-shaderResourceResidency,shaderResourceResidency>> 77| code:MinLod | <<features-features-shaderResourceMinLod,shaderResourceMinLod>> 78| code:SampledCubeArray | <<features-features-imageCubeArray,imageCubeArray>> 79| code:ImageMSArray | <<features-features-shaderStorageImageMultisample,shaderStorageImageMultisample>> 80| code:StorageImageExtendedFormats | <<features-features-shaderStorageImageExtendedFormats,shaderStorageImageExtendedFormats>> 81| code:InterpolationFunction | <<features-features-sampleRateShading,sampleRateShading>> 82| code:StorageImageReadWithoutFormat | <<features-features-shaderStorageImageReadWithoutFormat,shaderStorageImageReadWithoutFormat>> 83| code:StorageImageWriteWithoutFormat | <<features-features-shaderStorageImageWriteWithoutFormat,shaderStorageImageWriteWithoutFormat>> 84| code:MultiViewport | <<features-features-multiViewport,multiViewport>> 85ifdef::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[] 86| code:DrawParameters | 87ifdef::VK_VERSION_1_1[] 88<<features-features-shaderDrawParameters,shaderDrawParameters>> 89endif::VK_VERSION_1_1[] 90ifdef::VK_KHR_shader_draw_parameters+VK_VERSION_1_1[] 91or 92endif::VK_KHR_shader_draw_parameters+VK_VERSION_1_1[] 93ifdef::VK_KHR_shader_draw_parameters[] 94<<VK_KHR_shader_draw_parameters>> 95endif::VK_KHR_shader_draw_parameters[] 96endif::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[] 97ifdef::VK_VERSION_1_1,VK_KHR_multiview[] 98[[spirvenv-capabilities-multiview]] 99| code:MultiView | 100ifndef::VK_VERSION_1_1[] 101<<VK_KHR_multiview,VK_KHR_multiview>> 102endif::VK_VERSION_1_1[] 103endif::VK_VERSION_1_1,VK_KHR_multiview[] 104ifdef::VK_VERSION_1_1,VK_KHR_device_group[] 105| code:DeviceGroup | 106ifndef::VK_VERSION_1_1[] 107<<VK_KHR_device_group,VK_KHR_device_group>> 108endif::VK_VERSION_1_1[] 109endif::VK_VERSION_1_1,VK_KHR_device_group[] 110ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers[] 111[[spirvenv-capabilities-table-variablepointers]] 112| code:VariablePointersStorageBuffer | <<features-features-variablePointersStorageBuffer,variablePointersStorageBuffer>> 113| code:VariablePointers | <<features-features-variablePointers,variablePointers>> 114endif::VK_VERSION_1_1,VK_KHR_variable_pointers[] 115ifdef::VK_EXT_shader_stencil_export[] 116[[spirvenv-capabilities-table-shaderstencilexportext]] 117| code:StencilExportEXT | `<<VK_EXT_shader_stencil_export>>` 118endif::VK_EXT_shader_stencil_export[] 119ifdef::VK_EXT_shader_subgroup_ballot[] 120[[spirvenv-capabilities-table-subgroupballot]] 121| code:SubgroupBallotKHR | `<<VK_EXT_shader_subgroup_ballot>>` 122endif::VK_EXT_shader_subgroup_ballot[] 123ifdef::VK_EXT_shader_subgroup_vote[] 124[[spirvenv-capabilities-table-subgroupvote]] 125| code:SubgroupVoteKHR | `<<VK_EXT_shader_subgroup_vote>>` 126endif::VK_EXT_shader_subgroup_vote[] 127ifdef::VK_AMD_shader_image_load_store_lod[] 128[[spirvenv-capabilities-table-imagereadwritelodamd]] 129| code:ImageReadWriteLodAMD | `<<VK_AMD_shader_image_load_store_lod>>` 130endif::VK_AMD_shader_image_load_store_lod[] 131ifdef::VK_AMD_texture_gather_bias_lod[] 132[[spirvenv-capabilities-table-imagegatherbiaslodamd]] 133| code:ImageGatherBiasLodAMD | `<<VK_AMD_texture_gather_bias_lod>>` 134endif::VK_AMD_texture_gather_bias_lod[] 135ifdef::VK_AMD_shader_fragment_mask[] 136[[spirvenv-capabilities-table-fragmentmaskamd]] 137| code:FragmentMaskAMD | `<<VK_AMD_shader_fragment_mask>>` 138endif::VK_AMD_shader_fragment_mask[] 139ifdef::VK_NV_sample_mask_override_coverage[] 140[[spirvenv-capabilities-table-samplemaskoverridecoverage]] 141| code:SampleMaskOverrideCoverageNV | `<<VK_NV_sample_mask_override_coverage>>` 142endif::VK_NV_sample_mask_override_coverage[] 143ifdef::VK_NV_geometry_shader_passthrough[] 144[[spirvenv-capabilities-table-geometryshaderpassthrough]] 145| code:GeometryShaderPassthroughNV | `<<VK_NV_geometry_shader_passthrough>>` 146endif::VK_NV_geometry_shader_passthrough[] 147ifdef::VK_EXT_shader_viewport_index_layer[] 148[[spirvenv-capabilities-table-shader-viewport-index-layer]] 149| code:ShaderViewportIndexLayerEXT | `<<VK_EXT_shader_viewport_index_layer>>` 150endif::VK_EXT_shader_viewport_index_layer[] 151ifdef::VK_NV_viewport_array2[] 152[[spirvenv-capabilities-table-viewportarray2]] 153| code:ShaderViewportIndexLayerNV | `<<VK_NV_viewport_array2>>` 154| code:ShaderViewportMaskNV | `<<VK_NV_viewport_array2>>` 155endif::VK_NV_viewport_array2[] 156ifdef::VK_NVX_multiview_per_view_attributes[] 157[[spirvenv-capabilities-table-perviewattributes]] 158| code:PerViewAttributesNV | `<<VK_NVX_multiview_per_view_attributes>>` 159endif::VK_NVX_multiview_per_view_attributes[] 160ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[] 161[[spirvenv-capabilities-table-16bitstorage]] 162| code:StorageBuffer16BitAccess | <<features-features-storageBuffer16BitAccess, StorageBuffer16BitAccess>> 163| code:UniformAndStorageBuffer16BitAccess | <<features-features-uniformAndStorageBuffer16BitAccess,UniformAndStorageBuffer16BitAccess>> 164| code:StoragePushConstant16 | <<features-features-storagePushConstant16,storagePushConstant16>> 165| code:StorageInputOutput16 | <<features-features-storageInputOutput16,storageInputOutput16>> 166endif::VK_VERSION_1_1,VK_KHR_16bit_storage[] 167ifdef::VK_VERSION_1_1[] 168[[spirvenv-capabilities-table-subgroup]] 169| code:GroupNonUniform | <<features-features-subgroup-basic,VK_SUBGROUP_FEATURE_BASIC_BIT>> 170| code:GroupNonUniformVote | <<features-features-subgroup-vote,VK_SUBGROUP_FEATURE_VOTE_BIT>> 171| code:GroupNonUniformArithmetic | <<features-features-subgroup-arithmetic,VK_SUBGROUP_FEATURE_ARITHMETIC_BIT>> 172| code:GroupNonUniformBallot | <<features-features-subgroup-ballot,VK_SUBGROUP_FEATURE_BALLOT_BIT>> 173| code:GroupNonUniformShuffle | <<features-features-subgroup-shuffle,VK_SUBGROUP_FEATURE_SHUFFLE_BIT>> 174| code:GroupNonUniformShuffleRelative | <<features-features-subgroup-shuffle-relative,VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT>> 175| code:GroupNonUniformClustered | <<features-features-subgroup-clustered,VK_SUBGROUP_FEATURE_CLUSTERED_BIT>> 176| code:GroupNonUniformQuad | <<features-features-subgroup-quad,VK_SUBGROUP_FEATURE_QUAD_BIT>> 177ifdef::VK_NV_shader_subgroup_partitioned[] 178| code:GroupNonUniformPartitionedNV | <<features-features-subgroup-partitioned,VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV>> 179endif::VK_NV_shader_subgroup_partitioned[] 180endif::VK_VERSION_1_1[] 181ifdef::VK_EXT_post_depth_coverage[] 182[[spirvenv-capabilities-table-postdepthcoverage]] 183| code:SampleMaskPostDepthCoverage | `<<VK_EXT_post_depth_coverage>>` 184endif::VK_EXT_post_depth_coverage[] 185ifdef::VK_EXT_descriptor_indexing[] 186[[spirvenv-capabilities-table-descriptorindexing]] 187| code:ShaderNonUniformEXT | `<<VK_EXT_descriptor_indexing>>` 188| code:RuntimeDescriptorArrayEXT | <<features-features-runtimeDescriptorArray,runtimeDescriptorArray>> 189| code:InputAttachmentArrayDynamicIndexingEXT | <<features-features-shaderInputAttachmentArrayDynamicIndexing,shaderInputAttachmentArrayDynamicIndexing>> 190| code:UniformTexelBufferArrayDynamicIndexingEXT | <<features-features-shaderUniformTexelBufferArrayDynamicIndexing,shaderUniformTexelBufferArrayDynamicIndexing>> 191| code:StorageTexelBufferArrayDynamicIndexingEXT | <<features-features-shaderStorageTexelBufferArrayDynamicIndexing,shaderStorageTexelBufferArrayDynamicIndexing>> 192| code:UniformBufferArrayNonUniformIndexingEXT | <<features-features-shaderUniformBufferArrayNonUniformIndexing,shaderUniformBufferArrayNonUniformIndexing>> 193| code:SampledImageArrayNonUniformIndexingEXT | <<features-features-shaderSampledImageArrayNonUniformIndexing,shaderSampledImageArrayNonUniformIndexing>> 194| code:StorageBufferArrayNonUniformIndexingEXT | <<features-features-shaderStorageBufferArrayNonUniformIndexing,shaderStorageBufferArrayNonUniformIndexing>> 195| code:StorageImageArrayNonUniformIndexingEXT | <<features-features-shaderStorageImageArrayNonUniformIndexing,shaderStorageImageArrayNonUniformIndexing>> 196| code:InputAttachmentArrayNonUniformIndexingEXT | <<features-features-shaderInputAttachmentArrayNonUniformIndexing,shaderInputAttachmentArrayNonUniformIndexing>> 197| code:UniformTexelBufferArrayNonUniformIndexingEXT | <<features-features-shaderUniformTexelBufferArrayNonUniformIndexing,shaderUniformTexelBufferArrayNonUniformIndexing>> 198| code:StorageTexelBufferArrayNonUniformIndexingEXT | <<features-features-shaderStorageTexelBufferArrayNonUniformIndexing,shaderStorageTexelBufferArrayNonUniformIndexing>> 199endif::VK_EXT_descriptor_indexing[] 200ifdef::VK_AMD_gpu_shader_half_float[] 201| code:Float16 | `<<VK_AMD_gpu_shader_half_float>>` 202endif::VK_AMD_gpu_shader_half_float[] 203ifdef::VK_KHR_8bit_storage[] 204[[spirvenv-capabilities-table-8bitstorage]] 205| code:StorageBuffer8BitAccess | <<features-features-storageBuffer8BitAccess,StorageBuffer8BitAccess>> 206| code:UniformAndStorageBuffer8BitAccess | <<features-features-uniformAndStorageBuffer8BitAccess,UniformAndStorageBuffer8BitAccess>> 207| code:StoragePushConstant8 | <<features-features-storagePushConstant8,StoragePushConstant8>> 208endif::VK_KHR_8bit_storage[] 209|==== 210 211ifdef::VK_VERSION_1_1,VK_KHR_variable_pointers[] 212The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 213uses the `SPV_KHR_variable_pointers` SPIR-V extension. 214endif::VK_VERSION_1_1,VK_KHR_variable_pointers[] 215 216ifdef::VK_AMD_shader_explicit_vertex_parameter[] 217The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 218uses the `SPV_AMD_shader_explicit_vertex_parameter` SPIR-V extension. 219endif::VK_AMD_shader_explicit_vertex_parameter[] 220 221ifdef::VK_AMD_gcn_shader[] 222The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 223uses the `SPV_AMD_gcn_shader` SPIR-V extension. 224endif::VK_AMD_gcn_shader[] 225 226ifdef::VK_AMD_gpu_shader_half_float[] 227The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 228uses the `SPV_AMD_gpu_shader_half_float` SPIR-V extension. 229endif::VK_AMD_gpu_shader_half_float[] 230 231ifdef::VK_AMD_gpu_shader_int16[] 232The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 233uses the `SPV_AMD_gpu_shader_int16` SPIR-V extension. 234endif::VK_AMD_gpu_shader_int16[] 235 236ifdef::VK_AMD_shader_ballot[] 237The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 238uses the `SPV_AMD_shader_ballot` SPIR-V extension. 239endif::VK_AMD_shader_ballot[] 240 241ifdef::VK_AMD_shader_fragment_mask[] 242The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 243uses the `SPV_AMD_shader_fragment_mask` SPIR-V extension. 244endif::VK_AMD_shader_fragment_mask[] 245 246ifdef::VK_AMD_shader_image_load_store_lod[] 247The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 248uses the `SPV_AMD_shader_image_load_store_lod` SPIR-V extension. 249endif::VK_AMD_shader_image_load_store_lod[] 250 251ifdef::VK_AMD_shader_trinary_minmax[] 252The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 253uses the `SPV_AMD_shader_trinary_minmax` SPIR-V extension. 254endif::VK_AMD_shader_trinary_minmax[] 255 256ifdef::VK_AMD_texture_gather_bias_lod[] 257The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 258uses the `SPV_AMD_texture_gather_bias_lod` SPIR-V extension. 259endif::VK_AMD_texture_gather_bias_lod[] 260 261ifdef::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[] 262The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 263uses the `SPV_KHR_shader_draw_parameters` SPIR-V extension. 264endif::VK_VERSION_1_1,VK_KHR_shader_draw_parameters[] 265 266ifdef::VK_KHR_8bit_storage[] 267The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 268uses the +SPV_KHR_8bit_storage+ SPIR-V extension. 269endif::VK_KHR_8bit_storage[] 270 271ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[] 272The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 273uses the 274https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_16bit_storage.html[`SPV_KHR_16bit_storage`] 275SPIR-V extension. 276endif::VK_VERSION_1_1,VK_KHR_16bit_storage[] 277 278ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 279The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 280uses the 281https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_storage_buffer_storage_class.html[`SPV_KHR_storage_buffer_storage_class`] 282SPIR-V extension. 283endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 284 285ifdef::VK_EXT_post_depth_coverage[] 286The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 287uses the `SPV_KHR_post_depth_coverage` SPIR-V extension. 288endif::VK_EXT_post_depth_coverage[] 289 290ifdef::VK_EXT_shader_stencil_export[] 291The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 292uses the `SPV_EXT_shader_stencil_export` SPIR-V extension. 293endif::VK_EXT_shader_stencil_export[] 294 295ifdef::VK_EXT_shader_subgroup_ballot[] 296The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 297uses the `SPV_KHR_shader_ballot` SPIR-V extension. 298endif::VK_EXT_shader_subgroup_ballot[] 299 300ifdef::VK_EXT_shader_subgroup_vote[] 301The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 302uses the `SPV_KHR_subgroup_vote` SPIR-V extension. 303endif::VK_EXT_shader_subgroup_vote[] 304 305ifdef::VK_NV_sample_mask_override_coverage[] 306The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 307uses the `SPV_NV_sample_mask_override_coverage` SPIR-V extension. 308endif::VK_NV_sample_mask_override_coverage[] 309 310ifdef::VK_NV_geometry_shader_passthrough[] 311The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 312uses the `SPV_NV_geometry_shader_passthrough` SPIR-V extension. 313endif::VK_NV_geometry_shader_passthrough[] 314 315ifdef::VK_NV_viewport_array2[] 316The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 317uses the `SPV_NV_viewport_array2` SPIR-V extension. 318endif::VK_NV_viewport_array2[] 319 320ifdef::VK_EXT_shader_viewport_index_layer[] 321The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 322uses the `SPV_EXT_shader_viewport_index_layer` SPIR-V extension. 323endif::VK_EXT_shader_viewport_index_layer[] 324 325ifdef::VK_NVX_multiview_per_view_attributes[] 326The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 327uses the `SPV_NVX_multiview_per_view_attributes` SPIR-V extension. 328endif::VK_NVX_multiview_per_view_attributes[] 329 330ifdef::VK_EXT_descriptor_indexing[] 331The application can: pass a SPIR-V module to flink:vkCreateShaderModule that 332uses the +SPV_EXT_descriptor_indexing+ SPIR-V extension. 333endif::VK_EXT_descriptor_indexing[] 334 335The application must: not pass a SPIR-V module containing any of the 336following to flink:vkCreateShaderModule: 337 338 * any OpCapability not listed above, 339 * an unsupported capability, or 340 * a capability which corresponds to a Vulkan feature or extension which 341 has not been enabled. 342 343 344[[spirvenv-module-validation]] 345== Validation Rules within a Module 346 347A SPIR-V module passed to flink:vkCreateShaderModule must: conform to the 348following rules: 349 350 * Every entry point must: have no return value and accept no arguments. 351 * Recursion: The static function-call graph for an entry point must: not 352 contain cycles. 353 * The *Logical* addressing model must: be selected. 354 * *Scope* for execution must: be limited to: 355 ** *Workgroup* 356 ** *Subgroup* 357 * *Scope* for memory must: be limited to: 358 ** *Device* 359 ** *Workgroup* 360ifdef::VK_VERSION_1_1[] 361 ** *Subgroup* 362endif::VK_VERSION_1_1[] 363 ** *Invocation* 364ifdef::VK_VERSION_1_1[] 365 * *Scope* for *Non Uniform Group Operations* must: be limited to: 366 ** *Subgroup* 367endif::VK_VERSION_1_1[] 368 * *Storage Class* must: be limited to: 369 ** *UniformConstant* 370 ** *Input* 371 ** *Uniform* 372 ** *Output* 373 ** *Workgroup* 374 ** *Private* 375 ** *Function* 376 ** *PushConstant* 377 ** *Image* 378ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 379 ** *StorageBuffer* 380endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 381 * Memory semantics must: obey the following rules: 382 ** *Acquire* must: not be used with code:OpAtomicStore. 383 ** *Release* must: not be used with code:OpAtomicLoad. 384 ** *AcquireRelease* must: not be used with code:OpAtomicStore or 385 code:OpAtomicLoad. 386 ** Sequentially consistent atomics and barriers are not supported and 387 *SequentiallyConsistent* is treated as *AcquireRelease*. 388 *SequentiallyConsistent* should: not be used. 389 ** code:OpMemoryBarrier must: use one of *Acquire*, *Release*, 390 *AcquireRelease*, or *SequentiallyConsistent* and must: include at 391 least one storage class. 392 ** If the semantics for code:OpControlBarrier includes one of *Acquire*, 393 *Release*, *AcquireRelease*, or *SequentiallyConsistent*, then it must: 394 include at least one storage class. 395 ** *SubgroupMemory*, *CrossWorkgroupMemory*, and *AtomicCounterMemory* are 396 ignored. 397 * Any code:OpVariable with an code:Initializer operand must: have one of 398 the following as its code:Storage code:Class operand: 399 ** *Output* 400 ** *Private* 401 ** *Function* 402 * The code:OriginLowerLeft execution mode must: not be used; fragment 403 entry points must: declare code:OriginUpperLeft. 404 * The code:PixelCenterInteger execution mode must: not be used. 405 Pixels are always centered at half-integer coordinates. 406 * Images and Samplers 407 ** code:OpTypeImage must: declare a scalar 32-bit float or 32-bit integer 408 type for the "`Sampled Type`". 409 (code:RelaxedPrecision can: be applied to a sampling instruction and to 410 the variable holding the result of a sampling instruction.) 411 ** code:OpTypeImage must: have a "`Sampled`" operand of 1 (sampled image) 412 or 2 (storage image). 413 ** If 414 <<features-features-shaderStorageImageReadWithoutFormat,shaderStorageImageReadWithoutFormat>> 415 is not enabled and an code:OpTypeImage has "`Image Format`" operand of 416 code:Unknown, any variables created with the given type must be 417 decorated with code:NonReadable. 418 ** If 419 <<features-features-shaderStorageImageWriteWithoutFormat,shaderStorageImageWriteWithoutFormat>> 420 is not enabled and an code:OpTypeImage has "`Image Format`" operand of 421 code:Unknown, any variables created with the given type must be 422 decorated with code:NonWritable. 423 ** code:OpImageQuerySizeLod, and code:OpImageQueryLevels must: only 424 consume an "`Image`" operand whose type has its "`Sampled`" operand set 425 to 1. 426 ** The [eq]#(u,v)# coordinates used for a code:SubpassData must: be the 427 <id> of a constant vector [eq]#(0,0)#, or if a layer coordinate is 428 used, must: be a vector that was formed with constant 0 for the [eq]#u# 429 and [eq]#v# components. 430 ** The "`Depth`" operand of code:OpTypeImage is ignored. 431 ** Objects of types code:OpTypeImage, code:OpTypeSampler, 432 code:OpTypeSampledImage, and arrays of these types must: not be stored 433 to or modified. 434 * Decorations 435 ** The code:GLSLShared and code:GLSLPacked decorations must: not be used. 436 ** The code:Flat, code:NoPerspective, code:Sample, and code:Centroid 437 decorations must: not be used on variables with storage class other 438 than code:Input or on variables used in the interface of non-fragment 439 shader entry points. 440 ** The code:Patch decoration must: not be used on variables in the 441 interface of a vertex, geometry, or fragment shader stage's entry 442 point. 443ifdef::VK_NV_viewport_array2[] 444 ** The code:ViewportRelativeNV decoration must: only be used on a variable 445 decorated with code:Layer in the vertex, tessellation evaluation, or 446 geometry shader stages. 447 ** The code:ViewportRelativeNV decoration must: not be used unless a 448 variable decorated with one of code:ViewportIndex or 449 code:ViewportMaskNV is also statically used by the same 450 code:OpEntryPoint. 451 ** The code:ViewportMaskNV and code:ViewportIndex decorations must: not 452 both be statically used by one or more code:OpEntryPoint's that form 453 the vertex processing stages of a graphics pipeline. 454endif::VK_NV_viewport_array2[] 455ifdef::VK_VERSION_1_1,VK_KHR_16bit_storage[] 456 ** Only the round-to-nearest-even and the round-to-zero rounding modes 457 can: be used for the code:FPRoundingMode decoration. 458 ** The code:FPRoundingMode decoration can: only be used for the 459 floating-point conversion instructions as described in the 460 https://www.khronos.org/registry/spir-v/extensions/KHR/SPV_KHR_16bit_storage.html[`SPV_KHR_16bit_storage`] 461 SPIR-V extension. 462endif::VK_VERSION_1_1,VK_KHR_16bit_storage[] 463 ** code:DescriptorSet and code:Binding decorations must: obey the 464 constraints on storage class, type, and descriptor type described in 465 <<interfaces-resources-setandbinding,DescriptorSet and Binding 466 Assignment>> 467 * code:OpTypeRuntimeArray must: only be used for: 468 ** the last member of an code:OpTypeStruct 469ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 470 that is in the code:StorageBuffer storage class decorated as 471 code:Block, or 472endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 473 that is in the code:Uniform storage class decorated as 474 code:BufferBlock. 475ifdef::VK_EXT_descriptor_indexing[] 476 ** If the code:RuntimeDescriptorArrayEXT capability is supported, an array 477 of variables with storage class code:Uniform, 478ifdef::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 479 code:StorageBuffer, 480endif::VK_VERSION_1_1,VK_KHR_storage_buffer_storage_class[] 481 or code:UniformConstant, or for the outermost dimension of an array of 482 arrays of such variables. 483endif::VK_EXT_descriptor_indexing[] 484 * Linkage: See <<interfaces,Shader Interfaces>> for additional linking and 485 validation rules. 486ifdef::VK_VERSION_1_1[] 487 * If code:OpControlBarrier is used in fragment, vertex, tessellation 488 evaluation, or geometry stages, the execution Scope must: be 489 code:Subgroup. 490endif::VK_VERSION_1_1[] 491 * Compute Shaders 492 ** For each compute shader entry point, either a code:LocalSize execution 493 mode or an object decorated with the code:WorkgroupSize decoration 494 must: be specified. 495ifdef::VK_VERSION_1_1[] 496 * "`Result Type`" for *Non Uniform Group Operations* must: be limited to 497 32-bit float, 32-bit integer, boolean, or vectors of these types. 498 If the code:Float64 capability is enabled, double and vector of double 499 types are also permitted. 500 * "`Mask`" for code:OpGroupNonUniformShuffleXor must: be a specialization 501 constant or a constant, or if the dynamic instance is called within a 502 loop construct it must: be one of: 503 . A specialization constant. 504 . A constant. 505 . An arthimetic operation whose operands are 1., 2., or 4. 506 . A phi node whose operands are 1., 2., or 3. 507 * If code:OpGroupNonUniformBallotBitCount is used, the group operation 508 must: be one of: 509 ** *Reduce* 510 ** *InclusiveScan* 511 ** *ExclusiveScan* 512endif::VK_VERSION_1_1[] 513 * Atomic instructions must: declare a scalar 32-bit integer type for the 514 _Result Type_ and the type of the value pointed to by _Pointer_. 515ifdef::VK_EXT_descriptor_indexing[] 516 * If an instruction loads from or stores to a resource (including atomics 517 and image instructions) and the resource descriptor being accessed is 518 not dynamically uniform, then the operand corresponding to that resource 519 (e.g. the pointer or sampled image operand) must: be decorated with 520 code:NonUniformEXT. 521endif::VK_EXT_descriptor_indexing[] 522 523 524[[spirvenv-precision-operation]] 525== Precision and Operation of SPIR-V Instructions 526 527The following rules apply to both single and double-precision floating point 528instructions: 529 530 * Positive and negative infinities and positive and negative zeros are 531 generated as dictated by <<ieee-754,IEEE 754>>, but subject to the 532 precisions allowed in the following table. 533 * Dividing a non-zero by a zero results in the appropriately signed 534 <<ieee-754,IEEE 754>> infinity. 535 * Any denormalized value input into a shader or potentially generated by 536 any instruction in a shader may: be flushed to 0. 537 * The rounding mode cannot: be set and is undefined. 538 * [eq]##NaN##s may: not be generated. 539 Instructions that operate on a [eq]#NaN# may: not result in a [eq]#NaN#. 540 * Support for signaling [eq]##NaN##s is optional: and exceptions are never 541 raised. 542 543The precision of double-precision instructions is at least that of single 544precision. 545 546The precision of operations is defined either in terms of rounding, as an 547error bound in ULP, or as inherited from a formula as follows. 548 549.Correctly Rounded 550Operations described as "correctly rounded" will return the infinitely 551precise result, [eq]#x#, rounded so as to be representable in 552floating-point. 553The rounding mode used is not defined but if [eq]#x# is exactly 554representable then [eq]#x# will be returned. 555Otherwise, either the floating-point value closest to and no less than 556[eq]#x# or the value closest to and no greater than [eq]#x# will be 557returned. 558 559.ULP 560Where an error bound of [eq]#n# ULP (units in the last place) is given, for 561an operation with infinitely precise result #x# the value returned must be 562in the range #[x - n * ulp(x), x + n * ulp(x)]#. 563The function #ulp(x)# is defined as follows: 564 565 :: If there exist non-equal floating-point numbers #a# and #b# such that 566[eq]#a {leq} x {leq} b# then #ulp(x)# is the minimum possible distance 567between such numbers, latexmath:[ulp(x) = \mathrm{min}_{a,b} | b - a |]. 568If such numbers do not exist then #ulp(x)# is defined to be the difference 569between the two finite floating-point numbers nearest to #x#. 570 571Where the range of allowed return values includes any value of magnitude 572larger than that of the largest representable finite floating-point number, 573operations may return an infinity of the appropriate sign. 574If the infinitely precise result of the operation is not mathematically 575defined then the value returned is undefined. 576 577.Inherited From ... 578Where an operation's precision is described as being inherited from a 579formula, the result returned must be at least as accurate as the result of 580computing an approximation to [eq]#x# using a formula equivalent to the 581given formula applied to the supplied inputs. 582Specifically, the formula given may be transformed using the mathematical 583associativity, commutativity and distributivity of the operators involved to 584yield an equivalent formula. 585The SPIR-V precision rules, when applied to each such formula and the given 586input values, define a range of permitted values. 587If [eq]#NaN# is one of the permitted values then the operation may return 588any result, otherwise let the largest permitted value in any of the ranges 589be [eq]#F~max~# and the smallest be [eq]#F~min~#. 590The operation must return a value in the range [eq]#[x - E, x + E]# where 591latexmath:[E = \mathrm{max} \left( | x - F_{\mathrm{min}} |, | x - 592F_{\mathrm{max}} | \right) ] 593 594For single precision (32 bit) instructions, precisions are required: to be 595at least as follows, unless decorated with RelaxedPrecision: 596 597.Precision of core SPIR-V Instructions 598[options="header"] 599|==== 600| Instruction | Precision 601| code:OpFAdd | Correctly rounded. 602| code:OpFSub | Correctly rounded. 603| code:OpFMul | Correctly rounded. 604| code:OpFOrdEqual, code:OpFUnordEqual | Correct result. 605| code:OpFOrdLessThan, code:OpFUnordLessThan | Correct result. 606| code:OpFOrdGreaterThan, code:OpFUnordGreaterThan | Correct result. 607| code:OpFOrdLessThanEqual, code:OpFUnordLessThanEqual | Correct result. 608| code:OpFOrdGreaterThanEqual, code:OpFUnordGreaterThanEqual| Correct result. 609| code:OpFDiv | 2.5 ULP for b in the range [2^-126^, 2^126^]. 610| conversions between types | Correctly rounded. 611|==== 612 613.Precision of GLSL.std.450 Instructions 614[options="header"] 615|==== 616|Instruction | Precision 617| code:fma() | Inherited from code:OpFMul followed by code:OpFAdd. 618| code:exp(x), code:exp2(x) | [eq]#3 {plus} 2 {times} {vert}x{vert}# ULP. 619| 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]#. 620| code:pow(x, y) | Inherited from code:exp2(y {times} code:log2(x)). 621| code:sqrt() | Inherited from 1.0 / code:inversesqrt(). 622| code:inversesqrt() | 2 ULP. 623|==== 624 625GLSL.std.450 extended instructions specifically defined in terms of the 626above instructions inherit the above errors. 627GLSL.std.450 extended instructions not listed above and not defined in terms 628of the above have undefined precision. 629These include, for example, the trigonometric functions and determinant. 630 631For the code:OpSRem and code:OpSMod instructions, if either operand is 632negative the result is undefined. 633 634[NOTE] 635.Note 636==== 637While the code:OpSRem and code:OpSMod instructions are supported by the 638Vulkan environment, they require non-negative values and thus do not enable 639additional functionality beyond what code:OpUMod provides. 640==== 641 642 643[[spirvenv-image-formats]] 644== Compatibility Between SPIR-V Image Formats And Vulkan Formats 645 646Images which are read from or written to by shaders must: have SPIR-V image 647formats compatible with the Vulkan image formats backing the image under the 648circumstances described for <<textures-operation-validation,texture image 649validation>>. 650The compatibile formats are: 651 652.SPIR-V and Vulkan Image Format Compatibility 653[cols="2*", options="header"] 654|==== 655|SPIR-V Image Format |Compatible Vulkan Format 656|code:Rgba32f |ename:VK_FORMAT_R32G32B32A32_SFLOAT 657|code:Rgba16f |ename:VK_FORMAT_R16G16B16A16_SFLOAT 658|code:R32f |ename:VK_FORMAT_R32_SFLOAT 659|code:Rgba8 |ename:VK_FORMAT_R8G8B8A8_UNORM 660|code:Rgba8Snorm |ename:VK_FORMAT_R8G8B8A8_SNORM 661|code:Rg32f |ename:VK_FORMAT_R32G32_SFLOAT 662|code:Rg16f |ename:VK_FORMAT_R16G16_SFLOAT 663|code:R11fG11fB10f |ename:VK_FORMAT_B10G11R11_UFLOAT_PACK32 664|code:R16f |ename:VK_FORMAT_R16_SFLOAT 665|code:Rgba16 |ename:VK_FORMAT_R16G16B16A16_UNORM 666|code:Rgb10A2 |ename:VK_FORMAT_A2B10G10R10_UNORM_PACK32 667|code:Rg16 |ename:VK_FORMAT_R16G16_UNORM 668|code:Rg8 |ename:VK_FORMAT_R8G8_UNORM 669|code:R16 |ename:VK_FORMAT_R16_UNORM 670|code:R8 |ename:VK_FORMAT_R8_UNORM 671|code:Rgba16Snorm |ename:VK_FORMAT_R16G16B16A16_SNORM 672|code:Rg16Snorm |ename:VK_FORMAT_R16G16_SNORM 673|code:Rg8Snorm |ename:VK_FORMAT_R8G8_SNORM 674|code:R16Snorm |ename:VK_FORMAT_R16_SNORM 675|code:R8Snorm |ename:VK_FORMAT_R8_SNORM 676|code:Rgba32i |ename:VK_FORMAT_R32G32B32A32_SINT 677|code:Rgba16i |ename:VK_FORMAT_R16G16B16A16_SINT 678|code:Rgba8i |ename:VK_FORMAT_R8G8B8A8_SINT 679|code:R32i |ename:VK_FORMAT_R32_SINT 680|code:Rg32i |ename:VK_FORMAT_R32G32_SINT 681|code:Rg16i |ename:VK_FORMAT_R16G16_SINT 682|code:Rg8i |ename:VK_FORMAT_R8G8_SINT 683|code:R16i |ename:VK_FORMAT_R16_SINT 684|code:R8i |ename:VK_FORMAT_R8_SINT 685|code:Rgba32ui |ename:VK_FORMAT_R32G32B32A32_UINT 686|code:Rgba16ui |ename:VK_FORMAT_R16G16B16A16_UINT 687|code:Rgba8ui |ename:VK_FORMAT_R8G8B8A8_UINT 688|code:R32ui |ename:VK_FORMAT_R32_UINT 689|code:Rgb10a2ui |ename:VK_FORMAT_A2B10G10R10_UINT_PACK32 690|code:Rg32ui |ename:VK_FORMAT_R32G32_UINT 691|code:Rg16ui |ename:VK_FORMAT_R16G16_UINT 692|code:Rg8ui |ename:VK_FORMAT_R8G8_UINT 693|code:R16ui |ename:VK_FORMAT_R16_UINT 694|code:R8ui |ename:VK_FORMAT_R8_UINT 695|==== 696