Standard Portable Intermediate Representation
{{Short description|Internal code for computer graphics}}
{{Infobox software
| name = SPIR-V
| logo = SPIR logo.svg
| author =
| developer = Khronos Group
| released = 2015
| latest release version = SPIR-V 1.6
| latest release date = {{Start date and age|2021|12|16}}
| operating_system = Cross-platform
| platform = Cross-platform
| genre = Intermediate language
| website = {{URL|https://www.khronos.org/registry/SPIR-V}}
}}
Standard Portable Intermediate Representation (SPIR) is an intermediate language for parallel computing and graphics by Khronos Group. It is used in multiple execution environments, including the Vulkan graphics API and the OpenCL compute API, to represent a shader or kernel. It is also used as an interchange language for cross compilation.{{cite book |title=Heterogeneous Computing Architectures: Challenges and Vision |url=https://books.google.com/books?id=edeuDwAAQBAJ&dq=spir-v+natively+represent&pg=PT95 | isbn=9780429680038 |access-date=24 June 2022| last1=Terzo | first1=Olivier | last2=Djemame | first2=Karim | last3=Scionti | first3=Alberto | last4=Pezuela | first4=Clara | date=10 September 2019 | publisher=CRC Press }}
SPIR-V is a new version of SPIR which was introduced in 2015 by the Khronos Group, and has since replaced the original SPIR, which was introduced in 2012.
On September 19th 2024, Microsoft has announced plans to adopt SPIR-V as the Direct3D Interchange format in place of DXIL, beginning support from Shader Model 7 on.{{cite web |last1=Bieneman |first1=Chris |title=DirectX Adopting SPIR-V as the Interchange Format of the Future |url=https://devblogs.microsoft.com/directx/directx-adopting-spir-v/ |website=DirectX Developer Blog |access-date=19 September 2024 |date=19 September 2024}}
Purpose
The purposes of SPIR-V are to natively represent the primitives needed by compute and graphics; to separate high-level language from the interface to compute and graphics drivers; to be the distribution form, or distribute fully compiled binaries; to be a fully self-contained specification; and to support multiple APIs. It is also used as an intermediate target for cross-compilation tools.
For example, SPIR-V allows the Vulkan API to use any shading language, including GLSL and HLSL.{{cite web |title=Shader modules |url=https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules |website=Vulkan Tutorial}}{{cite web |title=HLSL as a First Class Vulkan Shading Language |url=https://www.khronos.org/blog/hlsl-first-class-vulkan-shading-language |website=The Khronos Group |language=en |date=15 January 2020}} SPIR-V can be decompiled into several shading languages (GLSL, GLSL ES, MSL, HLSL) using SPIRV-Cross, so that these languages can be interconverted.{{Citation|title=KhronosGroup/SPIRV-Cross|date=2019-09-06|url=https://github.com/KhronosGroup/SPIRV-Cross|publisher=The Khronos Group|access-date=2019-09-08}} It also has paths to and/or from WebGPU, OpenCL, SYCL, C++, and Rust.
In target platforms, ingesting SPIR-V removes the need to build a high-level language source compiler into device drivers, which reduces driver complexity.
Versions
SPIR was originally introduced in 2011 and SPIR-V was introduced in 2015.
class="wikitable" style="text-align:center;"
|+ SPIR and SPIR-V ! !SPIR 1.2 !SPIR 2.0 !SPIR-V 1.X |
LLVM Interaction
|LLVM IR version 3.2 |LLVM IR version 3.4 | :100% Khronos defined :Round-trip lossless conversion |
Compute Constructs
|Metadata/Intrinsics |Metadata/Intrinsics |Native |
Graphics Constructs
|{{No}} |{{No}} |Native |
Supported Language & Feature Supported
|OpenCL C 1.2 | :OpenCL C 1.2 :OpenCL C 2.0 | : OpenCL C 1.2 / 2.X : OpenCL C++ : GLSL |
OpenCL Ingestion
|OpenCL 1.2 Extension |OpenCL 2.0 Extension |OpenCL 2.1/2.2 Core |
Graphics API Ingestion
|{{NA}} |{{NA}} | :Vulkan 1.X :OpenGL 4.6 Core |
=LLVM-based versions=
SPIR prior to the 2015 SPIR-V release was based on the LLVM Intermediate Representation. A provisional specification for SPIR 1.0 was announced in 2012.{{cite web|url = https://www.phoronix.com/scan.php?page=news_item&px=MTE4MzM|title = Khronos SPIR For OpenCL Brings Binary Compatibility|date = 12 September 2012|access-date = 25 July 2015|website = Phoronix|last = Larabel|first = Michael}} On July 22, 2013, a provisional specification SPIR 1.2 was announced at SIGGRAPH 2013.{{cite web|url=http://www.anandtech.com/show/7161/khronos-siggraph-2013-opengl-44-opencl-20-opencl-12-spir-announced/2|title=Khronos @ SIGGRAPH 2013: OpenGL 4.4, OpenCL 2.0, & OpenCL 1.2 SPIR Announced|last1=Smith|first1=Ryan|date=22 July 2013|website=Anandtech|access-date=5 April 2015}} The final SPIR 1.2 specification was released at HiPEAC 2014 on January 21, 2014.{{Cite web|url=https://www.khronos.org/news/press/khronos-releases-spir-1.2-specification-for-portable-encoding-of-opencl-dev|title=Khronos Releases SPIR 1.2 Specification for Portable Encoding of OpenCL Device Programs|date=2014-01-20|website=The Khronos Group|language=en|access-date=2019-08-05}} On August 11, 2014, a provisional specification for SPIR 2.0 was released at SIGGRAPH 2014.{{cite web|last1=Smith|first1=Ryan|title=Khronos Announces OpenCL SPIR 2.0|url=http://www.anandtech.com/show/8360/khronos-announces-opencl-spir-20|website=Anandtech|access-date=5 April 2015|date=11 August 2014}} SPIR-V does not use LLVM.
=SPIR-V=
SPIR-V 1.0 is a new version of SPIR announced in March 2015,{{cite web|last1=Parkerson|first1=Stuart|title=Khronos Group Introduces New Vulkan Hardware Driver API and SPIR-V Intermediate Language Shared by Vulkan and OpenCL 2.1|url=https://appdevelopermagazine.com/2462/2015/3/4/Khronos-Group-Introduces-New-Vulkan-Hardware-Driver-API-and-SPIR-V-Intermediate-Language-Shared-by-Vulkan-and-OpenCL-2.1/|website=App Developer Magazine|access-date=5 April 2015|date=4 March 2015}} and released on November 16, 2015.{{cite web|title=Khronos Releases OpenCL 2.1 and SPIR-V 1.0 Specifications for Heterogeneous Parallel Programming|url=https://www.khronos.org/news/press/khronos-releases-opencl-2.1-and-spir-v-1.0-specifications-for-heterogeneous|website=www.Khronos.org|access-date=16 November 2015|date=16 November 2015}} The SPIR family now includes a true cross-API standard that is fully defined by Khronos with native support for shader and kernel features.
A separate program by the Khronos Group allows for interconversion with LLVM IR.{{cite web |title=SPIRV-LLVM-Translator: A tool and a library for bi-directional translation between SPIR-V and LLVM IR |url=https://github.com/KhronosGroup/SPIRV-LLVM-Translator |website=GitHub |publisher=The Khronos Group}}
Support for ingestion of SPIR-V is incorporated in the core specification of OpenCL 2.1, the Vulkan API, and OpenGL version 4.6.
Features
SPIR-V is a high-level intermediate language, exchanged in binary form. Functions are represented by a control-flow graph of basic blocks, using static single assignment (SSA) form. Data structures retain high-level hierarchical representation. It is not lossy like previous byte-code or virtual machine-like intermediate representations used for graphical shaders. This allows closer to optimum performance on the target devices.{{cite web|last1=Kessenich|first1=John|title=An Introduction to SPIR-V|url=https://www.khronos.org/registry/spir-v/papers/WhitePaper.pdf|publisher=Khronos|access-date=25 July 2015}}
=Extensibility=
SPIR-V can be extended by writing extensions to add semantics, or reserving ranges of the token values for the party's use. Vendors can independently add desired semantics to SPIR-V.{{cite web |title=SPIRV-Guide |url=https://github.com/KhronosGroup/SPIRV-Guide/blob/master/chapters/extended_instruction_sets.md |website=github.com |access-date=24 June 2022}} Additional sets of extended instruction sets can be provided in separate specifications. Multiple sets can be imported without issue, as extended instructions are used by specifying the ID of the set and of the instruction within the set.
=Shaders=
Debuggers include RenderDoc, SwiftShader, and Amber.{{cite web |title=Google Open-Sources 'Amber' Multi-API Shader Test Framework |url=https://www.phoronix.com/scan.php?page=news_item&px=Google-Open-Source-Amber |website=phoronix.com |access-date=24 June 2022}}
Graphical shaders use structured control flow in SPIR-V to state how control flow nests. This helps in defining divergence and reconvergence of control flow on parallel execution environments.{{cite web |title=SPIR-V Specification: Structured Control Flow |url=https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#_structured_control_flow |website=khronos.org |access-date=24 June 2022}} Specialization reduces the number of variants of a shader that need to be distributed.{{cite web |title=Specialization Constants |url=https://veldrid.dev/articles/specialization-constants.html |website=veldrid.dev |access-date=24 June 2022}}
=Validation=
The SPIR-V specification states the rules that must be followed to have a valid SPIR-V module. This allows for offline validation. Drivers are not obligated to handle invalid SPIR-V modules. In testing, conformance testing verifies that drivers behave correctly when consuming valid SPIR-V, while validators verify that front-ends properly generate SPIR-V.
=Linking=
SPIR-V can express calls to functions in a different compilation unit. The standard version of SPIR-V uses this feature for OpenCL compute kernels, but not for shader stages, which the graphical APIs want fully linked into a single SPIR-V module.{{cite web |title=Shader Fundamentals |url=https://www.informit.com/articles/article.aspx?p=2731929&seqNum=8 |website=informit.com |access-date=24 June 2022}} There are extensions available to allow tools to temporarily use partially linked shaders and also kernels.{{cite web |title=SPIR-V Extension for Visual Studio |url=https://www.saschawillems.de/creations/spirv-vs-extension/ |website=saschawillems.de |access-date=24 June 2022}}
=Capabilities=
A SPIR-V module is used by a client API to support that module's features, which are classified through capabilities, and declared early in the module. A validator can confirm that the module uses only its declared capabilities, and a client API can reject modules that declare unsupported capabilities.{{cite web |title=SPIR-V Specification: Language Capabilities |url=https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html#_language_capabilities |website=khronos.org |access-date=24 June 2022}}
SPIR-V for GLSL cross-compilation
SPIR-V has been used to help deal with multiple versions of source-level languages. For example, the multiple versions of OpenGL Shading Language (GLSL) require distribution of multiple versions of shaders, due to implementations that are pegged to a specific older version of GLSL, such as for WebGL 1.0 and Apple's OpenGL implementation. One of the notable use cases of SPIR-V is its ability to be used as an interchange format between GLSL versions, using tools maintained by the Khronos Group for compiling GLSL to SPIR-V glslangValidator
,{{Cite web|url=https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/|title=OpenGL / OpenGL ES Reference Compiler|website=www.khronos.org|access-date=2020-10-01}} optimizing SPIR-V spirv-opt
, and cross-compiling to SPIR-V to different GLSL targets spirv-cross
.{{Cite web|url=https://github.com/KhronosGroup/SPIRV-Cross|title=SPIR-V Cross|website=www.github.com|access-date=2020-10-01}}
As a format, however, SPIR-V has some limitations for cross-compilation, including the requirement that every SPIR-V module have at least one entry-point symbol. This prevents the format from being easily used for separate compilation, where complex shaders could be assembled by a series of partial compile steps followed by a linking step. This runs counter to the stated goals of some SPIR-V tools such as spirv-link
,{{Cite web|url=https://github.com/KhronosGroup/SPIRV-Tools|title=SPIR-V Tools|website=www.github.com|access-date=2020-10-01}} which aims to provide full linking functionality for SPIR-V binary code.
See also
References
{{Reflist}}
External links
- [https://www.khronos.org/spir Khronos SPIR webpage]
- [https://www.khronos.org/registry/SPIR-V/specs/unified1/SPIRV.html SPIR-V specification]
{{Khronos Group standards}}