• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2018 The Khronos Group Inc.
2 // Copyright (c) 2018 Valve Corporation
3 // Copyright (c) 2018 LunarG Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
18 #define INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
19 
20 // Shader Instrumentation Interface
21 //
22 // This file provides an external interface for applications that wish to
23 // communicate with shaders instrumented by passes created by:
24 //
25 //   CreateInstBindlessCheckPass
26 //   CreateInstBuffAddrCheckPass
27 //   CreateInstDebugPrintfPass
28 //
29 // More detailed documentation of these routines can be found in optimizer.hpp
30 
31 namespace spvtools {
32 
33 // Stream Output Buffer Offsets
34 //
35 // The following values provide offsets into the output buffer struct
36 // generated by InstrumentPass::GenDebugStreamWrite. This method is utilized
37 // by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass.
38 //
39 // The first member of the debug output buffer contains the next available word
40 // in the data stream to be written. Shaders will atomically read and update
41 // this value so as not to overwrite each others records. This value must be
42 // initialized to zero
43 static const int kDebugOutputSizeOffset = 0;
44 
45 // The second member of the output buffer is the start of the stream of records
46 // written by the instrumented shaders. Each record represents a validation
47 // error. The format of the records is documented below.
48 static const int kDebugOutputDataOffset = 1;
49 
50 // Common Stream Record Offsets
51 //
52 // The following are offsets to fields which are common to all records written
53 // to the output stream.
54 //
55 // Each record first contains the size of the record in 32-bit words, including
56 // the size word.
57 static const int kInstCommonOutSize = 0;
58 
59 // This is the shader id passed by the layer when the instrumentation pass is
60 // created.
61 static const int kInstCommonOutShaderId = 1;
62 
63 // This is the ordinal position of the instruction within the SPIR-V shader
64 // which generated the validation error.
65 static const int kInstCommonOutInstructionIdx = 2;
66 
67 // This is the stage which generated the validation error. This word is used
68 // to determine the contents of the next two words in the record.
69 // 0:Vert, 1:TessCtrl, 2:TessEval, 3:Geom, 4:Frag, 5:Compute
70 static const int kInstCommonOutStageIdx = 3;
71 static const int kInstCommonOutCnt = 4;
72 
73 // Stage-specific Stream Record Offsets
74 //
75 // Each stage will contain different values in the next set of words of the
76 // record used to identify which instantiation of the shader generated the
77 // validation error.
78 //
79 // Vertex Shader Output Record Offsets
80 static const int kInstVertOutVertexIndex = kInstCommonOutCnt;
81 static const int kInstVertOutInstanceIndex = kInstCommonOutCnt + 1;
82 static const int kInstVertOutUnused = kInstCommonOutCnt + 2;
83 
84 // Frag Shader Output Record Offsets
85 static const int kInstFragOutFragCoordX = kInstCommonOutCnt;
86 static const int kInstFragOutFragCoordY = kInstCommonOutCnt + 1;
87 static const int kInstFragOutUnused = kInstCommonOutCnt + 2;
88 
89 // Compute Shader Output Record Offsets
90 static const int kInstCompOutGlobalInvocationIdX = kInstCommonOutCnt;
91 static const int kInstCompOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
92 static const int kInstCompOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
93 
94 // Tessellation Control Shader Output Record Offsets
95 static const int kInstTessCtlOutInvocationId = kInstCommonOutCnt;
96 static const int kInstTessCtlOutPrimitiveId = kInstCommonOutCnt + 1;
97 static const int kInstTessCtlOutUnused = kInstCommonOutCnt + 2;
98 
99 // Tessellation Eval Shader Output Record Offsets
100 static const int kInstTessEvalOutPrimitiveId = kInstCommonOutCnt;
101 static const int kInstTessEvalOutTessCoordU = kInstCommonOutCnt + 1;
102 static const int kInstTessEvalOutTessCoordV = kInstCommonOutCnt + 2;
103 
104 // Geometry Shader Output Record Offsets
105 static const int kInstGeomOutPrimitiveId = kInstCommonOutCnt;
106 static const int kInstGeomOutInvocationId = kInstCommonOutCnt + 1;
107 static const int kInstGeomOutUnused = kInstCommonOutCnt + 2;
108 
109 // Ray Tracing Shader Output Record Offsets
110 static const int kInstRayTracingOutLaunchIdX = kInstCommonOutCnt;
111 static const int kInstRayTracingOutLaunchIdY = kInstCommonOutCnt + 1;
112 static const int kInstRayTracingOutLaunchIdZ = kInstCommonOutCnt + 2;
113 
114 // Mesh Shader Output Record Offsets
115 static const int kInstMeshOutGlobalInvocationIdX = kInstCommonOutCnt;
116 static const int kInstMeshOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
117 static const int kInstMeshOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
118 
119 // Task Shader Output Record Offsets
120 static const int kInstTaskOutGlobalInvocationIdX = kInstCommonOutCnt;
121 static const int kInstTaskOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
122 static const int kInstTaskOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
123 
124 // Size of Common and Stage-specific Members
125 static const int kInstStageOutCnt = kInstCommonOutCnt + 3;
126 
127 // Validation Error Code Offset
128 //
129 // This identifies the validation error. It also helps to identify
130 // how many words follow in the record and their meaning.
131 static const int kInstValidationOutError = kInstStageOutCnt;
132 
133 // Validation-specific Output Record Offsets
134 //
135 // Each different validation will generate a potentially different
136 // number of words at the end of the record giving more specifics
137 // about the validation error.
138 //
139 // A bindless bounds error will output the index and the bound.
140 static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 1;
141 static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 2;
142 static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 3;
143 static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 4;
144 
145 // A descriptor uninitialized error will output the index.
146 static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 1;
147 static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 2;
148 static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 3;
149 static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 4;
150 
151 // A buffer out-of-bounds error will output the descriptor
152 // index, the buffer offset and the buffer size
153 static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 1;
154 static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 2;
155 static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 3;
156 static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 4;
157 
158 // A buffer address unalloc error will output the 64-bit pointer in
159 // two 32-bit pieces, lower bits first.
160 static const int kInstBuffAddrUnallocOutDescPtrLo = kInstStageOutCnt + 1;
161 static const int kInstBuffAddrUnallocOutDescPtrHi = kInstStageOutCnt + 2;
162 static const int kInstBuffAddrUnallocOutCnt = kInstStageOutCnt + 3;
163 
164 // Maximum Output Record Member Count
165 static const int kInstMaxOutCnt = kInstStageOutCnt + 4;
166 
167 // Validation Error Codes
168 //
169 // These are the possible validation error codes.
170 static const int kInstErrorBindlessBounds = 0;
171 static const int kInstErrorBindlessUninit = 1;
172 static const int kInstErrorBuffAddrUnallocRef = 2;
173 // Deleted: static const int kInstErrorBindlessBuffOOB = 3;
174 // This comment will will remain for 2 releases to allow
175 // for the transition of all builds. Buffer OOB is
176 // generating the following four differentiated codes instead:
177 static const int kInstErrorBuffOOBUniform = 4;
178 static const int kInstErrorBuffOOBStorage = 5;
179 static const int kInstErrorBuffOOBUniformTexel = 6;
180 static const int kInstErrorBuffOOBStorageTexel = 7;
181 static const int kInstErrorMax = kInstErrorBuffOOBStorageTexel;
182 
183 // Direct Input Buffer Offsets
184 //
185 // The following values provide member offsets into the input buffers
186 // consumed by InstrumentPass::GenDebugDirectRead(). This method is utilized
187 // by InstBindlessCheckPass.
188 //
189 // The only object in an input buffer is a runtime array of unsigned
190 // integers. Each validation will have its own formatting of this array.
191 static const int kDebugInputDataOffset = 0;
192 
193 // Debug Buffer Bindings
194 //
195 // These are the bindings for the different buffers which are
196 // read or written by the instrumentation passes.
197 //
198 // This is the output buffer written by InstBindlessCheckPass,
199 // InstBuffAddrCheckPass, and possibly other future validations.
200 static const int kDebugOutputBindingStream = 0;
201 
202 // The binding for the input buffer read by InstBindlessCheckPass.
203 static const int kDebugInputBindingBindless = 1;
204 
205 // The binding for the input buffer read by InstBuffAddrCheckPass.
206 static const int kDebugInputBindingBuffAddr = 2;
207 
208 // This is the output buffer written by InstDebugPrintfPass.
209 static const int kDebugOutputPrintfStream = 3;
210 
211 // Bindless Validation Input Buffer Format
212 //
213 // An input buffer for bindless validation consists of a single array of
214 // unsigned integers we will call Data[]. This array is formatted as follows.
215 //
216 // At offset kDebugInputBindlessInitOffset in Data[] is a single uint which
217 // gives an offset to the start of the bindless initialization data. More
218 // specifically, if the following value is zero, we know that the descriptor at
219 // (set = s, binding = b, index = i) is not initialized; if the value is
220 // non-zero, and the descriptor points to a buffer, the value is the length of
221 // the buffer in bytes and can be used to check for out-of-bounds buffer
222 // references:
223 // Data[ i + Data[ b + Data[ s + Data[ kDebugInputBindlessInitOffset ] ] ] ]
224 static const int kDebugInputBindlessInitOffset = 0;
225 
226 // At offset kDebugInputBindlessOffsetLengths is some number of uints which
227 // provide the bindless length data. More specifically, the number of
228 // descriptors at (set=s, binding=b) is:
229 // Data[ Data[ s + kDebugInputBindlessOffsetLengths ] + b ]
230 static const int kDebugInputBindlessOffsetLengths = 1;
231 
232 // Buffer Device Address Input Buffer Format
233 //
234 // An input buffer for buffer device address validation consists of a single
235 // array of unsigned 64-bit integers we will call Data[]. This array is
236 // formatted as follows:
237 //
238 // At offset kDebugInputBuffAddrPtrOffset is a list of sorted valid buffer
239 // addresses. The list is terminated with the address 0xffffffffffffffff.
240 // If 0x0 is not a valid buffer address, this address is inserted at the
241 // start of the list.
242 //
243 static const int kDebugInputBuffAddrPtrOffset = 1;
244 //
245 // At offset kDebugInputBuffAddrLengthOffset in Data[] is a single uint64 which
246 // gives an offset to the start of the buffer length data. More
247 // specifically, for a buffer whose pointer is located at input buffer offset
248 // i, the length is located at:
249 //
250 // Data[ i - kDebugInputBuffAddrPtrOffset
251 //         + Data[ kDebugInputBuffAddrLengthOffset ] ]
252 //
253 // The length associated with the 0xffffffffffffffff address is zero. If
254 // not a valid buffer, the length associated with the 0x0 address is zero.
255 static const int kDebugInputBuffAddrLengthOffset = 0;
256 
257 }  // namespace spvtools
258 
259 #endif  // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
260