• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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