当前位置:网站首页>A glimpse of spir-v
A glimpse of spir-v
2022-07-06 01:15:00 【zenny_ chen】
SPIR-V Overview
SPIR-V Shaders are embedded in modular In . Each module can contain one or more shaders . Each shader has an entry point , The entry point has a name and a shader type , The shader type is used to define which shader the current shader runs in Stage . The entry point is where the current shader starts executing . One SPIR-V The module is passed to... Along with the creation information Vulkan, then Vulkan Return an object representing the module . The module object can then be used to construct a Assembly line . This is a fully compiled version of a single shader , Along with the information needed to run it on the current device .
SPIR-V It means
SPIR-V about Vulkan Is the only officially supported coloring language . It's in API Layers are accepted and eventually used to construct pipelines , These pipelines are configured with one Vulkan The object of the device , Finish the work for your application .
SPIR-V Designed to be very easy to handle for some tools and drivers . This improves portability through diversity between different implementations . One SPIR-V The internal representation of the module is a 32 Bitword stream , Store in memory . Unless you are a tool writer or plan to build it yourself SPIR-V, Otherwise, you don't need to deal with it directly SPIR-V Binary code of . But rather , You can either watch SPIR-V Readable text representation of , Or use something like glslangvalidator Such an official Khronos GLSL Compile tools to generate SPIR-V.
Next we can write a calculation shader source file , Name it simpleKernel.comp
, Then give it to me glslangvalidator To compile . among .comp
The suffix can tell glslangvalidator This shader will be compiled as a computational shader .
#version 460 core
void main(void)
{
// Do Nothing...
}
Then we use the following command line ( I use Windows Environmental Science ):
%VK_SDK_PATH%/Bin/glslangValidator -o simpleKernel.spv -V100 simpleKernel.comp
Then we can see that a file named simpleKernel.spv Of SPIR-V Binary . We can use SPIR-V The disassembler disassembles the binary file . We use spirv-dis This official disassembly tool .
%VK_SDK_PATH%/Bin/spirv-dis -o simpleKernel.spvasm simpleKernel.spv
The above command will output a human readable assembly file simpleKernel.spvasm. It reads as follows :
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 10
; Bound: 6
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 460
OpName %main "main"
%void = OpTypeVoid
%3 = OpTypeFunction %void
%main = OpFunction %void None %3
%5 = OpLabel
OpReturn
OpFunctionEnd
We can see SPIR-V The text form of looks like a strange variant of assembly language . We can go through the above disassembly content line by line , Then see how it works with the original GLSL Enter the associated . Each line of the output assembly above represents a single SPIR-V Instructions , An instruction may consist of multiple symbols (token) constitute . Besides , A semicolon (;
) The first statement is a comment .
The first instruction in the stream is OpCapability Shader
, It requests to turn on shader capabilities .SPIR-V Functions are roughly divided into Instructions and features . Before your shader can use any of these features , You must state which features it will use as part of it . The shader in the above code is a graphics shader and thus uses Shader This ability . As we introduce more SPIR-V as well as Vulkan function , We will introduce the different capabilities that each feature depends on .
next , We see %1 = OpExtInstImport "GLSL.std.450"
. This is essentially importing an additional set corresponding to GLSL edition 450 Functions included , And this is often written by the original shader . Be careful , This instruction begins with %1 =
. This is an assignment to the result of the current instruction ID.OpExtInstImport
The result is a library in effect . When we want to call functions in this library , We just use OpExtInst
This instruction is used to realize . It has two operands , They are one library (OpExtInstImport
The result of the instruction ) And an instruction index . This allows SPIR-V The instruction set can be arbitrarily extended .
next , We see some additional statements .OpMemoryModel
A working memory model is specified for this module , In the above code example, it corresponds to GLSL edition 450 Logical memory model . This means that all memory accesses all memory accesses are performed through resources rather than through a physical memory model . The physical memory model accesses the memory directly through the pointer .
Next is the declaration of the entry point of the current module .OpEntryPoint GLCompute %main "main"
Instruction means that there is an entry point corresponding to OpenGL Compute Shader , The exported function is named main, And what is specified here ID by %main
, The symbol will be spirv-as The assembler assigns a specific ID Number . From the above code, we can see that %1
、%3
and %5
, But there is no %2
and %4
. And these two. ID It is very likely that number will eventually be compiled %main
and The next symbol %void
Allocated . The function name here "main"
Used to reference entry points , When we pass the generated shader module back to Vulkan The entry point of this module is required .
Then we will use the above in the latter instruction %main
This symbol —— OpExecutionMode %main LocalSize 1 1 1
The execution group size that defines this shader is 1×1×1 Work items . If the local size layout
Modifier defaults , that GLSL Will implicitly specify local size by 1×1×1.
The following two instructions simply provide some information .OpSource GLSL 460
Indicates that the current module uses GLSL edition 460 For compiling , and OpName %main "main"
For having ID by %main
The symbol of provides a name .
Now we can take a look at this main The real part of the function . First ,%void = OpTypeVoid
It states that we want to use %void
This symbol is used as a type void
. As mentioned earlier , It may eventually be allocated ID by 2. stay SPIR-V Everything in has a ID, Even type definitions . Larger aggregate types can be referenced sequentially by smaller 、 Simpler types to construct . However , We need to start somewhere , Here, a type is assigned to void
That's where we started .
%3 = OpTypeFunction %void
It means that we define one as 3 Of ID As a function type , The function type is void
As its return type ( Previously stated as void
) And there are no parameters . We use this type in the following line .%main = OpFunction %void None %3
This means that we declare a symbol %main
( Finally assigned ID May be 4, And we named it before "main"
) As function 3( The sentence above ) An example of , Its return type is void
, And there is no other special statement . This is through None
Give instructions , Other parameters available at this location include whether to inline 、 Or whether the variable is a constant .
Last , We see a label ( The label is not used , It's just a side effect of compiler operation )、 Implicit return statement 、 And the declaration of the end of the final function . This is us SPIR-V At the end of .
Design principles
- Regularity : All instructions begin with a number of words indicating how long the current instruction is . This allows SPIR-V The module does not need to decode every opcode . All instructions have an opcode to govern all operands , Determine which operands they belong to . For instructions with variable operand , The number of variable operands is obtained by subtracting the total number of words of the instruction from the number of non variable words .
- Non combinatorial : No combination type exposure , There is no need for large-scale coding of types / Decoding table . In its place , Types are parameterized . Image types declare their dimensions 、 Arrays, etc . Everything is orthogonal , This greatly simplifies the code . This is similar to other types . This also applies to opcodes . Operation for scalar / Vector sizes are orthogonal , But the difference between integer and floating-point number is not orthogonal .
- No model : When a given execution model is specified ( For example, the assembly line stage ) after , Internal operations are essentially modelless : Generally speaking , It follows this rule :“ The same spelling has the same semantics ”, And thus does not have schema bits with modified semantics . If the SPIR-V Changes to the semantics , Then it should be a different spelling . This makes SPIR-V Our consumers are more robust . There are indeed declared execution patterns , But these usually affect the way the module interacts with its execution environment , Rather than its internal semantics . Also have the ability to be declared , But this is to declare the subset of functions to be used , Instead of changing any semantics to be used .
- declarative :SPIR-V Declare externally visible patterns , image “ Write depth ”, Instead of having rules that require derivation from full shader observations . It also explicitly declares what addressing mode will be used 、 Execution model 、 Extended instruction set, etc .
- SSA: All results of intermediate operations are strict SSA. However , Declared variables residing in memory 、 And loading for access / Storage , And such variables can be stored many times .
- IO: Some storage classes are used for input / Output (IO) Of , And fundamentally ,IO It is through the loading of variables declared in these storage classes / Storage to complete .
Static single assignment (SSA)
SPIR-V Contains a phi Instructions to allow intermediate results to be merged from the split control flow . This allows the control flow to be unloaded / Store in memory .SPIR-V In the load / The use of storage is flexible ; no need phi Instructions to use control flow is also possible , And by loading with memory / Storage still follows SSA form .
Some storage classes are used for IO Of , And basically IO It's through storage / Load the implemented , The initial loading and final storage will not be eliminated . Other storage classes are shader native , This can load them / Storage for elimination . We can think of this loading / Storage by moving them to SSA The great elimination of intermediate results of form is an optimization .
Built in variables
SPIR-V Use an enumeration value decoration to identify built-in variables from a high-level language . This assigns any unusual semantics to the variable . In addition to these, the built-in variables are correct SPIR-V Type to declare , And treat it like other variables .
specialized
Specialization allows a portable based on constant values SPIR-V Modules are created offline , This constant was unknown at first , Until some later time . such as , During the creation of a module , Has a constant fixed size array , Its constant value is unknown , Therefore, the specific size of the array is unknown . But when the module is decentralized to the target architecture , The constant value is known .
The term
Instructions
One SPIR-V Physical layout of modules and instructions
One SPIR-V The module is a single string of linear words (word) flow . Some words at the beginning are shown in the following table :
surface 1: The starting word of physical layout
Word serial number | Content |
---|---|
0 | Magic number ——0x07230203 |
1 | Version number . These bytes are in high order to low order : 0 | The major version number | Minor version number | 0 thus , edition 1.3 The value is : 0x00'01'03'00 |
2 | Magic number of generator . It is associated with the tool that generates the module . Its value does not affect any semantics , And it is allowed to be 0. Use a non 0 Value is worth encouraging , And you can Khronos Register in . |
3 | The border ; Here are all in this module <id> Make sure that :0 < id < Bound The boundary should be as small as possible , The smaller the better. . All in a module <id> It should be packed densely and thus close to 0. |
4 | 0( Reserved for instruction mode , If necessary ) |
5 | The first word of the instruction stream , See the table below |
All the remaining words are a linear sequence of instructions . The word stream of each instruction is as follows :
surface 2: Instruction physical layout
Instruction word serial number | Content |
---|---|
0 | opcode : high 16 Bit is the number of words in the current instruction . low 16 Bit is the opcode enumeration value . |
1 | Optional instruction types type <id> ( The existence depends on the opcode ) |
- | Optional instruction results Result <id> ( The existence depends on the opcode ) |
- | Operands 1( if necessary ) |
- | Operands 2( if necessary ) |
… | … |
The number of words - 1 | Operands N(N Subtract... From the number of words 1 To 3 Words to determine , this 1 To 3 Words for opcode 、 Instruction type type <id> 、 And instruction results Result <id> ). |
Instructions are of variable length , Due to the optional instruction type type <id>
and Result <id>
word , And variable operands .
边栏推荐
- Five challenges of ads-npu chip architecture design
- 95后CV工程师晒出工资单,狠补了这个,真香...
- Kotlin core programming - algebraic data types and pattern matching (3)
- vSphere实现虚拟机迁移
- Leetcode 208. 实现 Trie (前缀树)
- 3D模型格式汇总
- Dede collection plug-in free collection release push plug-in
- Finding the nearest common ancestor of binary tree by recursion
- Leetcode 剑指 Offer 59 - II. 队列的最大值
- After Luke zettlemoyer, head of meta AI Seattle research | trillion parameters, will the large model continue to grow?
猜你喜欢
随机推荐
Introduction to robotics I. spatial transformation (1) posture, transformation
Differences between standard library functions and operators
FFT 学习笔记(自认为详细)
测试/开发程序员的成长路线,全局思考问题的问题......
View class diagram in idea
DOM introduction
037 PHP login, registration, message, personal Center Design
Recursive method to realize the insertion operation in binary search tree
Recommended areas - ways to explore users' future interests
Exciting, 2022 open atom global open source summit registration is hot
Ubantu check cudnn and CUDA versions
Illustrated network: the principle behind TCP three-time handshake, why can't two-time handshake?
GNSS terminology
JVM_ 15_ Concepts related to garbage collection
毕设-基于SSM高校学生社团管理系统
伦敦银走势中的假突破
RAID disk redundancy queue
Obstacle detection
SCM Chinese data distribution
Finding the nearest common ancestor of binary tree by recursion