Note This document is meant to be a reference for understanding and discussing WebGPU & WGSL. It is not meant to an implemented SPIR-V environment. Note This document is in transition. It started as a specification of the form and semantics SPIR-V modules that could be directly ingestible as the shader language for WebGPU. It is transitioning to a specification of the form and semantics of SPIR-V modules that should be translatable into WGSL, such that the corresponding WGSL shaders are ingestible as shaders in WebGPU.
Note: Many items are marked "TBD". In most cases those items will be resolved once the exact feature set of WebGPU has been determined.
[TBD: this may belong in a different specification, if it exists, about WebGPU]
WebGPU executes graphics and compute pipelines. A graphics pipeline processes data through a programmable vertex shader, and the resulting fragments through a programmable fragment shader. A compute pipeline processes data via a compute shader.
A WebGPU pipeline defines:
- Shader modules for each programmable stage (vertex, fragment, and compute)
- Shader modules declare their usage of resources as "bindings", "vertex inputs" or "fragment outputs". This is the shader module's implicit resource interface.
- Specialization constants for each shader module
- A "resource interface" that must be a superset of each of the shader module implicit interfaces. Each resource in a resource interface can be either read-only or read-write.
- Various "fixed function" configuration options.
WebGPU shaders are expressed in WGSL. However, a SPIR-V module can often be translated into WGSL for use in WebGPU. SPIR-V is usable in several execution environments, and so its core definition describes a superset of functionality across all those environments. The "WebGPU Execution Environment Specification for SPIR-V" section describes restrictions on SPIR-V such that they can be expected to be translated into WGSL for use with WebGPU.
A WebGPU application (an "App") consists of code to invoke WebGPU API entry points ("host code"), and WebGPU shaders. A WebGPU implementation does not trust either host code or shaders.
Stages of execution:
- A WebGPU implementation loads App code, and begins running the App host code in an untrusted manner.
- The App host code invokes WebGPU APIs to create resources, load shaders, and create a pipeline configuration.
- The App invokes a WebGPU API to run a pipeline.
During these steps the WebGPU implementation will have:
- Validated the pipeline configuration and all associated objects.
- Determined the set of data resources that should be accessible to the shaders, and in what access modes (e.g. read-only, read-write).
- Determined the computing resources to be used to execute the pipeline.
- Created a pipeline ExecutionContext consisting of the computing and data resources that are valid to be used by the pipeline, and in particular by the shaders in the pipeline. Each data resource is associated with valid access modes: read-only resources may only be read; only writable resources may be written.
- Executes the pipeline, subject to the security property that follows.
A WebGPU implementation is secure if, for any application App running on the implementation, accesses explicitly granted to App are the only means by which:
- App may sense state outside its ExecutionContext
- App may cause mutation of state outside its ExecutionContext
- App may cause or sense I/O outside its ExecutionContext
An access is considered explicitly granted only if:
- It is a read access to a resource attached for reading to the ExecutionContext
- It is a write access to a resource attached for writing to the ExecutionContext
Typically a WebGPU implementation can make sure that the App can only access resources provided in the ExecutionContext by validating the code in the shader module. However this only guarantees that the correct resources are accessed, not that they are accessed in bounds.
A WebGPU implementation must ensure out of bounds accesses don't cause accesses outside of the ExecutionContext. This will typically be done by instrumenting the generated code. Because this code is highly performance sensitive, the WebGPU implementation is granted multiple options for enforcing security.
The following rules are based on those defined by the robustBufferAccess feature in the Vulkan 1.0 specification.
Out-of-bounds buffer loads may result in any of the following behaviors:
-
Return values from anywhere within the memory range(s) bound to the buffer (possibly including bytes of memory past the end of the buffer, up to the end of the bound range).
-
Return zero values, or (0,0,0,x) vectors for vector reads, where x is a valid value represented in the type of the vector components and may be any of:
-
0, 1, or the maximum representable positive integer value, for signed or unsigned integer components.
-
0.0 or 1.0, for floating-point components.
-
-
Cause a trap: that is, cause the shader invocation to write zero values to all shader stage outputs, and then terminate without other side effects.
Out-of-bounds buffer writes may result in any of the following behaviors:
- Be discarded.
- Modify values within the memory range(s) bound to the buffer, but must not modify any other memory.
- Cause a trap.
Out-of-bounds atomics may result in any of the following behaviors:
- Be discarded.
- Modify values within the memory range(s) bound to the buffer, but must not modify any other memory.
- Return an undefined value.
- Cause a trap.
Additional functionality exists to create pointers to values inside resources. Creating a pointer for a resource that points outside the resource may result in any of the following behaviors:
- Defer the out of bounds behavior to when the pointer is dereferenced.
- Create a pointer to any location within the resource. (this is equivalent to deferring and "access any location" for resource accesses).
- Cause a trap.
(TODO are there pointers to unsized arrays? Could talk about the "sized part of the type if that's the case" and use the "any location" rule)
Shaders in SPIR-V that may be translated into WGSL are specified by this rules in this document in addition to the Khronos SPIR-V Specification. [TBD: update to latest available specification] See the "Version" subsection below for allowed version numbers.
The following sections visit the parts of a SPIR-V module, in order, covering each section, and state additional requirements for SPIR-V shaders translatable for use in WebGPU. These are in addition to all requirements already present in the SPIR-V specification itself.
The SPIR-V specification states that certain actions by a SPIR-V shader result in undefined behaviour. A WebGPU implementation is required to be secure. Therefore in the context of WebGPU, a shader which triggers SPIR-V's undefined behaviour may continue to execute in an arbitrary manner except that it may not sense or mutate any state outside its ExecutionContext, and it may not cause or sense I/O outside its ExecutionContext.
NOTE: One of the possible behaviours of an ill-behaved application is non-termination. The WebGPU specification should say what happens to a runaway application.
Certain operations in SPIR-V which are valid in the WebGPU environment could result in out-of-bounds accesses. Their behavior is governed by the out-of-bounds access behavior section above.
OpLoad
,OpRead
,OpMemoryCopy
when the pointer is out of bounds.OpAccessChain
when any of the indices for array accesses are larger (or equal) to the array's size or when the pointer is out of bounds. Note that the size of arrays are known at runtime forOpTypeRuntimeArray
. Sizes forOpTypeArray
are always known at pipeline compilation time when all specialization constants have been set.OpInBoundsAccessChain
under the same conditions asOpAccessChain
, effectively making it an exact equivalent ofOpAccessChain
.- All operations starting with
OpAtomic
when the pointer is out of bounds. OpImageFetch
,OpImageRead
,OpImageWrite
when coordinates aren't in bounds of the resource.OpImageTexelPointer
when the coordinates aren't in bounds of the resource.
Other operations can result in out-of-bounds accesses even if they aren't on resources. The same out of bounds rules apply to them as well:
OpVectorIndexDynamic
andOpVectorInsertDynamic
when the index is larger than, or equal to, the vector size.OpBitFieldInsert
,OpBitFieldSExtract
andOpBitFieldUExtract
when the range of bits isn't fully contained in the variable.
SPIR-V versions 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 should be usable: The version number (second 32-bit word) of a SPIR-V module must be one of the following:
- 0x00010000 (SPIR-V 1.0)
- 0x00010100 (SPIR-V 1.1)
- 0x00010200 (SPIR-V 1.2)
- 0x00010300 (SPIR-V 1.3)
- 0x00010400 (SPIR-V 1.4)
- 0x00010500 (SPIR-V 1.5)
Features introduced in newer versions might still be unavailable due to restrictions introduced later in this specification.
All capabilities declared by OpCapability instructions (located after the header in a SPIR-V module) must be one of the following:
- Matrix
- Shader
- Sampled1D
- Image1D
- DerivativeControl
- ImageQuery
- VulkanMemoryModelKHR
- [Notably missing: Linkage, Kernel, …]
Further, if a capability is used only for non-enabled optional functionality, it is invalid to use it.
All extensions declared by OpExtension instructions must be one of the following:
- SPV_KHR_vulkan_memory_model
- SPV_KHR_storage_buffer_storage_class
- SPV_KHR_no_integer_wrap_decoration
- SPV_KHR_non_semantic_info
- SPV_GOOGLE_decorate_string
- SPV_GOOGLE_hlsl_functionality1
- SPV_GOOGLE_user_type
- [No other extensions allowed for now]
All extended instruction sets declared by OpExtInstImport must be one of the following:
- "GLSL.std.450"
- A non-semantic extended instruction set following the conventions in SPV_KHR_non_semantic_info In particular, "NonSemantic." is a prefix of the extended instruction set name.
The addressing declared by OpMemoryModel must be Logical.
The memory model declared must be one of:
- Simple
- GLSL450
- Vulkan, also known as VulkanKHR
There must be at least one OpEntryPoint in a module, and each one present must satisfy:
- The OpFunction declared as the entry point must have no OpFunctionParameter and its Return Type must be OpTypeVoid.
- The complete call graph rooted by the entry point must
- be present in the module (the Linkage capability is not valid, so there are no partially linked modules), and
- not contain any cycles (no recursion, even statically).
- The Name of an OpEntryPoint
- cannot be used by any other OpEntryPoint in the same module.
- has its length bounded due to SPIR-V instruction length limits.
- may be limited by the WebGPU specification. WHLSL Issue 292
The execution model declared by each OpEntryPoint must be one of the following:
- Vertex
- Fragment
- GLCompute
All execution modes declared by OpExecutionMode must be one of the following:
- OriginUpperLeft
- DepthReplacing
- DepthGreater
- DepthLess
- DepthUnchanged
- LocalSize
The following debug instructions are permitted: OpName, OpMemberName, OpLine, OpNoLine, OpModuleProcessed, OpString, OpSourceExtension, OpSource, and OpSourceContinued.
OpDecorationGroup, OpGroupDecorate, OpGroupMemberDecorate are not allowed.
Only the following decorations are valid:
- SpecId
- Block
- RowMajor
- ColMajor
- ArrayStride (also see "Layouts" below)
- MatrixStride (also see "Layouts" below)
- Builtin (also see "Built-In Variables" below)
- NoPerspective, only in the Input storage class and the Fragment execution model
- Flat, only in the Input storage class and the Fragment execution model
- Centroid
- Restrict
- Aliased
- NonWritable
- NonReadable
- Uniform
- Location, required for all Input and Output, see "Interface" section below
- Component
- Index
- Binding
- DescriptorSet
- Offset (also see "Layouts" below)
- NoContraction
- NoSignedWrap
- NoUnsignedWrap
- CounterBuffer, also known as HlslCounterBufferGOOGLE
- UserSemantic, also known as HlslSemanticGOOGLE
- UserTypeGOOGLE
- UniformId
When decorating with the Builtin decoration, only the following are valid, and these are further restricted as indicated by the table.
Builtin | Allowed types | Allowed execution models for the Input storage class | Allowed execution models for the Output storage class |
---|---|---|---|
Position | Vector of 4 32-bit floats | Vertex | |
VertexIndex | Scalar 32-bit integer | Vertex | |
InstanceIndex | Scalar 32-bit integer | Vertex | |
FrontFacing | Boolean | Fragment | |
FragCoord | Vector of 4 32-bit floats | Fragment | |
FragDepth | 32-bit float | Fragment | |
WorkgroupSize | Vector of 3 32-bit ints | GLCompute | |
LocalInvocationId | Vector of 3 32-bit ints | GLCompute | |
GlobalInvocationId | Vector of 3 32-bit ints | GLCompute | |
LocalInvocationIndex | 32-bit int | GLCompute |
Note: NumWorkgroups is not in the WebGPU MVP. See gpuweb/gpuweb#920
Full semantic descriptions of what these mean, how the behave, when they have what values, etc. is part of the WebGPU specification proper, not this specification.
Scalar floating-point types (OpTypeFloat) must have 32 bit width.
Scalar integer types (OpTypeInteger) must have 32 bit width.
Signed integers use two's complement representation.
Vector types must have one of the following number of components:
- 2
- 3
- 4
Matrix types must have one of the following number of vectors:
- 2
- 3
- 4
Storage Class must be one of the following:
- UniformConstant
- Uniform
- StorageBuffer (no BufferBlock)
- Input
- Output
- Image
- Workgroup
- PushConstant, if WebGPU supports them: WebGPU Issue 75
- Private
- Function
OpTypeRunTimeArray is only for the last member of a block in the StorageBuffer storage class.
- If function A calls function B, then B precedes A in the module.
- OpTypeFunction may not have OpTypeVoid as a parameter type.
All functions in the SPIR-V module must use structured control flow. See 2.11 Structured Control Flow.
Scope when used for memory must be one of:
- Workgroup
- Invocation
- QueueFamilyKHR
Workgroup memory scope is only usable in a GLCompute shader.
Scope when used for execution must be one of:
- Workgroup
Workgroup execution scope is only usable in a GLCompute shader.
Individual SPIR-V instructions may further restrict valid values.
A Memory Semantics operand is expressed in a single word, using mask bits in grouped into three sets:
- Memory Semantics Order bits are mask bits with value between 1 through 0x10:
- 0x1 Reserved
- 0x2 Acquire
- 0x4 Release
- 0x8 AcquireRelease
- 0x10 SequentiallyConsistent
- Memory Semantics Storage Class bits are mask bits with value between 0x20 through 0x1000:
- 0x20 Reserved
- 0x40 UniformMemory
- 0x80 SubgroupMemory
- 0x100 WorkgroupMemory
- 0x200 CrossWorkgroupMemory
- 0x400 AtomicCounterMemory
- 0x800 ImageMemory
- 0x1000 OutputMemoryKHR
- Memory Semantics Propagation bits are mask bits with value between 0x2000 through 0x4000:
- 0x2000 MakeAvailableKHR
- 0x4000 MakeVisibleKHR
Individual SPIR-V instructions may further restrict valid values for a Memory Semantics operand. The restrictions are expressed in terms of the order, storage class, and propagation sets of bits.
TBD: To simplify the programming model: could require if an instruction takes a memory access operand and operates on a storage class other than Function or Private, then it must use NonPrivateKHR. This could give up some performance.
TBD: Consider a similar simplification for image accesses.
If a variable declaration has an initializer, then the variable must be in one of the following storage classes:
- Output
- Private
- Function
All variables in the following storage classes must have an initializer:
- Output
- Private
- Function
- INF, NaN, etc. …. TBD
- Exceptions are never raised, but signaling NaNs can be generated.
- Denorms… TBD
- Rounding… TBD
- Single precision…. [See tables in Vulkan spec]
- Double precision is at least the precision of single precision.
- Error bounds (ULP)
- … TBD
Fusing and reassociation of floating point operations is allowed when those instructions are not decorated with NoContraction.
Supported OpCodes are listed in Appendix A.
The following sections describe differences from specific SPIR-V instructions.
- OpUndef is not allowed.
- OpSpecConstantOp:
- Opcode OpVectorShuffle may not have a component literal with value 0xFFFFFFFF.
-
Workgroup variables are only usable in GLCompute shaders. Specifically:
- If instruction Inst is in the function parameter list or the body of a function in the call graph of an entry point E, and
- The type of any operand of Inst or the result of Inst is a pointer type with storage class Workgroup,
- Then E must have an execution model of GLCompute.
-
OpPtrEqual, OpPtrNotEqual, OpPtrDiff are not allowed.
- OpVectorShuffle may not have a component literal with value 0xFFFFFFFF.
- Atomic instructions (OpAtomic*) are restricted:
- The Memory scope operand must be QueueFamilyKHR
- The Semantics operand must be zero:
- Must not set any Memory Semantics Order bits.
- Must not set any Memory Semantics Storage Class bits.
- Must not set any Memory Semantics Propagation bits.
Note: In terms from other standards, OpAtomic* instructions are Relaxed.
Note: In the memory model, atomic operations automatically include availability and visibility semantics.
- OpControlBarrier* restrictions:
- OpControlBarrier may only be used in the call graph of GLCompute entry point.
- The Execution scope operand must be Workgroup
- The Memory scope operand must be Workgroup
- The Semantics operand:
- Memory Semantics Order bits: Must set the AcquireRelease bit, and no other bits.
- Memory Semantics Storage Class bits: Must set the WorkgroupMemory bit, and no other bits.
- Must not set any Memory Semantics Propagation bits.
Note: To ensure propagation of Workgroup writes to readers, individual accesses of Workgroup memory should use availability and visibility semantics: MakePointerAvailableKHR with Workgroup scope on writes, MakePointerVisibleKHR with Workgroup scope on reads, and NonPrivatePointerKHR on both.
- OpMemoryBarrier* restrictions:
- The Memory scope operand must be Invocation
- The Semantics operand:
- Must not set any Memory Semantics Order bits.
- Memory Semantics Storage Class bits: Must set the ImageMemory bit, and no other bits.
- Must not set any Memory Semantics Propagation bits.
Note: OpMemoryBarrier is only used to order reads and writes by the same invocation to the same locations in image memory.
TBD: List rules for supported formats, combinations, types, etc. This is mostly independent of SPIR-V.
See WebGPU Issue 163
Interfaces discussed here are those that are:
- connecting one shader stage to the subsequent shader stage; from the former's Output storage class to the latter's Input storage class
- between the application and the Input storage class to the first shader stage in the pipeline
- between the Output storage class of the last tages and the application
- between the application and the shader stages through buffers: storage buffer blocks and uniform buffer blocks
- Push constants, if WebGPU supports them: WebGPU Issue 75
Each such interface must match, via the following matching rules:
- Location/Component … see section 14.1.4 "Location Assignment" in the Vulkan spec.
- TBD: What does the buffer interface look like? Block decoration and StorageBuffer, etc.?
- TBD: Built-in variables placed in a block go only in one block, with nothing but built-in variables.
- …
- TBD, see section 14.1.3 "Interface Matching" from the Vulkan spec.
- See 14.2. "Vertex Input Interface" in the Vulkan spec.
- See 14.3. "Fragment Output Interface" in the Vulkan spec.
- Attachment interface? 14.4
- Push Constant 14.5.1, if WebGPU supports them: WebGPU Issue 75
- See 14.5.2. "Descriptor Set Interface" and 14.5.3. "DescriptorSet and Binding Assignment"
Text in this section is adapted from 14.5.4 Offset and Stride Assignment section in the Vulkan Specification version 1.1
All SPIR-V aggregates and matrices appearing in the Uniform and StorageBuffer storage classes must be explicitly and fully laid out through the Offset, ArrayStride, MatrixStride, RowMajor, and ColMajor decorations. These must satisfy the following rules described in this section.
Note: If WebGPU supports push constants, then aggregates and matrices in the PushConstant storage class must also be explicitly laid out. See WebGPU Issue 75.
Two different layouts requirements are described below: standard uniform buffer layout, and standard storage buffer layout. The rules to apply for a specific resource depends on the type of the buffer resource.
Offsets and strides are expressed in units of 8-bit bytes.
A scalar numeric value of 32 bits occupies 4 bytes in memory, i.e. its size is 4. In general a scalar value of N bits occupies floor((N + 7) / 8) bytes. Scalars are represented in little-endian byte order.
Layout decorations on SPIR-V objects may not conflict or be duplicated:
- A SPIR-V object or structure member must have at most one decoration each of kind:
- Offset
- ArrayStride
- MatrixStride
- RowMajor
- ColMajor
- A SPIR-V structure member must not be decorated with both RowMajor and ColMajor.
The numeric order of Offset decorations does not need to follow structure member declaration order. That is, offsets of structure members are not necessarily monotonic.
Section 2.16.2 Validation Rules for Shader Capabilities of the SPIR-V specification has additional constraints not copied here. For example, in effect:
- Structure members may not overlap.
- Each matrix in Uniform or StorageBuffer storage must have its row- or column-majorness expressed as a RowMajor or ColMajor decoration on the nearest enclosing structure member.
This section specifies rules for Standard Uniform Buffer Layout.
The base alignment of the type of an OpTypeStruct member is defined recursively as follows:
- A scalar of size N bytes has a base alignment of N.
- A two-component vector, with components of size N bytes, has a base alignment of 2 N.
- A three- or four-component vector, with components of size N bytes, has a base alignment of 4 N.
- An array has a base alignment equal to the base alignment of its element type, rounded up to a multiple of 16.
- A structure has a base alignment equal to the largest base alignment of any of its members, rounded up to a multiple of 16.
- A row-major matrix of C columns has a base alignment equal to the base alignment of a vector of C matrix components.
- A column-major matrix has a base alignment equal to the base alignment of the matrix column type.
A member is defined to improperly straddle if either of the following are true:
- It is a vector with total size less than or equal to 16 bytes, and has Offset decorations placing its first byte at F and its last byte at L, where floor(F / 16) != floor(L / 16).
- It is a vector with total size greater than 16 bytes and has its Offset decorations placing its first byte at a non-integer multiple of 16.
Every member of an OpTypeStruct with storage class of Uniform and a decoration of Block (uniform buffers) must be laid out according to the following rules:
- The Offset decoration of a scalar, an array, a structure, or a matrix must be a multiple of its base alignment.
- The Offset decoration of a vector must be an integer multiple of the base alignment of its scalar component type, and must not improperly straddle, as defined above.
- Any ArrayStride or MatrixStride decoration must be an integer multiple of the base alignment of the array or matrix from above.
- The Offset decoration of a member must not place it between the end of a structure or an array and the next multiple of the base alignment of that structure or array.
Note: The std140 layout in GLSL satisfies these rules.
Note: The above assumes WebGPU can use what Vulkan calls relaxed block layout, which is optional in Vulkan 1.0 but a required feature of Vulkan 1.1.
This section specifies rules for Standard Storage Buffer Layout.
Member variables of an OpTypeStruct with a storage class of StorageBuffer with a decoration of Block must be laid out as for Standard Uniform Buffer Layout, except for array and structure base alignment which do not need to be rounded up to a multiple of 16.
Note: The std430 in GLSL satisfies these rules.
Vulkan Specification, version 1.1, The Khronos Group Inc. Portions copied and modified under Creative Commons Attribution 4.0 International License. See terms at Vulkan-Docs/COPYING.md
OpCode | Name |
---|---|
0 | OpNop |
10 | OpExtension |
11 | OpExtInstImport |
12 | OpExtInst |
14 | OpMemoryModel |
15 | OpEntryPoint |
16 | OpExecutionMode |
17 | OpCapability |
19 | OpTypeVoid |
20 | OpTypeBool |
21 | OpTypeInt |
22 | OpTypeFloat |
23 | OpTypeVector |
24 | OpTypeMatrix |
25 | OpTypeImage |
26 | OpTypeSampler |
27 | OpTypeSampledImage |
28 | OpTypeArray |
29 | OpTypeRuntimeArray |
30 | OpTypeStruct |
32 | OpTypePointer |
33 | OpTypeFunction |
41 | OpConstantTrue |
42 | OpConstantFalse |
43 | OpConstant |
44 | OpConstantComposite |
46 | OpConstantNull |
48 | OpSpecConstantTrue |
49 | OpSpecConstantFalse |
50 | OpSpecConstant |
51 | OpSpecConstantComposite |
52 | OpSpecConstantOp |
54 | OpFunction |
55 | OpFunctionParameter |
56 | OpFunctionEnd |
57 | OpFunctionCall |
59 | OpVariable |
60 | OpImageTexelPointer |
61 | OpLoad |
62 | OpStore |
63 | OpCopyMemory |
65 | OpAccessChain |
66 | OpInBoundsAccessChain |
68 | OpArrayLength |
71 | OpDecorate |
72 | OpMemberDecorate |
77 | OpVectorExtractDynamic |
78 | OpVectorInsertDynamic |
79 | OpVectorShuffle |
80 | OpCompositeConstruct |
81 | OpCompositeExtract |
82 | OpCompositeInsert |
83 | OpCopyObject |
84 | OpTranspose |
86 | OpSampledImage |
87 | OpImageSampleImplicitLod |
88 | OpImageSampleExplicitLod |
89 | OpImageSampleDrefImplicitLod |
90 | OpImageSampleDrefExplicitLod |
91 | OpImageSampleProjImplicitLod |
92 | OpImageSampleProjExplicitLod |
93 | OpImageSampleProjDrefImplicitLod |
94 | OpImageSampleProjDrefExplicitLod |
95 | OpImageFetch |
96 | OpImageGather |
97 | OpImageDrefGather |
98 | OpImageRead |
99 | OpImageWrite |
100 | OpImage |
103 | OpImageQuerySizeLod |
104 | OpImageQuerySize |
105 | OpImageQueryLod |
106 | OpImageQueryLevels |
107 | OpImageQuerySamples |
109 | OpConvertFToU |
110 | OpConvertFToS |
111 | OpConvertSToF |
112 | OpConvertUToF |
113 | OpUConvert |
114 | OpSConvert |
115 | OpFConvert |
116 | OpQuantizeToF16 |
124 | OpBitcast |
126 | OpSNegate |
127 | OpFNegate |
128 | OpIAdd |
129 | OpFAdd |
130 | OpISub |
131 | OpFSub |
132 | OpIMul |
133 | OpFMul |
134 | OpUDiv |
135 | OpSDiv |
136 | OpFDiv |
137 | OpUMod |
138 | OpSRem |
139 | OpSMod |
140 | OpFRem |
141 | OpFMod |
142 | OpVectorTimesScalar |
143 | OpMatrixTimesScalar |
144 | OpVectorTimesMatrix |
145 | OpMatrixTimesVector |
146 | OpMatrixTimesMatrix |
147 | OpOuterProduct |
148 | OpDot |
149 | OpIAddCarry |
150 | OpISubBorrow |
151 | OpUMulExtended |
152 | OpSMulExtended |
154 | OpAny |
155 | OpAll |
156 | OpIsNan |
157 | OpIsInf |
164 | OpLogicalEqual |
165 | OpLogicalNotEqual |
166 | OpLogicalOr |
167 | OpLogicalAnd |
168 | OpLogicalNot |
169 | OpSelect |
170 | OpIEqual |
171 | OpINotEqual |
172 | OpUGreaterThan |
173 | OpSGreaterThan |
174 | OpUGreaterThanEqual |
175 | OpSGreaterThanEqual |
176 | OpULessThan |
177 | OpSLessThan |
178 | OpULessThanEqual |
179 | OpSLessThanEqual |
180 | OpFOrdEqual |
181 | OpFUnordEqual |
182 | OpFOrdNotEqual |
183 | OpFUnordNotEqual |
184 | OpFOrdLessThan |
185 | OpFUnordLessThan |
186 | OpFOrdGreaterThan |
187 | OpFUnordGreaterThan |
188 | OpFOrdLessThanEqual |
189 | OpFUnordLessThanEqual |
190 | OpFOrdGreaterThanEqual |
191 | OpFUnordGreaterThanEqual |
194 | OpShiftRightLogical |
195 | OpShiftRightArithmetic |
196 | OpShiftLeftLogical |
197 | OpBitwiseOr |
198 | OpBitwiseXor |
199 | OpBitwiseAnd |
200 | OpNot |
201 | OpBitFieldInsert |
202 | OpBitFieldSExtract |
203 | OpBitFieldUExtract |
204 | OpBitReverse |
205 | OpBitCount |
207 | OpDPdx |
208 | OpDPdy |
209 | OpFwidth |
210 | OpDPdxFine |
211 | OpDPdyFine |
212 | OpFwidthFine |
213 | OpDPdxCoarse |
214 | OpDPdyCoarse |
215 | OpFwidthCoarse |
224 | OpControlBarrier |
225 | OpMemoryBarrier |
227 | OpAtomicLoad |
228 | OpAtomicStore |
229 | OpAtomicExchange |
230 | OpAtomicCompareExchange |
232 | OpAtomicIIncrement |
233 | OpAtomicIDecrement |
234 | OpAtomicIAdd |
235 | OpAtomicISub |
236 | OpAtomicSMin |
237 | OpAtomicUMin |
238 | OpAtomicSMax |
239 | OpAtomicUMax |
240 | OpAtomicAnd |
241 | OpAtomicOr |
242 | OpAtomicXor |
245 | OpPhi |
246 | OpLoopMerge |
247 | OpSelectionMerge |
248 | OpLabel |
249 | OpBranch |
250 | OpBranchConditional |
251 | OpSwitch |
252 | OpKill |
253 | OpReturn |
254 | OpReturnValue |
255 | OpUnreachable |
331 | OpExecutionModeId |
332 | OpDecorateId |
333 | OpName |
334 | OpMemberName |
335 | OpLine |
336 | OpNoLine |
337 | OpModuleProcessed |
338 | OpString |
339 | OpSourceExtension |
340 | OpSource |
341 | OpSourceContinued |
400 | OpCopyLogical |
5632 | OpDecorateString |
5633 | OpMemberDecorateString |