xref: /aosp_15_r20/external/vulkan-validation-layers/docs/gpu_validation.md (revision b7893ccf7851cd6a48cc5a1e965257d8a5cdcc70)
1*b7893ccfSSadaf Ebrahimi<!-- markdownlint-disable MD041 -->
2*b7893ccfSSadaf Ebrahimi<!-- Copyright 2015-2019 LunarG, Inc. -->
3*b7893ccfSSadaf Ebrahimi[![Khronos Vulkan][1]][2]
4*b7893ccfSSadaf Ebrahimi
5*b7893ccfSSadaf Ebrahimi[1]: https://vulkan.lunarg.com/img/Vulkan_100px_Dec16.png "https://www.khronos.org/vulkan/"
6*b7893ccfSSadaf Ebrahimi[2]: https://www.khronos.org/vulkan/
7*b7893ccfSSadaf Ebrahimi
8*b7893ccfSSadaf Ebrahimi# GPU-Assisted Validation
9*b7893ccfSSadaf Ebrahimi
10*b7893ccfSSadaf Ebrahimi[![Creative Commons][3]][4]
11*b7893ccfSSadaf Ebrahimi
12*b7893ccfSSadaf Ebrahimi[3]: https://i.creativecommons.org/l/by-nd/4.0/88x31.png "Creative Commons License"
13*b7893ccfSSadaf Ebrahimi[4]: https://creativecommons.org/licenses/by-nd/4.0/
14*b7893ccfSSadaf Ebrahimi
15*b7893ccfSSadaf EbrahimiGPU-Assisted validation is implemented in the SPIR-V Tools optimizer and the `VK_LAYER_KHRONOS_validation layer (or, in the
16*b7893ccfSSadaf Ebrahimisoon-to-be-deprecated `VK_LAYER_LUNARG_core_validation` layer). This document covers the design of the layer portion of the
17*b7893ccfSSadaf Ebrahimiimplementation.
18*b7893ccfSSadaf Ebrahimi
19*b7893ccfSSadaf Ebrahimi## Basic Operation
20*b7893ccfSSadaf Ebrahimi
21*b7893ccfSSadaf EbrahimiThe basic operation of GPU-Assisted validation is comprised of instrumenting shader code to perform run-time checking in shaders and
22*b7893ccfSSadaf Ebrahimireporting any error conditions to the layer.
23*b7893ccfSSadaf EbrahimiThe layer then reports the errors to the user via the same reporting mechanisms used by the rest of the validation system.
24*b7893ccfSSadaf Ebrahimi
25*b7893ccfSSadaf EbrahimiThe layer instruments the shaders by passing the shader's SPIR-V bytecode to the SPIR-V optimizer component and
26*b7893ccfSSadaf Ebrahimiinstructs the optimizer to perform an instrumentation pass to add the additional instructions to perform the run-time checking.
27*b7893ccfSSadaf EbrahimiThe layer then passes the resulting modified SPIR-V bytecode to the driver as part of the process of creating a ShaderModule.
28*b7893ccfSSadaf Ebrahimi
29*b7893ccfSSadaf EbrahimiThe layer also allocates a buffer that describes the length of all descriptor arrays and the write state of each element of each array.
30*b7893ccfSSadaf EbrahimiIt only does this if the VK_EXT_descriptor_indexing extension is enabled.
31*b7893ccfSSadaf Ebrahimi
32*b7893ccfSSadaf EbrahimiAs the shader is executed, the instrumented shader code performs the run-time checks.
33*b7893ccfSSadaf EbrahimiIf a check detects an error condition, the instrumentation code writes an error record into the GPU's device memory.
34*b7893ccfSSadaf EbrahimiThis record is small and is on the order of a dozen 32-bit words.
35*b7893ccfSSadaf EbrahimiSince multiple shader stages and multiple invocations of a shader can all detect errors, the instrumentation code
36*b7893ccfSSadaf Ebrahimiwrites error records into consecutive memory locations as long as there is space available in the pre-allocated block of device memory.
37*b7893ccfSSadaf Ebrahimi
38*b7893ccfSSadaf EbrahimiThe layer inspects this device memory block after completion of a queue submission.
39*b7893ccfSSadaf EbrahimiIf the GPU had written an error record to this memory block,
40*b7893ccfSSadaf Ebrahimithe layer analyzes this error record and constructs a validation error message
41*b7893ccfSSadaf Ebrahimiwhich is then reported in the same manner as other validation messages.
42*b7893ccfSSadaf EbrahimiIf the shader was compiled with debug information (source code and SPIR-V instruction mapping to source code lines), the layer
43*b7893ccfSSadaf Ebrahimialso provides the line of shader source code that provoked the error as part of the validation error message.
44*b7893ccfSSadaf Ebrahimi
45*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Checks
46*b7893ccfSSadaf Ebrahimi
47*b7893ccfSSadaf EbrahimiThe initial release (Jan 2019) of GPU-Assisted Validation includes checking for out-of-bounds descriptor array indexing
48*b7893ccfSSadaf Ebrahimifor image/texel descriptor types.
49*b7893ccfSSadaf Ebrahimi
50*b7893ccfSSadaf EbrahimiThe second release (Apr 2019) adds validation for out-of-bounds descriptor array indexing and use of unwritten descriptors when the
51*b7893ccfSSadaf EbrahimiVK_EXT_descriptor_indexing extension is enabled.  Also added (June 2019) was validation for buffer descriptors.
52*b7893ccfSSadaf Ebrahimi
53*b7893ccfSSadaf Ebrahimi### Out-of-Bounds(OOB) Descriptor Array Indexing
54*b7893ccfSSadaf Ebrahimi
55*b7893ccfSSadaf EbrahimiChecking for correct indexing of descriptor arrays is sometimes referred to as "bind-less validation".
56*b7893ccfSSadaf EbrahimiIt is called "bind-less" because a binding in a descriptor set may contain an array of like descriptors.
57*b7893ccfSSadaf EbrahimiAnd unless there is a constant or compile-time indication of which descriptor in the array is selected,
58*b7893ccfSSadaf Ebrahimithe descriptor binding status is considered to be ambiguous, leaving the actual binding to be determined at run-time.
59*b7893ccfSSadaf Ebrahimi
60*b7893ccfSSadaf EbrahimiAs an example, a fragment shader program may use a variable to index an array of combined image samplers.
61*b7893ccfSSadaf EbrahimiSuch a line might look like:
62*b7893ccfSSadaf Ebrahimi
63*b7893ccfSSadaf Ebrahimi```glsl
64*b7893ccfSSadaf EbrahimiuFragColor = light * texture(tex[tex_ind], texcoord.xy);
65*b7893ccfSSadaf Ebrahimi```
66*b7893ccfSSadaf Ebrahimi
67*b7893ccfSSadaf EbrahimiThe array of combined image samplers is `tex` and has 6 samplers in the array.
68*b7893ccfSSadaf EbrahimiThe complete validation error message issued when `tex_ind` indexes past the array is:
69*b7893ccfSSadaf Ebrahimi
70*b7893ccfSSadaf Ebrahimi```terminal
71*b7893ccfSSadaf EbrahimiERROR : VALIDATION - Message Id Number: 0 | Message Id Name: UNASSIGNED-Image descriptor index out of bounds
72*b7893ccfSSadaf Ebrahimi        Index of 6 used to index descriptor array of length 6.  Command buffer (CubeDrawCommandBuf)(0xbc24b0).
73*b7893ccfSSadaf Ebrahimi        Pipeline (0x45). Shader Module (0x43). Shader Instruction Index = 108.  Stage = Fragment.
74*b7893ccfSSadaf Ebrahimi        Fragment coord (x,y) = (419.5, 254.5). Shader validation error occurred in file:
75*b7893ccfSSadaf Ebrahimi        /home/user/src/Vulkan-ValidationLayers/external/Vulkan-Tools/cube/cube.frag at line 45.
76*b7893ccfSSadaf Ebrahimi45:    uFragColor = light * texture(tex[tex_ind], texcoord.xy);
77*b7893ccfSSadaf Ebrahimi```
78*b7893ccfSSadaf EbrahimiThe VK_EXT_descriptor_indexing extension allows a shader to declare a descriptor array without specifying its size
79*b7893ccfSSadaf Ebrahimi```glsl
80*b7893ccfSSadaf Ebrahimilayout(set = 0, binding = 1) uniform sampler2D tex[];
81*b7893ccfSSadaf Ebrahimi```
82*b7893ccfSSadaf EbrahimiIn this case, the layer needs to tell the optimization code how big the descriptor array is so the code can determine what is out of
83*b7893ccfSSadaf Ebrahimibounds and what is not.
84*b7893ccfSSadaf Ebrahimi
85*b7893ccfSSadaf EbrahimiThe extension also allows descriptor set bindings to be partially bound, meaning that as long as the shader doesn't use certain
86*b7893ccfSSadaf Ebrahimiarray elements, those elements are not required to have been written.
87*b7893ccfSSadaf EbrahimiThe instrumentation code needs to know which elements of a descriptor array have been written, so that it can tell if one is used
88*b7893ccfSSadaf Ebrahimithat has not been written.
89*b7893ccfSSadaf Ebrahimi
90*b7893ccfSSadaf EbrahimiNote that currently, VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT validation is not working and all accesses are reported as valid.
91*b7893ccfSSadaf Ebrahimi
92*b7893ccfSSadaf Ebrahimi
93*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Options
94*b7893ccfSSadaf Ebrahimi
95*b7893ccfSSadaf EbrahimiHere are the options related to activating GPU-Assisted Validation:
96*b7893ccfSSadaf Ebrahimi
97*b7893ccfSSadaf Ebrahimi1. Enable GPU-Assisted Validation - GPU-Assisted Validation is off by default and must be enabled.
98*b7893ccfSSadaf Ebrahimi
99*b7893ccfSSadaf Ebrahimi    GPU-Assisted Validation is disabled by default because the shader instrumentation may introduce significant
100*b7893ccfSSadaf Ebrahimi    shader performance degradation and additional resource consumption.
101*b7893ccfSSadaf Ebrahimi    GPU-Assisted Validation requires additional resources such as device memory and descriptors.
102*b7893ccfSSadaf Ebrahimi    It is desirable for the user to opt-in to this feature because of these requirements.
103*b7893ccfSSadaf Ebrahimi    In addition, there are several limitations that may adversely affect application behavior,
104*b7893ccfSSadaf Ebrahimi    as described later in this document.
105*b7893ccfSSadaf Ebrahimi
106*b7893ccfSSadaf Ebrahimi2. Reserve a Descriptor Set Binding Slot - Modifies the value of the `VkPhysicalDeviceLimits::maxBoundDescriptorSets`
107*b7893ccfSSadaf Ebrahimi   property to return a value one less than the actual device's value to "reserve" a descriptor set binding slot for use by GPU validation.
108*b7893ccfSSadaf Ebrahimi
109*b7893ccfSSadaf Ebrahimi   This option is likely only of interest to applications that dynamically adjust their descriptor set bindings to adjust for
110*b7893ccfSSadaf Ebrahimi   the limits of the device.
111*b7893ccfSSadaf Ebrahimi
112*b7893ccfSSadaf Ebrahimi### Enabling and Specifying Options with a Configuration File
113*b7893ccfSSadaf Ebrahimi
114*b7893ccfSSadaf EbrahimiThe existing layer configuration file mechanism can be used to enable GPU-Assisted Validation.
115*b7893ccfSSadaf EbrahimiThis mechanism is described on the
116*b7893ccfSSadaf Ebrahimi[LunarXchange website](https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_configuration.html),
117*b7893ccfSSadaf Ebrahimiin the "Layers Overview and Configuration" document.
118*b7893ccfSSadaf Ebrahimi
119*b7893ccfSSadaf EbrahimiTo turn on GPU validation, add the following to your layer settings file, which is often
120*b7893ccfSSadaf Ebrahiminamed `vk_layer_settings.txt`.
121*b7893ccfSSadaf Ebrahimi
122*b7893ccfSSadaf Ebrahimi```code
123*b7893ccfSSadaf Ebrahimikhronos_validation.gpu_validation = all
124*b7893ccfSSadaf Ebrahimi```
125*b7893ccfSSadaf Ebrahimi
126*b7893ccfSSadaf EbrahimiTo turn on GPU validation and request to reserve a binding slot:
127*b7893ccfSSadaf Ebrahimi
128*b7893ccfSSadaf Ebrahimi```code
129*b7893ccfSSadaf Ebrahimikhronos_validation.gpu_validation = all,reserve_binding_slot
130*b7893ccfSSadaf Ebrahimi```
131*b7893ccfSSadaf Ebrahimi
132*b7893ccfSSadaf EbrahimiNote: When using the core_validation layer, the above settings should use `lunarg_core_validation` in place of
133*b7893ccfSSadaf Ebrahimi`khronos_validation`.
134*b7893ccfSSadaf Ebrahimi
135*b7893ccfSSadaf EbrahimiSome platforms do not support configuration of the validation layers with this configuration file.
136*b7893ccfSSadaf EbrahimiPrograms running on these platforms must then use the programmatic interface.
137*b7893ccfSSadaf Ebrahimi
138*b7893ccfSSadaf Ebrahimi### Enabling and Specifying Options with the Programmatic Interface
139*b7893ccfSSadaf Ebrahimi
140*b7893ccfSSadaf EbrahimiThe `VK_EXT_validation_features` extension can be used to enable GPU-Assisted Validation at CreateInstance time.
141*b7893ccfSSadaf Ebrahimi
142*b7893ccfSSadaf EbrahimiHere is sample code illustrating how to enable it:
143*b7893ccfSSadaf Ebrahimi
144*b7893ccfSSadaf Ebrahimi```C
145*b7893ccfSSadaf EbrahimiVkValidationFeatureEnableEXT enables[] = {VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT};
146*b7893ccfSSadaf EbrahimiVkValidationFeaturesEXT features = {};
147*b7893ccfSSadaf Ebrahimifeatures.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
148*b7893ccfSSadaf Ebrahimifeatures.enabledValidationFeatureCount = 1;
149*b7893ccfSSadaf Ebrahimifeatures.pEnabledValidationFeatures = enables;
150*b7893ccfSSadaf Ebrahimi
151*b7893ccfSSadaf EbrahimiVkInstanceCreateInfo info = {};
152*b7893ccfSSadaf Ebrahimiinfo.pNext = &features;
153*b7893ccfSSadaf Ebrahimi```
154*b7893ccfSSadaf Ebrahimi
155*b7893ccfSSadaf EbrahimiUse the `VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT` enum to reserve a binding slot.
156*b7893ccfSSadaf Ebrahimi
157*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Limitations
158*b7893ccfSSadaf Ebrahimi
159*b7893ccfSSadaf EbrahimiThere are several limitations that may impede the operation of GPU-Assisted Validation:
160*b7893ccfSSadaf Ebrahimi
161*b7893ccfSSadaf Ebrahimi### Vulkan 1.1
162*b7893ccfSSadaf Ebrahimi
163*b7893ccfSSadaf EbrahimiVulkan 1.1 or later is required because the GPU instrumentation code uses SPIR-V 1.3 features.
164*b7893ccfSSadaf EbrahimiVulkan 1,1 is required to ensure that SPIR-V 1.3 is available.
165*b7893ccfSSadaf Ebrahimi
166*b7893ccfSSadaf Ebrahimi### Descriptor Types
167*b7893ccfSSadaf Ebrahimi
168*b7893ccfSSadaf EbrahimiThe current implementation works with image, texel, and buffer descriptor types.
169*b7893ccfSSadaf EbrahimiA complete list appears later in this document.
170*b7893ccfSSadaf Ebrahimi
171*b7893ccfSSadaf Ebrahimi### Descriptor Set Binding Limit
172*b7893ccfSSadaf Ebrahimi
173*b7893ccfSSadaf EbrahimiThis is probably the most important limitation and is related to the
174*b7893ccfSSadaf Ebrahimi`VkPhysicalDeviceLimits::maxBoundDescriptorSets` device limit.
175*b7893ccfSSadaf Ebrahimi
176*b7893ccfSSadaf EbrahimiWhen applications use all the available descriptor set binding slots,
177*b7893ccfSSadaf EbrahimiGPU-Assisted Validation cannot be performed because it needs a descriptor set to
178*b7893ccfSSadaf Ebrahimilocate the memory for writing the error report record.
179*b7893ccfSSadaf Ebrahimi
180*b7893ccfSSadaf EbrahimiThis problem is most likely to occur on devices, often mobile, that support only the
181*b7893ccfSSadaf Ebrahimiminimum required value for `VkPhysicalDeviceLimits::maxBoundDescriptorSets`, which is 4.
182*b7893ccfSSadaf EbrahimiSome applications may be written to use 4 slots since this is the highest value that
183*b7893ccfSSadaf Ebrahimiis guaranteed by the specification.
184*b7893ccfSSadaf EbrahimiWhen such an application using 4 slots runs on a device with only 4 slots,
185*b7893ccfSSadaf Ebrahimithen GPU-Assisted Validation cannot be performed.
186*b7893ccfSSadaf Ebrahimi
187*b7893ccfSSadaf EbrahimiIn this implementation, this condition is detected and gracefully recovered from by
188*b7893ccfSSadaf Ebrahimibuilding the graphics pipeline with non-instrumented shaders instead of instrumented ones.
189*b7893ccfSSadaf EbrahimiAn error message is also displayed informing the user of the condition.
190*b7893ccfSSadaf Ebrahimi
191*b7893ccfSSadaf EbrahimiApplications don't have many options in this situation and it is anticipated that
192*b7893ccfSSadaf Ebrahimichanging the application to free a slot is difficult.
193*b7893ccfSSadaf Ebrahimi
194*b7893ccfSSadaf Ebrahimi### Device Memory
195*b7893ccfSSadaf Ebrahimi
196*b7893ccfSSadaf EbrahimiGPU-Assisted Validation does allocate device memory for the error report buffers, and if
197*b7893ccfSSadaf Ebrahimidescriptor indexing is enabled, for the input buffer of descriptor sizes and write state.
198*b7893ccfSSadaf EbrahimiThis can lead to a greater chance of memory exhaustion, especially in cases where
199*b7893ccfSSadaf Ebrahimithe application is trying to use all of the available memory.
200*b7893ccfSSadaf EbrahimiThe extra memory allocations are also not visible to the application, making it
201*b7893ccfSSadaf Ebrahimiimpossible for the application to account for them.
202*b7893ccfSSadaf Ebrahimi
203*b7893ccfSSadaf EbrahimiNote that if descriptor indexing is enabled, the input buffer size will be equal to
204*b7893ccfSSadaf Ebrahimi(1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count) words of memory where
205*b7893ccfSSadaf Ebrahimibinding_count is the binding number of the largest binding in the set.
206*b7893ccfSSadaf EbrahimiThis means that sparsely populated sets and sets with a very large binding will cause
207*b7893ccfSSadaf Ebrahimithe input buffer to be much larger than it could be with more densely packed binding numbers.
208*b7893ccfSSadaf EbrahimiAs a best practice, when using GPU-Assisted Validation with descriptor indexing enabled,
209*b7893ccfSSadaf Ebrahimimake sure descriptor bindings are densely packed.
210*b7893ccfSSadaf Ebrahimi
211*b7893ccfSSadaf EbrahimiIf GPU-Assisted Validation device memory allocations fail, the device could become
212*b7893ccfSSadaf Ebrahimiunstable because some previously-built pipelines may contain instrumented shaders.
213*b7893ccfSSadaf EbrahimiThis is a condition that is nearly impossible to recover from, so the layer just
214*b7893ccfSSadaf Ebrahimiprints an error message and refrains from any further allocations or instrumentations.
215*b7893ccfSSadaf EbrahimiThere is a reasonable chance to recover from these conditions,
216*b7893ccfSSadaf Ebrahimiespecially if the instrumentation does not write any error records.
217*b7893ccfSSadaf Ebrahimi
218*b7893ccfSSadaf Ebrahimi### Descriptors
219*b7893ccfSSadaf Ebrahimi
220*b7893ccfSSadaf EbrahimiThis is roughly the same problem as the device memory problem mentioned above,
221*b7893ccfSSadaf Ebrahimibut for descriptors.
222*b7893ccfSSadaf EbrahimiAny failure to allocate a descriptor set means that the instrumented shader code
223*b7893ccfSSadaf Ebrahimiwon't have a place to write error records, resulting in unpredictable device
224*b7893ccfSSadaf Ebrahimibehavior.
225*b7893ccfSSadaf Ebrahimi
226*b7893ccfSSadaf Ebrahimi### Other Device Limits
227*b7893ccfSSadaf Ebrahimi
228*b7893ccfSSadaf EbrahimiThis implementation uses additional resources that may count against the following limits,
229*b7893ccfSSadaf Ebrahimiand possibly others:
230*b7893ccfSSadaf Ebrahimi
231*b7893ccfSSadaf Ebrahimi* `maxMemoryAllocationCount`
232*b7893ccfSSadaf Ebrahimi* `maxBoundDescriptorSets`
233*b7893ccfSSadaf Ebrahimi* `maxPerStageDescriptorStorageBuffers`
234*b7893ccfSSadaf Ebrahimi* `maxPerStageResources`
235*b7893ccfSSadaf Ebrahimi* `maxDescriptorSetStorageBuffers`
236*b7893ccfSSadaf Ebrahimi* `maxFragmentCombinedOutputResources`
237*b7893ccfSSadaf Ebrahimi
238*b7893ccfSSadaf EbrahimiThe implementation does not take steps to avoid exceeding these limits
239*b7893ccfSSadaf Ebrahimiand does not update the tracking performed by other validation functions.
240*b7893ccfSSadaf Ebrahimi
241*b7893ccfSSadaf Ebrahimi### A Note About the `VK_EXT_buffer_device_address` Extension
242*b7893ccfSSadaf Ebrahimi
243*b7893ccfSSadaf EbrahimiThe recently introduced `VK_EXT_buffer_device_address` extension can be used
244*b7893ccfSSadaf Ebrahimito implement GPU-Assisted Validation without some of the limitations described above.
245*b7893ccfSSadaf EbrahimiThis approach would use this extension to obtain a GPU device pointer to a storage
246*b7893ccfSSadaf Ebrahimibuffer and make it available to the shader via a specialization constant.
247*b7893ccfSSadaf EbrahimiThis technique removes the need to create descriptors, use a descriptor set slot,
248*b7893ccfSSadaf Ebrahimimodify pipeline layouts, etc, and would relax some of the limitations listed above.
249*b7893ccfSSadaf Ebrahimi
250*b7893ccfSSadaf EbrahimiThis alternate implementation is under consideration.
251*b7893ccfSSadaf Ebrahimi
252*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Internal Design
253*b7893ccfSSadaf Ebrahimi
254*b7893ccfSSadaf EbrahimiThis section may be of interest to readers who are interested on how GPU-Assisted Validation is implemented.
255*b7893ccfSSadaf EbrahimiIt isn't necessarily required for using the feature.
256*b7893ccfSSadaf Ebrahimi
257*b7893ccfSSadaf Ebrahimi### General
258*b7893ccfSSadaf Ebrahimi
259*b7893ccfSSadaf EbrahimiIn general, the implementation does:
260*b7893ccfSSadaf Ebrahimi
261*b7893ccfSSadaf Ebrahimi* For each draw, dispatch, and trace rays call, allocate a buffer with enough device memory to hold a single debug output record written by the
262*b7893ccfSSadaf Ebrahimi    instrumented shader code.
263*b7893ccfSSadaf Ebrahimi    If descriptor indexing is enabled, calculate the amount of memory needed to describe the descriptor arrays sizes and
264*b7893ccfSSadaf Ebrahimi    write states and allocate device memory and a buffer for input to the instrumented shader.
265*b7893ccfSSadaf Ebrahimi    The Vulkan Memory Allocator is used to handle this efficiently.
266*b7893ccfSSadaf Ebrahimi
267*b7893ccfSSadaf Ebrahimi    There is probably little advantage in providing a larger output buffer in order to obtain more debug records.
268*b7893ccfSSadaf Ebrahimi    It is likely, especially for fragment shaders, that multiple errors occurring near each other have the same root cause.
269*b7893ccfSSadaf Ebrahimi
270*b7893ccfSSadaf Ebrahimi    A block is allocated on a per draw basis to make it possible to associate a shader debug error record with
271*b7893ccfSSadaf Ebrahimi    a draw within a command buffer.
272*b7893ccfSSadaf Ebrahimi    This is done partly to give the user more information in the error report, namely the command buffer handle/name and the draw within that command buffer.
273*b7893ccfSSadaf Ebrahimi    An alternative design allocates this block on a per-device or per-queue basis and should work.
274*b7893ccfSSadaf Ebrahimi    However, it is not possible to identify the command buffer that causes the error if multiple command buffers
275*b7893ccfSSadaf Ebrahimi    are submitted at once.
276*b7893ccfSSadaf Ebrahimi* For each draw, dispatch, and trace rays call, allocate a descriptor set and update it to point to the block of device memory just allocated.
277*b7893ccfSSadaf Ebrahimi    If descriptor indexing is enabled, also update the descriptor set to point to the allocated input buffer.
278*b7893ccfSSadaf Ebrahimi    Fill the input buffer with the size and write state information for each descriptor array.
279*b7893ccfSSadaf Ebrahimi    There is a descriptor set manager to handle this efficiently.
280*b7893ccfSSadaf Ebrahimi    Also make an additional call down the chain to create a bind descriptor set command to bind our descriptor set at the desired index.
281*b7893ccfSSadaf Ebrahimi    This has the effect of binding the device memory block belonging to this draw so that the GPU instrumentation
282*b7893ccfSSadaf Ebrahimi    writes into this buffer for when the draw is executed.
283*b7893ccfSSadaf Ebrahimi    The end result is that each draw call has its own buffer containing GPU instrumentation error
284*b7893ccfSSadaf Ebrahimi    records, if any occurred while executing that draw.
285*b7893ccfSSadaf Ebrahimi* Determine the descriptor set binding index that is eventually used to bind the descriptor set just allocated and updated.
286*b7893ccfSSadaf Ebrahimi    Usually, it is `VkPhysicalDeviceLimits::maxBoundDescriptorSets` minus one.
287*b7893ccfSSadaf Ebrahimi    For devices that have a very high or no limit on this bound, pick an index that isn't too high, but above most other device
288*b7893ccfSSadaf Ebrahimi    maxima such as 32.
289*b7893ccfSSadaf Ebrahimi* When creating a ShaderModule, pass the SPIR-V bytecode to the SPIR-V optimizer to perform the instrumentation pass.
290*b7893ccfSSadaf Ebrahimi    Pass the desired descriptor set binding index to the optimizer via a parameter so that the instrumented
291*b7893ccfSSadaf Ebrahimi    code knows which descriptor to use for writing error report data to the memory block.
292*b7893ccfSSadaf Ebrahimi    If descriptor indexing is enabled, turn on OOB and write state checking in the instrumentation pass.
293*b7893ccfSSadaf Ebrahimi    Use the instrumented bytecode to create the ShaderModule.
294*b7893ccfSSadaf Ebrahimi* For all pipeline layouts, add our descriptor set to the layout, at the binding index determined earlier.
295*b7893ccfSSadaf Ebrahimi    Fill any gaps with empty descriptor sets.
296*b7893ccfSSadaf Ebrahimi
297*b7893ccfSSadaf Ebrahimi    If the incoming layout already has a descriptor set placed at our desired index, the layer must not add its
298*b7893ccfSSadaf Ebrahimi    descriptor set to the layout, replacing the one in the incoming layout.
299*b7893ccfSSadaf Ebrahimi    Instead, the layer leaves the layout alone and later replaces the instrumented shaders with
300*b7893ccfSSadaf Ebrahimi    non-instrumented ones when the pipeline layout is later used to create a graphics pipeline.
301*b7893ccfSSadaf Ebrahimi    The layer issues an error message to report this condition.
302*b7893ccfSSadaf Ebrahimi* When creating a GraphicsPipeline, ComputePipeline, or RayTracingPipeline, check to see if the pipeline is using the debug binding index.
303*b7893ccfSSadaf Ebrahimi    If it is, replace the instrumented shaders in the pipeline with non-instrumented ones.
304*b7893ccfSSadaf Ebrahimi* Before calling QueueSubmit, if descriptor indexing is enabled, check to see if there were any unwritten descriptors that were declared
305*b7893ccfSSadaf Ebrahimi    update-after-bind.
306*b7893ccfSSadaf Ebrahimi    If there were, update the write state of those elements.
307*b7893ccfSSadaf Ebrahimi* After calling QueueSubmit, perform a wait on the queue to allow the queue to finish executing.
308*b7893ccfSSadaf Ebrahimi    Then map and examine the device memory block for each draw or trace ray command that was submitted.
309*b7893ccfSSadaf Ebrahimi    If any debug record is found, generate a validation error message for each record found.
310*b7893ccfSSadaf Ebrahimi
311*b7893ccfSSadaf EbrahimiThe above describes only the high-level details of GPU-Assisted Validation operation.
312*b7893ccfSSadaf EbrahimiMore detail is found in the discussion of the individual hooked functions below.
313*b7893ccfSSadaf Ebrahimi
314*b7893ccfSSadaf Ebrahimi### Initialization
315*b7893ccfSSadaf Ebrahimi
316*b7893ccfSSadaf EbrahimiWhen the validation layer loads, it examines the user options from both the layer settings file and the
317*b7893ccfSSadaf Ebrahimi`VK_EXT_validation_features` extension.
318*b7893ccfSSadaf EbrahimiNote that it also processes the subsumed `VK_EXT_validation_flags` extension for simple backwards compatibility.
319*b7893ccfSSadaf EbrahimiFrom these options, the layer sets instance-scope flags in the validation layer tracking data to indicate if
320*b7893ccfSSadaf EbrahimiGPU-Assisted Validation has been requested, along with any other associated options.
321*b7893ccfSSadaf Ebrahimi
322*b7893ccfSSadaf Ebrahimi### "Calling Down the Chain"
323*b7893ccfSSadaf Ebrahimi
324*b7893ccfSSadaf EbrahimiMuch of the GPU-Assisted Validation implementation involves making "application level" Vulkan API
325*b7893ccfSSadaf Ebrahimicalls outside of the application's API usage to create resources and perform its required operations
326*b7893ccfSSadaf Ebrahimiinside of the validation layer.
327*b7893ccfSSadaf EbrahimiThese calls are not routed up through the top of the loader/layer/driver call stack via the loader.
328*b7893ccfSSadaf EbrahimiInstead, they are simply dispatched via the containing layer's dispatch table.
329*b7893ccfSSadaf Ebrahimi
330*b7893ccfSSadaf EbrahimiThese calls therefore don't pass through any validation checks that occur before the gpu validation checks are run.
331*b7893ccfSSadaf EbrahimiThis doesn't present any particular problem, but it does raise some issues:
332*b7893ccfSSadaf Ebrahimi
333*b7893ccfSSadaf Ebrahimi* The additional API calls are not fully validated
334*b7893ccfSSadaf Ebrahimi
335*b7893ccfSSadaf Ebrahimi  This implies that this additional code may never be checked for validation errors.
336*b7893ccfSSadaf Ebrahimi  To address this, the code can "just" be written carefully so that it is "valid" Vulkan,
337*b7893ccfSSadaf Ebrahimi  which is hard to do.
338*b7893ccfSSadaf Ebrahimi
339*b7893ccfSSadaf Ebrahimi  Or, this code can be checked by loading a khronos validation layer with
340*b7893ccfSSadaf Ebrahimi  GPU validation enabled on top of "normal" standard validation in the
341*b7893ccfSSadaf Ebrahimi  layer stack, which effectively validates the API usage of this code.
342*b7893ccfSSadaf Ebrahimi  This sort of checking is performed by layer developers to check that the additional
343*b7893ccfSSadaf Ebrahimi  Vulkan usage is valid.
344*b7893ccfSSadaf Ebrahimi
345*b7893ccfSSadaf Ebrahimi  This validation can be accomplished by:
346*b7893ccfSSadaf Ebrahimi
347*b7893ccfSSadaf Ebrahimi  * Building the validation layer with a hack to force GPU-Assisted Validation to be enabled.
348*b7893ccfSSadaf Ebrahimi  Can't use the exposed mechanisms because we probably don't want it on twice.
349*b7893ccfSSadaf Ebrahimi  * Rename this layer binary to something else like "khronos_validation2" to keep it apart from the
350*b7893ccfSSadaf Ebrahimi  "normal" khronos validation.
351*b7893ccfSSadaf Ebrahimi  * Create a new JSON file with the new layer name.
352*b7893ccfSSadaf Ebrahimi  * Set up the layer stack so that the "khronos_validation2" layer is on top of or before the actual khronos
353*b7893ccfSSadaf Ebrahimi    validation layer
354*b7893ccfSSadaf Ebrahimi  * Then run tests and check for validation errors pointing to API usage in the "khronos_validation2" layer.
355*b7893ccfSSadaf Ebrahimi
356*b7893ccfSSadaf Ebrahimi  This should only need to be done after making any major changes to the implementation.
357*b7893ccfSSadaf Ebrahimi
358*b7893ccfSSadaf Ebrahimi  Another approach involves capturing an application trace with `vktrace` and then playing
359*b7893ccfSSadaf Ebrahimi  it back with `vkreplay`.
360*b7893ccfSSadaf Ebrahimi
361*b7893ccfSSadaf Ebrahimi* The additional API calls are not state-tracked
362*b7893ccfSSadaf Ebrahimi
363*b7893ccfSSadaf Ebrahimi  This means that things like device memory allocations and descriptor allocations are not
364*b7893ccfSSadaf Ebrahimi  tracked and do not show up in any of the bookkeeping performed by the validation layers.
365*b7893ccfSSadaf Ebrahimi  For example, any device memory allocation performed by GPU-Assisted Validation won't be
366*b7893ccfSSadaf Ebrahimi  counted towards the maximum number of allocations allowed by a device.
367*b7893ccfSSadaf Ebrahimi  This could lead to an early allocation failure that is not accompanied by a validation error.
368*b7893ccfSSadaf Ebrahimi
369*b7893ccfSSadaf Ebrahimi  This shortcoming is left as not addressed in this implementation because it is anticipated that
370*b7893ccfSSadaf Ebrahimi  a later implementation of GPU-Assisted Validation using the `VK_EXT_buffer_device_address`
371*b7893ccfSSadaf Ebrahimi  extension will have less of a need to allocate these
372*b7893ccfSSadaf Ebrahimi  tracked resources and it therefore becomes less of an issue.
373*b7893ccfSSadaf Ebrahimi
374*b7893ccfSSadaf Ebrahimi### Code Structure and Relationship to the Core Validation Layer
375*b7893ccfSSadaf Ebrahimi
376*b7893ccfSSadaf EbrahimiThe GPU-Assisted Validation code is largely contained in one
377*b7893ccfSSadaf Ebrahimi[file](https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/master/layers/gpu_validation.cpp), with "hooks" in
378*b7893ccfSSadaf Ebrahimithe other validation code that call functions in this file.
379*b7893ccfSSadaf EbrahimiThese hooks in the validation code look something like this:
380*b7893ccfSSadaf Ebrahimi
381*b7893ccfSSadaf Ebrahimi```C
382*b7893ccfSSadaf Ebrahimiif (GetEnables(dev_data)->gpu_validation) {
383*b7893ccfSSadaf Ebrahimi    GpuPreCallRecordDestroyPipeline(dev_data, pipeline_state);
384*b7893ccfSSadaf Ebrahimi}
385*b7893ccfSSadaf Ebrahimi```
386*b7893ccfSSadaf Ebrahimi
387*b7893ccfSSadaf EbrahimiThe GPU-Assisted Validation code is linked into the shared library for the khronos and core validation layers.
388*b7893ccfSSadaf Ebrahimi
389*b7893ccfSSadaf Ebrahimi#### Review of Khronos Validation Code Structure
390*b7893ccfSSadaf Ebrahimi
391*b7893ccfSSadaf EbrahimiEach function for a Vulkan API command intercepted in the khronos validation layer is usually split up
392*b7893ccfSSadaf Ebrahimiinto several decomposed functions in order to organize the implementation.
393*b7893ccfSSadaf EbrahimiThese functions take the form of:
394*b7893ccfSSadaf Ebrahimi
395*b7893ccfSSadaf Ebrahimi* PreCallValidate&lt;foo&gt;: Perform validation steps before calling down the chain
396*b7893ccfSSadaf Ebrahimi* PostCallValidate&lt;foo&gt;: Perform validation steps after calling down the chain
397*b7893ccfSSadaf Ebrahimi* PreCallRecord&lt;foo&gt;: Perform state recording before calling down the chain
398*b7893ccfSSadaf Ebrahimi* PostCallRecord&lt;foo&gt;: Perform state recording after calling down the chain
399*b7893ccfSSadaf Ebrahimi
400*b7893ccfSSadaf EbrahimiThe GPU-Assisted Validation functions follow this pattern not by hooking into the top-level validation API shim, but
401*b7893ccfSSadaf Ebrahimiby hooking one of these decomposed functions.
402*b7893ccfSSadaf Ebrahimi
403*b7893ccfSSadaf EbrahimiThe design of each hooked function follows:
404*b7893ccfSSadaf Ebrahimi
405*b7893ccfSSadaf Ebrahimi#### GpuPreCallRecordCreateDevice
406*b7893ccfSSadaf Ebrahimi
407*b7893ccfSSadaf Ebrahimi* Modify the `VkPhysicalDeviceFeatures` to turn on two additional physical device features:
408*b7893ccfSSadaf Ebrahimi  * `fragmentStoresAndAtomics`
409*b7893ccfSSadaf Ebrahimi  * `vertexPipelineStoresAndAtomics`
410*b7893ccfSSadaf Ebrahimi
411*b7893ccfSSadaf Ebrahimi#### GpuPostCallRecordCreateDevice
412*b7893ccfSSadaf Ebrahimi
413*b7893ccfSSadaf Ebrahimi* Determine and record (save in device state) the desired descriptor set binding index.
414*b7893ccfSSadaf Ebrahimi* Initialize Vulkan Memory Allocator
415*b7893ccfSSadaf Ebrahimi  * Determine error record block size based on the maximum size of the error record and alignment limits of the device.
416*b7893ccfSSadaf Ebrahimi* Initialize descriptor set manager
417*b7893ccfSSadaf Ebrahimi* Make a descriptor set layout to describe our descriptor set
418*b7893ccfSSadaf Ebrahimi* Make a descriptor set layout to describe a "dummy" descriptor set that contains no descriptors
419*b7893ccfSSadaf Ebrahimi  * This is used to "pad" pipeline layouts to fill any gaps between the used bind indices and our bind index
420*b7893ccfSSadaf Ebrahimi* Record these objects in the per-device state
421*b7893ccfSSadaf Ebrahimi
422*b7893ccfSSadaf Ebrahimi#### GpuPreCallRecordDestroyDevice
423*b7893ccfSSadaf Ebrahimi
424*b7893ccfSSadaf Ebrahimi* Destroy descriptor set layouts created in CreateDevice
425*b7893ccfSSadaf Ebrahimi* Clean up descriptor set manager
426*b7893ccfSSadaf Ebrahimi* Clean up Vulkan Memory Allocator (VMA)
427*b7893ccfSSadaf Ebrahimi* Clean up device state
428*b7893ccfSSadaf Ebrahimi
429*b7893ccfSSadaf Ebrahimi#### GpuAllocateValidationResources
430*b7893ccfSSadaf Ebrahimi
431*b7893ccfSSadaf Ebrahimi* For each Draw, Dispatch, or TraceRays call:
432*b7893ccfSSadaf Ebrahimi  * Get a descriptor set from the descriptor set manager
433*b7893ccfSSadaf Ebrahimi  * Get an output buffer and associated memory from VMA
434*b7893ccfSSadaf Ebrahimi  * If descriptor indexing is enabled, get an input buffer and fill with descriptor array information
435*b7893ccfSSadaf Ebrahimi  * Update (write) the descriptor set with the memory info
436*b7893ccfSSadaf Ebrahimi  * Check to see if the layout for the pipeline just bound is using our selected bind index
437*b7893ccfSSadaf Ebrahimi  * If no conflict, add an additional command to the command buffer to bind our descriptor set at our selected index
438*b7893ccfSSadaf Ebrahimi* Record the above objects in the per-CB state
439*b7893ccfSSadaf EbrahimiNote that the Draw and Dispatch calls include vkCmdDraw, vkCmdDrawIndexed, vkCmdDrawIndirect, vkCmdDrawIndexedIndirect, vkCmdDispatch, vkCmdDispatchIndirect, and vkCmdTraceRaysNV.
440*b7893ccfSSadaf Ebrahimi
441*b7893ccfSSadaf Ebrahimi#### GpuPreCallRecordFreeCommandBuffers
442*b7893ccfSSadaf Ebrahimi
443*b7893ccfSSadaf Ebrahimi* For each command buffer:
444*b7893ccfSSadaf Ebrahimi  * Destroy the VMA buffer(s), releasing the memory
445*b7893ccfSSadaf Ebrahimi  * Give the descriptor sets back to the descriptor set manager
446*b7893ccfSSadaf Ebrahimi  * Clean up CB state
447*b7893ccfSSadaf Ebrahimi
448*b7893ccfSSadaf Ebrahimi#### GpuOverrideDispatchCreateShaderModule
449*b7893ccfSSadaf Ebrahimi
450*b7893ccfSSadaf EbrahimiThis function is called from PreCallRecordCreateShaderModule.
451*b7893ccfSSadaf EbrahimiThis routine sets up to call the SPIR-V optimizer to run the "BindlessCheckPass", replacing the original SPIR-V with the instrumented SPIR-V
452*b7893ccfSSadaf Ebrahimiwhich is then used in the call down the chain to CreateShaderModule.
453*b7893ccfSSadaf Ebrahimi
454*b7893ccfSSadaf EbrahimiThis function generates a "unique shader ID" that is passed to the SPIR-V optimizer,
455*b7893ccfSSadaf Ebrahimiwhich the instrumented code puts in the debug error record to identify the shader.
456*b7893ccfSSadaf EbrahimiThis ID is returned by this function so it can be recorded in the shader module at PostCallRecord time.
457*b7893ccfSSadaf EbrahimiIt would have been convenient to use the shader module handle returned from the driver to use as this shader ID.
458*b7893ccfSSadaf EbrahimiBut the shader needs to be instrumented before creating the shader module and therefore the handle is not available to use
459*b7893ccfSSadaf Ebrahimias this ID to pass to the optimizer.
460*b7893ccfSSadaf EbrahimiTherefore, the layer keeps a "counter" in per-device state that is incremented each time a shader is instrumented
461*b7893ccfSSadaf Ebrahimito generate unique IDs.
462*b7893ccfSSadaf EbrahimiThis unique ID is given to the SPIR-V optimizer and is stored in the shader module state tracker after the shader module is created, which creates the necessary association between the ID and the shader module.
463*b7893ccfSSadaf Ebrahimi
464*b7893ccfSSadaf EbrahimiThe process of instrumenting the SPIR-V also includes passing the selected descriptor set binding index
465*b7893ccfSSadaf Ebrahimito the SPIR-V optimizer which the instrumented
466*b7893ccfSSadaf Ebrahimicode uses to locate the memory block used to write the debug error record.
467*b7893ccfSSadaf EbrahimiAn instrumented shader is now "hard-wired" to write error records via the descriptor set at that binding
468*b7893ccfSSadaf Ebrahimiif it detects an error.
469*b7893ccfSSadaf EbrahimiThis implies that the instrumented shaders should only be allowed to run when the correct bindings are in place.
470*b7893ccfSSadaf Ebrahimi
471*b7893ccfSSadaf EbrahimiThe original SPIR-V bytecode is left stored in the shader module tracking data.
472*b7893ccfSSadaf EbrahimiThis is important because the layer may need to replace the instrumented shader with the original shader if, for example,
473*b7893ccfSSadaf Ebrahimithere is a binding index conflict.
474*b7893ccfSSadaf EbrahimiThe application cannot destroy the shader module until it has used the shader module to create the pipeline.
475*b7893ccfSSadaf EbrahimiThis ensures that the original SPIR-V bytecode is available if we need it to replace the instrumented shader.
476*b7893ccfSSadaf Ebrahimi
477*b7893ccfSSadaf Ebrahimi#### GpuOverrideDispatchCreatePipelineLayout
478*b7893ccfSSadaf Ebrahimi
479*b7893ccfSSadaf EbrahimiThis is function is called through PreCallRecordCreatePipelineLayout.
480*b7893ccfSSadaf Ebrahimi
481*b7893ccfSSadaf Ebrahimi* Check for a descriptor set binding index conflict.
482*b7893ccfSSadaf Ebrahimi  * If there is one, issue an error message and leave the pipeline layout unmodified
483*b7893ccfSSadaf Ebrahimi  * If no conflict, for each pipeline layout:
484*b7893ccfSSadaf Ebrahimi    * Create a new pipeline layout
485*b7893ccfSSadaf Ebrahimi    * Copy the original descriptor set layouts into the new pipeline layout
486*b7893ccfSSadaf Ebrahimi    * Pad the new pipeline layout with dummy descriptor set layouts up to but not including the last one
487*b7893ccfSSadaf Ebrahimi    * Add our descriptor set layout as the last one in the new pipeline layout
488*b7893ccfSSadaf Ebrahimi* Create the pipeline layouts by calling down the chain with the original or modified create info
489*b7893ccfSSadaf Ebrahimi
490*b7893ccfSSadaf Ebrahimi#### GpuPreCallQueueSubmit
491*b7893ccfSSadaf Ebrahimi
492*b7893ccfSSadaf Ebrahimi* For each primary and secondary command buffer in the submission:
493*b7893ccfSSadaf Ebrahimi  * Call helper function to see if there are any update after bind descriptors whose write state may need to be updated
494*b7893ccfSSadaf Ebrahimi    and if so, map the input buffer and update the state.
495*b7893ccfSSadaf Ebrahimi
496*b7893ccfSSadaf Ebrahimi#### GpuPostCallQueueSubmit
497*b7893ccfSSadaf Ebrahimi
498*b7893ccfSSadaf Ebrahimi* Submit a command buffer containing a memory barrier to make GPU writes available to the host domain.
499*b7893ccfSSadaf Ebrahimi* Call QueueWaitIdle.
500*b7893ccfSSadaf Ebrahimi* For each primary and secondary command buffer in the submission:
501*b7893ccfSSadaf Ebrahimi  * Call a helper function to process the instrumentation debug buffers (described later)
502*b7893ccfSSadaf Ebrahimi
503*b7893ccfSSadaf Ebrahimi#### GpuPreCallValidateCmdWaitEvents
504*b7893ccfSSadaf Ebrahimi
505*b7893ccfSSadaf Ebrahimi* Report an error about a possible deadlock if CmdWaitEvents is recorded with VK_PIPELINE_STAGE_HOST_BIT set.
506*b7893ccfSSadaf Ebrahimi
507*b7893ccfSSadaf Ebrahimi#### GpuPreCallRecordCreateGraphicsPipelines
508*b7893ccfSSadaf Ebrahimi
509*b7893ccfSSadaf Ebrahimi* Examine the pipelines to see if any use the debug descriptor set binding index
510*b7893ccfSSadaf Ebrahimi* For those that do:
511*b7893ccfSSadaf Ebrahimi  * Create non-instrumented shader modules from the saved original SPIR-V
512*b7893ccfSSadaf Ebrahimi  * Modify the CreateInfo data to use these non-instrumented shaders.
513*b7893ccfSSadaf Ebrahimi    * This prevents instrumented shaders from using the application's descriptor set.
514*b7893ccfSSadaf Ebrahimi
515*b7893ccfSSadaf Ebrahimi#### GpuPostCallRecordCreateGraphicsPipelines
516*b7893ccfSSadaf Ebrahimi
517*b7893ccfSSadaf Ebrahimi* For every shader in the pipeline:
518*b7893ccfSSadaf Ebrahimi  * Destroy the shader module created in GpuPreCallRecordCreateGraphicsPipelines, if any
519*b7893ccfSSadaf Ebrahimi    * These are found in the CreateInfo used to create the pipeline and not in the shader_module
520*b7893ccfSSadaf Ebrahimi  * Create a shader tracking record that saves:
521*b7893ccfSSadaf Ebrahimi    * shader module handle
522*b7893ccfSSadaf Ebrahimi    * unique shader id
523*b7893ccfSSadaf Ebrahimi    * graphics pipeline handle
524*b7893ccfSSadaf Ebrahimi    * shader bytecode if it contains debug info
525*b7893ccfSSadaf Ebrahimi
526*b7893ccfSSadaf EbrahimiThis tracker is used to attach the shader bytecode to the shader in case it is needed
527*b7893ccfSSadaf Ebrahimilater to get the shader source code debug info.
528*b7893ccfSSadaf Ebrahimi
529*b7893ccfSSadaf EbrahimiThe current shader module tracker in the validation code stores the bytecode,
530*b7893ccfSSadaf Ebrahimibut this tracker has the same life cycle as the shader module itself.
531*b7893ccfSSadaf EbrahimiIt is possible for the application to destroy the shader module after
532*b7893ccfSSadaf Ebrahimicreating graphics pipeline and before submitting work that uses the shader,
533*b7893ccfSSadaf Ebrahimimaking the shader bytecode unavailable if needed for later analysis.
534*b7893ccfSSadaf EbrahimiTherefore, the bytecode must be saved at this opportunity.
535*b7893ccfSSadaf Ebrahimi
536*b7893ccfSSadaf EbrahimiThis tracker exists as long as the graphics pipeline exists,
537*b7893ccfSSadaf Ebrahimiso the graphics pipeline handle is also stored in this tracker so that it can
538*b7893ccfSSadaf Ebrahimibe looked up when the graphics pipeline is destroyed.
539*b7893ccfSSadaf EbrahimiAt that point, it is safe to free the bytecode since the pipeline is never used again.
540*b7893ccfSSadaf Ebrahimi
541*b7893ccfSSadaf Ebrahimi#### GpuPreCallRecordDestroyPipeline
542*b7893ccfSSadaf Ebrahimi
543*b7893ccfSSadaf Ebrahimi* Find the shader tracker(s) with the graphics pipeline handle and free the tracker, along with any bytecode it has stored in it.
544*b7893ccfSSadaf Ebrahimi
545*b7893ccfSSadaf Ebrahimi### Shader Instrumentation Scope
546*b7893ccfSSadaf Ebrahimi
547*b7893ccfSSadaf EbrahimiThe shader instrumentation process performed by the SPIR-V optimizer applies descriptor index bounds checking
548*b7893ccfSSadaf Ebrahimito descriptors of the following types:
549*b7893ccfSSadaf Ebrahimi
550*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
551*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
552*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
553*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
554*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
555*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
556*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
557*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
558*b7893ccfSSadaf Ebrahimi    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
559*b7893ccfSSadaf Ebrahimi
560*b7893ccfSSadaf EbrahimiInstrumentation is applied to the following SPIR-V operations:
561*b7893ccfSSadaf Ebrahimi
562*b7893ccfSSadaf Ebrahimi    OpImageSampleImplicitLod
563*b7893ccfSSadaf Ebrahimi    OpImageSampleExplicitLod
564*b7893ccfSSadaf Ebrahimi    OpImageSampleDrefImplicitLod
565*b7893ccfSSadaf Ebrahimi    OpImageSampleDrefExplicitLod
566*b7893ccfSSadaf Ebrahimi    OpImageSampleProjImplicitLod
567*b7893ccfSSadaf Ebrahimi    OpImageSampleProjExplicitLod
568*b7893ccfSSadaf Ebrahimi    OpImageSampleProjDrefImplicitLod
569*b7893ccfSSadaf Ebrahimi    OpImageSampleProjDrefExplicitLod
570*b7893ccfSSadaf Ebrahimi    OpImageGather
571*b7893ccfSSadaf Ebrahimi    OpImageDrefGather
572*b7893ccfSSadaf Ebrahimi    OpImageQueryLod
573*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleImplicitLod
574*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleExplicitLod
575*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleDrefImplicitLod
576*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleDrefExplicitLod
577*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleProjImplicitLod
578*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleProjExplicitLod
579*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleProjDrefImplicitLod
580*b7893ccfSSadaf Ebrahimi    OpImageSparseSampleProjDrefExplicitLod
581*b7893ccfSSadaf Ebrahimi    OpImageSparseGather
582*b7893ccfSSadaf Ebrahimi    OpImageSparseDrefGather
583*b7893ccfSSadaf Ebrahimi    OpImageFetch
584*b7893ccfSSadaf Ebrahimi    OpImageRead
585*b7893ccfSSadaf Ebrahimi    OpImageQueryFormat
586*b7893ccfSSadaf Ebrahimi    OpImageQueryOrder
587*b7893ccfSSadaf Ebrahimi    OpImageQuerySizeLod
588*b7893ccfSSadaf Ebrahimi    OpImageQuerySize
589*b7893ccfSSadaf Ebrahimi    OpImageQueryLevels
590*b7893ccfSSadaf Ebrahimi    OpImageQuerySamples
591*b7893ccfSSadaf Ebrahimi    OpImageSparseFetch
592*b7893ccfSSadaf Ebrahimi    OpImageSparseRead
593*b7893ccfSSadaf Ebrahimi    OpImageWrite
594*b7893ccfSSadaf Ebrahimi
595*b7893ccfSSadaf EbrahimiAlso, OpLoad and OpStore with an AccessChain into a base of OpVariable with
596*b7893ccfSSadaf Ebrahimieither Uniform or StorageBuffer storage class and a type which is either a
597*b7893ccfSSadaf Ebrahimistruct decorated with Block, or a runtime or statically-sized array of such
598*b7893ccfSSadaf Ebrahimia struct.
599*b7893ccfSSadaf Ebrahimi
600*b7893ccfSSadaf Ebrahimi
601*b7893ccfSSadaf Ebrahimi### Shader Instrumentation Error Record Format
602*b7893ccfSSadaf Ebrahimi
603*b7893ccfSSadaf EbrahimiThe instrumented shader code generates "error records" in a specific format.
604*b7893ccfSSadaf Ebrahimi
605*b7893ccfSSadaf EbrahimiThis description includes the support for future GPU-Assisted Validation features
606*b7893ccfSSadaf Ebrahimisuch as checking for uninitialized descriptors in the partially-bound scenario.
607*b7893ccfSSadaf EbrahimiThese items are not used in the current implementation for descriptor array
608*b7893ccfSSadaf Ebrahimibounds checking, but are provided here to complete the description of the
609*b7893ccfSSadaf Ebrahimierror record format.
610*b7893ccfSSadaf Ebrahimi
611*b7893ccfSSadaf EbrahimiThe format of this buffer is as follows:
612*b7893ccfSSadaf Ebrahimi
613*b7893ccfSSadaf Ebrahimi```C
614*b7893ccfSSadaf Ebrahimistruct DebugOutputBuffer_t
615*b7893ccfSSadaf Ebrahimi{
616*b7893ccfSSadaf Ebrahimi   uint DataWrittenLength;
617*b7893ccfSSadaf Ebrahimi   uint Data[];
618*b7893ccfSSadaf Ebrahimi}
619*b7893ccfSSadaf Ebrahimi```
620*b7893ccfSSadaf Ebrahimi
621*b7893ccfSSadaf Ebrahimi`DataWrittenLength` is the number of uint32_t words that have been attempted to be written.
622*b7893ccfSSadaf EbrahimiIt should be initialized to 0.
623*b7893ccfSSadaf Ebrahimi
624*b7893ccfSSadaf EbrahimiThe `Data` array is the uint32_t words written by the shaders of the pipeline to record bindless validation errors.
625*b7893ccfSSadaf EbrahimiAll elements of `Data` should be initialized to 0.
626*b7893ccfSSadaf EbrahimiNote that the `Data` array has runtime length.
627*b7893ccfSSadaf EbrahimiThe shader queries the length of the `Data` array to make sure that it does not write past the end of `Data`.
628*b7893ccfSSadaf EbrahimiThe shader only writes complete records.
629*b7893ccfSSadaf EbrahimiThe layer uses the length of `Data` to control the number of records written by the shaders.
630*b7893ccfSSadaf Ebrahimi
631*b7893ccfSSadaf EbrahimiThe `DataWrittenLength` is atomically updated by the shaders so that shaders do not overwrite each others data.
632*b7893ccfSSadaf EbrahimiThe shader takes the value it gets from the atomic update.
633*b7893ccfSSadaf EbrahimiIf the value plus the record length is greater than the length of `Data`, it does not write the record.
634*b7893ccfSSadaf Ebrahimi
635*b7893ccfSSadaf EbrahimiGiven this protocol, the value in `DataWrittenLength` is not very meaningful if it is greater than the length of `Data`.
636*b7893ccfSSadaf EbrahimiHowever, the format of the written records plus the fact that `Data` is initialized to 0 should be enough to determine
637*b7893ccfSSadaf Ebrahimithe records that were written.
638*b7893ccfSSadaf Ebrahimi
639*b7893ccfSSadaf Ebrahimi### Record Format
640*b7893ccfSSadaf Ebrahimi
641*b7893ccfSSadaf EbrahimiThe format of an output record is the following:
642*b7893ccfSSadaf Ebrahimi
643*b7893ccfSSadaf Ebrahimi    Word 0: Record size
644*b7893ccfSSadaf Ebrahimi    Word 1: Shader ID
645*b7893ccfSSadaf Ebrahimi    Word 2: Instruction Index
646*b7893ccfSSadaf Ebrahimi    Word 3: Stage
647*b7893ccfSSadaf Ebrahimi    <Stage-Specific Words>
648*b7893ccfSSadaf Ebrahimi    <Validation-Specific Words>
649*b7893ccfSSadaf Ebrahimi
650*b7893ccfSSadaf EbrahimiThe Record Size is the number of words in this record, including the the Record Size.
651*b7893ccfSSadaf Ebrahimi
652*b7893ccfSSadaf EbrahimiThe Shader ID is a handle that was provided by the layer when the shader was instrumented.
653*b7893ccfSSadaf Ebrahimi
654*b7893ccfSSadaf EbrahimiThe Instruction Index is the instruction within the original function at which the error occurred.
655*b7893ccfSSadaf EbrahimiFor bindless, this will be the instruction which consumes the descriptor in question,
656*b7893ccfSSadaf Ebrahimior the instruction that consumes the OpSampledImage that consumes the descriptor.
657*b7893ccfSSadaf Ebrahimi
658*b7893ccfSSadaf EbrahimiThe Stage is the integer value used in SPIR-V for each of the Execution Models:
659*b7893ccfSSadaf Ebrahimi
660*b7893ccfSSadaf Ebrahimi| Stage         | Value |
661*b7893ccfSSadaf Ebrahimi|---------------|:-----:|
662*b7893ccfSSadaf Ebrahimi|Vertex         |0      |
663*b7893ccfSSadaf Ebrahimi|TessCtrl       |1      |
664*b7893ccfSSadaf Ebrahimi|TessEval       |2      |
665*b7893ccfSSadaf Ebrahimi|Geometry       |3      |
666*b7893ccfSSadaf Ebrahimi|Fragment       |4      |
667*b7893ccfSSadaf Ebrahimi|Compute        |5      |
668*b7893ccfSSadaf Ebrahimi|RayGenerationNV|5313   |
669*b7893ccfSSadaf Ebrahimi|IntersectionNV |5314   |
670*b7893ccfSSadaf Ebrahimi|AnyHitNV       |5315   |
671*b7893ccfSSadaf Ebrahimi|ClosestHitNV   |5316   |
672*b7893ccfSSadaf Ebrahimi|MissNV         |5317   |
673*b7893ccfSSadaf Ebrahimi|CallableNV     |5318   |
674*b7893ccfSSadaf Ebrahimi
675*b7893ccfSSadaf Ebrahimi### Stage Specific Words
676*b7893ccfSSadaf Ebrahimi
677*b7893ccfSSadaf EbrahimiThese are words that identify which "instance" of the shader the validation error occurred in.
678*b7893ccfSSadaf EbrahimiHere are words for each stage:
679*b7893ccfSSadaf Ebrahimi
680*b7893ccfSSadaf Ebrahimi| Stage         | Word 0           | Word 1     | World 2    |
681*b7893ccfSSadaf Ebrahimi|---------------|------------------|------------|------------|
682*b7893ccfSSadaf Ebrahimi|Vertex         |VertexID          |InstanceID  | unused     |
683*b7893ccfSSadaf Ebrahimi|Tess*          |InvocationID      |unused      | unused     |
684*b7893ccfSSadaf Ebrahimi|Geometry       |PrimitiveID       |InvocationID| unused     |
685*b7893ccfSSadaf Ebrahimi|Fragment       |FragCoord.x       |FragCoord.y | unused     |
686*b7893ccfSSadaf Ebrahimi|Compute        |GlobalInvocationID|unused      | unused     |
687*b7893ccfSSadaf Ebrahimi|RayGenerationNV|LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
688*b7893ccfSSadaf Ebrahimi|IntersectionNV |LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
689*b7893ccfSSadaf Ebrahimi|AnyHitNV       |LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
690*b7893ccfSSadaf Ebrahimi|ClosestHitNV   |LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
691*b7893ccfSSadaf Ebrahimi|MissNV         |LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
692*b7893ccfSSadaf Ebrahimi|CallableNV     |LaunchIdNV.x      |LaunchIdNV.y|LaunchIdNV.z|
693*b7893ccfSSadaf Ebrahimi
694*b7893ccfSSadaf Ebrahimi"unused" means not relevant, but still present.
695*b7893ccfSSadaf Ebrahimi
696*b7893ccfSSadaf Ebrahimi### Validation-Specific Words
697*b7893ccfSSadaf Ebrahimi
698*b7893ccfSSadaf EbrahimiThese are words that are specific to the validation being done.
699*b7893ccfSSadaf EbrahimiFor bindless validation, they are variable.
700*b7893ccfSSadaf Ebrahimi
701*b7893ccfSSadaf EbrahimiThe first word is the Error Code.
702*b7893ccfSSadaf Ebrahimi
703*b7893ccfSSadaf EbrahimiFor the *OutOfBounds errors, two words will follow: Word0:DescriptorIndex, Word1:DescriptorArrayLength
704*b7893ccfSSadaf Ebrahimi
705*b7893ccfSSadaf EbrahimiFor the *Uninitialized errors, one word will follow: Word0:DescriptorIndex
706*b7893ccfSSadaf Ebrahimi
707*b7893ccfSSadaf Ebrahimi| Error                       | Code | Word 0         | Word 1                |
708*b7893ccfSSadaf Ebrahimi|-----------------------------|:----:|----------------|-----------------------|
709*b7893ccfSSadaf Ebrahimi|IndexOutOfBounds             |0     |Descriptor Index|Descriptor Array Length|
710*b7893ccfSSadaf Ebrahimi|DescriptorUninitialized      |1     |Descriptor Index|unused                 |
711*b7893ccfSSadaf Ebrahimi
712*b7893ccfSSadaf EbrahimiSo the words written for an image descriptor bounds error in a fragment shader is:
713*b7893ccfSSadaf Ebrahimi
714*b7893ccfSSadaf Ebrahimi    Word 0: Record size (9)
715*b7893ccfSSadaf Ebrahimi    Word 1: Shader ID
716*b7893ccfSSadaf Ebrahimi    Word 2: Instruction Index
717*b7893ccfSSadaf Ebrahimi    Word 3: Stage (4:Fragment)
718*b7893ccfSSadaf Ebrahimi    Word 4: FragCoord.x
719*b7893ccfSSadaf Ebrahimi    Word 5: FragCoord.y
720*b7893ccfSSadaf Ebrahimi    Word 6: Error (0: ImageIndexOutOfBounds)
721*b7893ccfSSadaf Ebrahimi    Word 7: DescriptorIndex
722*b7893ccfSSadaf Ebrahimi    Word 8: DescriptorArrayLength
723*b7893ccfSSadaf Ebrahimi
724*b7893ccfSSadaf EbrahimiIf another error is encountered, that record is written starting at Word 10, if the whole record will not overflow Data.
725*b7893ccfSSadaf EbrahimiIf overflow will happen, no words are written..
726*b7893ccfSSadaf Ebrahimi
727*b7893ccfSSadaf EbrahimiThe validation layer can continue to read valid records until it sees a Record Length of 0 or the end of Data is reached.
728*b7893ccfSSadaf Ebrahimi
729*b7893ccfSSadaf Ebrahimi#### Programmatic interface
730*b7893ccfSSadaf Ebrahimi
731*b7893ccfSSadaf EbrahimiThe programmatic interface for the above informal description is codified in the
732*b7893ccfSSadaf Ebrahimi[SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) repository in file
733*b7893ccfSSadaf Ebrahimi[`instrument.hpp`](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/include/spirv-tools/instrument.hpp).
734*b7893ccfSSadaf EbrahimiIt consists largely of integer constant definitions for the codes and values mentioned above and
735*b7893ccfSSadaf Ebrahimioffsets into the record for locating each item.
736*b7893ccfSSadaf Ebrahimi
737*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Error Report
738*b7893ccfSSadaf Ebrahimi
739*b7893ccfSSadaf EbrahimiThis is a fairly simple process of mapping the debug report buffer associated with
740*b7893ccfSSadaf Ebrahimieach draw in the command buffer that was just submitted and looking to see if the GPU instrumentation
741*b7893ccfSSadaf Ebrahimicode wrote anything.
742*b7893ccfSSadaf EbrahimiEach draw in the command buffer should have a corresponding result buffer in the command buffer's list of result buffers.
743*b7893ccfSSadaf EbrahimiThe report generating code loops through the result buffers, maps each of them, checks for errors, and unmaps them.
744*b7893ccfSSadaf EbrahimiThe layer clears the buffer to zeros when it is allocated and after processing any
745*b7893ccfSSadaf Ebrahimibuffer that was written to.
746*b7893ccfSSadaf EbrahimiThe instrumented shader code expects these buffers to be cleared to zeros before it
747*b7893ccfSSadaf Ebrahimiwrites to them.
748*b7893ccfSSadaf Ebrahimi
749*b7893ccfSSadaf EbrahimiThe layer then prepares a "common" validation error message containing:
750*b7893ccfSSadaf Ebrahimi
751*b7893ccfSSadaf Ebrahimi* command buffer handle - This is easily obtained because we are looping over the command
752*b7893ccfSSadaf Ebrahimi  buffers just submitted.
753*b7893ccfSSadaf Ebrahimi* draw number - keep track of how many draws we've processed for a given command buffer.
754*b7893ccfSSadaf Ebrahimi* pipeline handle - The shader tracker discussed earlier contains this handle
755*b7893ccfSSadaf Ebrahimi* shader module handle - The "Shader ID" (Word 1 in the record) is used to lookup
756*b7893ccfSSadaf Ebrahimi  the shader tracker which is then used to obtain the shader module and pipeline handles
757*b7893ccfSSadaf Ebrahimi* instruction index - This is the SPIR-V instruction index where the invalid array access occurred.
758*b7893ccfSSadaf Ebrahimi  It is not that useful by itself, since the user would have to use it to locate a SPIR-V instruction
759*b7893ccfSSadaf Ebrahimi  in a SPIR-V disassembly and somehow relate it back to the shader source code.
760*b7893ccfSSadaf Ebrahimi  But it could still be useful to some and it is easy to report.
761*b7893ccfSSadaf Ebrahimi  The user can build the shader with debug information to get source-level information.
762*b7893ccfSSadaf Ebrahimi
763*b7893ccfSSadaf EbrahimiFor all objects, the layer also looks up the objects in the Debug Utils object name map in
764*b7893ccfSSadaf Ebrahimicase the application used that extension to name any objects.
765*b7893ccfSSadaf EbrahimiIf a name exists for that object, it is included in the error message.
766*b7893ccfSSadaf Ebrahimi
767*b7893ccfSSadaf EbrahimiThe layer then adds on error message text obtained from decoding the stage-specific and
768*b7893ccfSSadaf Ebrahimivalidation-specific data as described earlier.
769*b7893ccfSSadaf Ebrahimi
770*b7893ccfSSadaf EbrahimiThis completes the error report when there is no source-level debug information in the shader.
771*b7893ccfSSadaf Ebrahimi
772*b7893ccfSSadaf Ebrahimi### Source-Level Debug Information
773*b7893ccfSSadaf Ebrahimi
774*b7893ccfSSadaf EbrahimiThis is one of the more complicated and code-heavy parts of the GPU-Assisted Validation feature
775*b7893ccfSSadaf Ebrahimiand all it really does is display source-level information when the shader is compiled
776*b7893ccfSSadaf Ebrahimiwith debugging info (`-g` option in the case of `glslangValidator`).
777*b7893ccfSSadaf Ebrahimi
778*b7893ccfSSadaf EbrahimiThe process breaks down into two steps:
779*b7893ccfSSadaf Ebrahimi
780*b7893ccfSSadaf Ebrahimi#### OpLine Processing
781*b7893ccfSSadaf Ebrahimi
782*b7893ccfSSadaf EbrahimiThe SPIR-V generator (e.g., glslangValidator) places an OpLine SPIR-V instruction in the
783*b7893ccfSSadaf Ebrahimishader program ahead of code generated for each source code statement.
784*b7893ccfSSadaf EbrahimiThe OpLine instruction contains the filename id (for an OpString),
785*b7893ccfSSadaf Ebrahimithe source code line number and the source code column number.
786*b7893ccfSSadaf EbrahimiIt is possible to have two source code statements on the same line in the source file,
787*b7893ccfSSadaf Ebrahimiwhich explains the need for the column number.
788*b7893ccfSSadaf Ebrahimi
789*b7893ccfSSadaf EbrahimiThe layer scans the SPIR-V looking for the last OpLine instruction that appears before the instruction
790*b7893ccfSSadaf Ebrahimiat the instruction index obtained from the debug report.
791*b7893ccfSSadaf EbrahimiThis OpLine then contains the correct filename id, line number, and column number of the
792*b7893ccfSSadaf Ebrahimistatement causing the error.
793*b7893ccfSSadaf EbrahimiThe filename itself is obtained by scanning the SPIR-V again for an OpString instruction that
794*b7893ccfSSadaf Ebrahimimatches the id from the OpLine.
795*b7893ccfSSadaf EbrahimiThis OpString contains the text string representing the filename.
796*b7893ccfSSadaf EbrahimiThis information is added to the validation error message.
797*b7893ccfSSadaf Ebrahimi
798*b7893ccfSSadaf EbrahimiFor online compilation when there is no "file", only the line number information is reported.
799*b7893ccfSSadaf Ebrahimi
800*b7893ccfSSadaf Ebrahimi#### OpSource Processing
801*b7893ccfSSadaf Ebrahimi
802*b7893ccfSSadaf EbrahimiThe SPIR-V built with source-level debug info also contains OpSource instructions that
803*b7893ccfSSadaf Ebrahimihave a string containing the source code, delimited by newlines.
804*b7893ccfSSadaf EbrahimiDue to possible pre-processing, the layer just cannot simply use the source file line number
805*b7893ccfSSadaf Ebrahimifrom the OpLine to index into this set of source code lines.
806*b7893ccfSSadaf Ebrahimi
807*b7893ccfSSadaf EbrahimiInstead, the correct source code line is found by first locating the "#line" directive in the
808*b7893ccfSSadaf Ebrahimisource that specifies a line number closest to and less than the source line number reported
809*b7893ccfSSadaf Ebrahimiby the OpLine located in the previous step.
810*b7893ccfSSadaf EbrahimiThe correct "#line" directive must also match its filename, if specified,
811*b7893ccfSSadaf Ebrahimiwith the filename from the OpLine.
812*b7893ccfSSadaf Ebrahimi
813*b7893ccfSSadaf EbrahimiThen the difference between the "#line" line number and the OpLine line number is added
814*b7893ccfSSadaf Ebrahimito the place where the "#line" was found to locate the actual line of source, which is
815*b7893ccfSSadaf Ebrahimithen added to the validation error message.
816*b7893ccfSSadaf Ebrahimi
817*b7893ccfSSadaf EbrahimiFor example, if the OpLine line number is 15, and there is a "#line 10" on line 40
818*b7893ccfSSadaf Ebrahimiin the OpSource source, then line 45 in the OpSource contains the correct source line.
819*b7893ccfSSadaf Ebrahimi
820*b7893ccfSSadaf Ebrahimi### Shader Instrumentation Input Record Format
821*b7893ccfSSadaf Ebrahimi
822*b7893ccfSSadaf EbrahimiAlthough the input buffer is a linear array of unsigned integers, conceptually there are arrays within the linear array
823*b7893ccfSSadaf Ebrahimi
824*b7893ccfSSadaf EbrahimiWord 1 starts an array (denoted by sets_to_sizes) that is number_of_sets long, with an index that indicates the start of that set's entries in the sizes array
825*b7893ccfSSadaf Ebrahimi
826*b7893ccfSSadaf EbrahimiAfter the sets_to_sizes array is the sizes array, that contains the array size (or 1 if descriptor is not an array) of each descriptor in the set.  Bindings with no descriptor are filled in with zeros
827*b7893ccfSSadaf Ebrahimi
828*b7893ccfSSadaf EbrahimiAfter the sizes array is the sets_to_bindings array that for each descriptor set, indexes into the bindings_to_written array.  Word 0 contains the index that is the start of the sets_to_bindings array
829*b7893ccfSSadaf Ebrahimi
830*b7893ccfSSadaf EbrahimiAfter the sets_to_bindings array, is the bindings_to_written array that for each binding in the set, indexes to the start of that binding's entries in the written array
831*b7893ccfSSadaf Ebrahimi
832*b7893ccfSSadaf EbrahimiLastly comes the written array, which indicates whether a given binding / array element has been written
833*b7893ccfSSadaf Ebrahimi
834*b7893ccfSSadaf EbrahimiExample:
835*b7893ccfSSadaf Ebrahimi```
836*b7893ccfSSadaf EbrahimiAssume Descriptor Set 0 looks like:                        And Descriptor Set 1 looks like:
837*b7893ccfSSadaf Ebrahimi  Binding                                                    Binding
838*b7893ccfSSadaf Ebrahimi     0          Array[3]                                       2          Array[4]
839*b7893ccfSSadaf Ebrahimi     1          Non Array                                      3          Array[5]
840*b7893ccfSSadaf Ebrahimi     3          Array[2]
841*b7893ccfSSadaf Ebrahimi
842*b7893ccfSSadaf EbrahimiHere is what the input buffer should look like:
843*b7893ccfSSadaf Ebrahimi
844*b7893ccfSSadaf Ebrahimi   Index of                     sets_to_sizes                     sizes             sets_to_bindings                       bindings_to_written    written
845*b7893ccfSSadaf Ebrahimi   sets_to_bindings
846*b7893ccfSSadaf Ebrahimi
847*b7893ccfSSadaf Ebrahimi     0 |11| sets_to_bindings     1 |3| set 0 sizes start at 3     3  |3| S0B0       11 |13| set 0 bindings start at 13        13 |21| S0B0        21 |1| S0B0I0 was written
848*b7893ccfSSadaf Ebrahimi            starts at 11         2 |7| set 1 sizes start at 7     4  |1| S0B1       12 |17| set 1 bindings start at 17        14 |24| S0B1        22 |1| S0B0I1 was written
849*b7893ccfSSadaf Ebrahimi                                                                  5  |0| S0B2                                                 15 |0 | S0B2        23 |1| S0B0I3 was written
850*b7893ccfSSadaf Ebrahimi                                                                  6  |2| S0B3                                                 16 |25| S0B3        24 |1| S0B1 was written
851*b7893ccfSSadaf Ebrahimi                                                                  7  |0| S1B0                                                 17 |0 | S1B0        25 |1| S0B3I0 was written
852*b7893ccfSSadaf Ebrahimi                                                                  8  |0| S1B1                                                 18 |0 | S1B1        26 |1| S0B3I1 was written
853*b7893ccfSSadaf Ebrahimi                                                                  9  |4| S1B2                                                 19 |27| S1B2        27 |0| S1B2I0 was not written
854*b7893ccfSSadaf Ebrahimi                                                                  10 |5| S1B3                                                 20 |31| S1B3        28 |1| S1B2I1 was written
855*b7893ccfSSadaf Ebrahimi                                                                                                                                                  29 |1| S1B2I2 was written
856*b7893ccfSSadaf Ebrahimi                                                                                                                                                  30 |1| S1B2I3 was written
857*b7893ccfSSadaf Ebrahimi                                                                                                                                                  31 |1| S1B3I0 was written
858*b7893ccfSSadaf Ebrahimi                                                                                                                                                  32 |1| S1B3I1 was written
859*b7893ccfSSadaf Ebrahimi                                                                                                                                                  33 |1| S1B3I2 was written
860*b7893ccfSSadaf Ebrahimi                                                                                                                                                  34 |1| S1B3I3 was written
861*b7893ccfSSadaf Ebrahimi                                                                                                                                                  35 |1| S1B3I4 was written
862*b7893ccfSSadaf Ebrahimi```
863*b7893ccfSSadaf EbrahimiAlternately, you could describe the array size and write state data as:
864*b7893ccfSSadaf Ebrahimi(set = s, binding = b, index = i) is not initialized if
865*b7893ccfSSadaf Ebrahimi```
866*b7893ccfSSadaf EbrahimiInput[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] == 0
867*b7893ccfSSadaf Ebrahimi```
868*b7893ccfSSadaf Ebrahimiand the array's size = Input[ Input[ s + 1 ] + b ]
869*b7893ccfSSadaf Ebrahimi
870*b7893ccfSSadaf Ebrahimi## GPU-Assisted Validation Testing
871*b7893ccfSSadaf Ebrahimi
872*b7893ccfSSadaf EbrahimiValidation Layer Tests (VLTs) exist for GPU-Assisted Validation.
873*b7893ccfSSadaf EbrahimiThey cannot be run with the "mock ICD" in headless CI environments because they need to
874*b7893ccfSSadaf Ebrahimiactually execute shaders.
875*b7893ccfSSadaf EbrahimiBut they are still useful to run on real devices to check for regressions.
876*b7893ccfSSadaf Ebrahimi
877*b7893ccfSSadaf EbrahimiThere isn't anything else that remarkable or different about these tests.
878*b7893ccfSSadaf EbrahimiThey activate GPU-Assisted Validation via the programmatic
879*b7893ccfSSadaf Ebrahimiinterface as described earlier.
880*b7893ccfSSadaf Ebrahimi
881*b7893ccfSSadaf EbrahimiThe tests exercise the extraction of source code information when the shader
882*b7893ccfSSadaf Ebrahimiis built with debug info.
883