275 lines
14 KiB
Plaintext
275 lines
14 KiB
Plaintext
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
||
// Copyright notice at https://www.khronos.org/registry/speccopyright.html
|
||
|
||
[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.
|
||
|
||
== Required Versions and Formats
|
||
|
||
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.
|
||
|
||
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
|
||
|
||
Implementations must: support the following capability operands declared by
|
||
code:OpCapability:
|
||
|
||
* code:Matrix
|
||
* code:Shader
|
||
* code:InputAttachment
|
||
* code:Sampled1D
|
||
* code:Image1D
|
||
* code:SampledBuffer
|
||
* code:ImageBuffer
|
||
* code:ImageQuery
|
||
* code:DerivativeControl
|
||
|
||
Implementations may: support features that are not required: by the
|
||
Specification, as described in the <<features-features,Features>> chapter.
|
||
If such a feature is supported, then any capability operand(s) corresponding
|
||
to that feature must: also be supported.
|
||
|
||
[[spirvenv-capabilities-table]]
|
||
.SPIR-V Capabilities which are not required:, and corresponding feature names
|
||
[options="header"]
|
||
|====
|
||
| SPIR-V OpCapability | Vulkan feature name
|
||
| 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_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_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[]
|
||
|
||
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 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*
|
||
** *Invocation*
|
||
* 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
|
||
** 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:OpSampledImage must: only consume an ``Image'' operand whose type
|
||
has its ``Sampled'' operand set to 1.
|
||
** The ``(u, v)'' coordinates used for a code:SubpassData must: be the <id>
|
||
of a constant vector (0, 0), or if a layer coordinate is used, must: be
|
||
a vector that was formed with constant 0 for the ``u'' and ``v''
|
||
components.
|
||
** The ``Depth'' operand of code:OpTypeImage is ignored.
|
||
* 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.
|
||
* code:OpTypeRuntimeArray must: only be used for the last member of an
|
||
code:OpTypeStruct in the code:Uniform storage class.
|
||
* Linkage: See <<interfaces,Shader Interfaces>> for additional linking and
|
||
validation rules.
|
||
* 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.
|
||
|
||
|
||
[[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.
|
||
* NaNs may: not be generated. Instructions that operate on a NaN may: not
|
||
result in a NaN.
|
||
* Support for signaling NaNs is optional: and exceptions are never raised.
|
||
|
||
The precision of double-precision instructions is at least that of single
|
||
precision. 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) | latexmath:[$(3 + 2 \times \|x\|)$] ULP.
|
||
| code:log(), code:log2() | 3 ULP outside the range [0.5, 2.0]. Absolute error < 2^-21^ inside the range [0.5, 2.0].
|
||
| code:pow(x, y) | Inherited from code:exp2(y × 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
|
||
|====
|