blob: 88cdae83e458a6803af3d065444c0ad82f647c5c [file] [log] [blame]
Mark Lobodzinski103c58a2020-01-29 13:20:00 -07001/* Copyright (c) 2018-2020 The Khronos Group Inc.
2 * Copyright (c) 2018-2020 Valve Corporation
3 * Copyright (c) 2018-2020 LunarG, Inc.
Karl Schultz7b024b42018-08-30 16:18:18 -06004 *
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 *
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060017 * Author: Karl Schultz <karl@lunarg.com>
18 * Author: Tony Barbour <tony@lunarg.com>
Karl Schultz7b024b42018-08-30 16:18:18 -060019 */
20
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070021#include "gpu_validation.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060022#include "spirv-tools/optimizer.hpp"
23#include "spirv-tools/instrument.hpp"
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060024#include "layer_chassis_dispatch.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060025
Jason Macnak67407e72019-07-11 11:05:09 -070026static const VkShaderStageFlags kShaderStageAllRayTracing =
27 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
28 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
29
Jason Macnak83cfd582019-07-31 10:14:24 -070030// Keep in sync with the GLSL shader below.
31struct GpuAccelerationStructureBuildValidationBuffer {
32 uint32_t instances_to_validate;
33 uint32_t replacement_handle_bits_0;
34 uint32_t replacement_handle_bits_1;
35 uint32_t invalid_handle_found;
36 uint32_t invalid_handle_bits_0;
37 uint32_t invalid_handle_bits_1;
38 uint32_t valid_handles_count;
39};
40
41// This is the GLSL source for the compute shader that is used during ray tracing acceleration structure
42// building validation which inspects instance buffers for top level acceleration structure builds and
43// reports and replaces invalid bottom level acceleration structure handles with good bottom level
44// acceleration structure handle so that applications can continue without undefined behavior long enough
45// to report errors.
46//
47// #version 450
48// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
49// struct VkGeometryInstanceNV {
50// uint unused[14];
51// uint handle_bits_0;
52// uint handle_bits_1;
53// };
54// layout(set=0, binding=0, std430) buffer InstanceBuffer {
55// VkGeometryInstanceNV instances[];
56// };
57// layout(set=0, binding=1, std430) buffer ValidationBuffer {
58// uint instances_to_validate;
59// uint replacement_handle_bits_0;
60// uint replacement_handle_bits_1;
61// uint invalid_handle_found;
62// uint invalid_handle_bits_0;
63// uint invalid_handle_bits_1;
64// uint valid_handles_count;
65// uint valid_handles[];
66// };
67// void main() {
68// for (uint instance_index = 0; instance_index < instances_to_validate; instance_index++) {
69// uint instance_handle_bits_0 = instances[instance_index].handle_bits_0;
70// uint instance_handle_bits_1 = instances[instance_index].handle_bits_1;
71// bool valid = false;
72// for (uint valid_handle_index = 0; valid_handle_index < valid_handles_count; valid_handle_index++) {
73// if (instance_handle_bits_0 == valid_handles[2*valid_handle_index+0] &&
74// instance_handle_bits_1 == valid_handles[2*valid_handle_index+1]) {
75// valid = true;
76// break;
77// }
78// }
79// if (!valid) {
80// invalid_handle_found += 1;
81// invalid_handle_bits_0 = instance_handle_bits_0;
82// invalid_handle_bits_1 = instance_handle_bits_1;
83// instances[instance_index].handle_bits_0 = replacement_handle_bits_0;
84// instances[instance_index].handle_bits_1 = replacement_handle_bits_1;
85// }
86// }
87// }
88//
89// To regenerate the spirv below:
90// 1. Save the above GLSL source to a file called validation_shader.comp.
91// 2. Run in terminal
92//
93// glslangValidator.exe -x -V validation_shader.comp -o validation_shader.comp.spv
94//
95// 4. Copy-paste the contents of validation_shader.comp.spv here (clang-format will fix up the alignment).
96static const uint32_t kComputeShaderSpirv[] = {
97 0x07230203, 0x00010000, 0x00080007, 0x0000006d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
98 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005, 0x00000004, 0x6e69616d,
99 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2,
100 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x00000008, 0x74736e69, 0x65636e61, 0x646e695f, 0x00007865,
101 0x00070005, 0x00000011, 0x696c6156, 0x69746164, 0x75426e6f, 0x72656666, 0x00000000, 0x00090006, 0x00000011, 0x00000000,
102 0x74736e69, 0x65636e61, 0x6f745f73, 0x6c61765f, 0x74616469, 0x00000065, 0x000a0006, 0x00000011, 0x00000001, 0x6c706572,
103 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x000a0006, 0x00000011, 0x00000002, 0x6c706572,
104 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00090006, 0x00000011, 0x00000003, 0x61766e69,
105 0x5f64696c, 0x646e6168, 0x665f656c, 0x646e756f, 0x00000000, 0x00090006, 0x00000011, 0x00000004, 0x61766e69, 0x5f64696c,
106 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00090006, 0x00000011, 0x00000005, 0x61766e69, 0x5f64696c, 0x646e6168,
107 0x625f656c, 0x5f737469, 0x00000031, 0x00080006, 0x00000011, 0x00000006, 0x696c6176, 0x61685f64, 0x656c646e, 0x6f635f73,
108 0x00746e75, 0x00070006, 0x00000011, 0x00000007, 0x696c6176, 0x61685f64, 0x656c646e, 0x00000073, 0x00030005, 0x00000013,
109 0x00000000, 0x00080005, 0x0000001b, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000305f, 0x00080005,
110 0x0000001e, 0x65476b56, 0x74656d6f, 0x6e497972, 0x6e617473, 0x564e6563, 0x00000000, 0x00050006, 0x0000001e, 0x00000000,
111 0x73756e75, 0x00006465, 0x00070006, 0x0000001e, 0x00000001, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00070006,
112 0x0000001e, 0x00000002, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00060005, 0x00000020, 0x74736e49, 0x65636e61,
113 0x66667542, 0x00007265, 0x00060006, 0x00000020, 0x00000000, 0x74736e69, 0x65636e61, 0x00000073, 0x00030005, 0x00000022,
114 0x00000000, 0x00080005, 0x00000027, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000315f, 0x00040005,
115 0x0000002d, 0x696c6176, 0x00000064, 0x00070005, 0x0000002f, 0x696c6176, 0x61685f64, 0x656c646e, 0x646e695f, 0x00007865,
116 0x00040047, 0x00000010, 0x00000006, 0x00000004, 0x00050048, 0x00000011, 0x00000000, 0x00000023, 0x00000000, 0x00050048,
117 0x00000011, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000011, 0x00000002, 0x00000023, 0x00000008, 0x00050048,
118 0x00000011, 0x00000003, 0x00000023, 0x0000000c, 0x00050048, 0x00000011, 0x00000004, 0x00000023, 0x00000010, 0x00050048,
119 0x00000011, 0x00000005, 0x00000023, 0x00000014, 0x00050048, 0x00000011, 0x00000006, 0x00000023, 0x00000018, 0x00050048,
120 0x00000011, 0x00000007, 0x00000023, 0x0000001c, 0x00030047, 0x00000011, 0x00000003, 0x00040047, 0x00000013, 0x00000022,
121 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000001, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00050048,
122 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000038, 0x00050048,
123 0x0000001e, 0x00000002, 0x00000023, 0x0000003c, 0x00040047, 0x0000001f, 0x00000006, 0x00000040, 0x00050048, 0x00000020,
124 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000003, 0x00040047, 0x00000022, 0x00000022, 0x00000000,
125 0x00040047, 0x00000022, 0x00000021, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015,
126 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x0004002b, 0x00000006, 0x00000009,
127 0x00000000, 0x0003001d, 0x00000010, 0x00000006, 0x000a001e, 0x00000011, 0x00000006, 0x00000006, 0x00000006, 0x00000006,
128 0x00000006, 0x00000006, 0x00000006, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012,
129 0x00000013, 0x00000002, 0x00040015, 0x00000014, 0x00000020, 0x00000001, 0x0004002b, 0x00000014, 0x00000015, 0x00000000,
130 0x00040020, 0x00000016, 0x00000002, 0x00000006, 0x00020014, 0x00000019, 0x0004002b, 0x00000006, 0x0000001c, 0x0000000e,
131 0x0004001c, 0x0000001d, 0x00000006, 0x0000001c, 0x0005001e, 0x0000001e, 0x0000001d, 0x00000006, 0x00000006, 0x0003001d,
132 0x0000001f, 0x0000001e, 0x0003001e, 0x00000020, 0x0000001f, 0x00040020, 0x00000021, 0x00000002, 0x00000020, 0x0004003b,
133 0x00000021, 0x00000022, 0x00000002, 0x0004002b, 0x00000014, 0x00000024, 0x00000001, 0x0004002b, 0x00000014, 0x00000029,
134 0x00000002, 0x00040020, 0x0000002c, 0x00000007, 0x00000019, 0x0003002a, 0x00000019, 0x0000002e, 0x0004002b, 0x00000014,
135 0x00000036, 0x00000006, 0x0004002b, 0x00000014, 0x0000003b, 0x00000007, 0x0004002b, 0x00000006, 0x0000003c, 0x00000002,
136 0x0004002b, 0x00000006, 0x00000048, 0x00000001, 0x00030029, 0x00000019, 0x00000050, 0x0004002b, 0x00000014, 0x00000058,
137 0x00000003, 0x0004002b, 0x00000014, 0x0000005d, 0x00000004, 0x0004002b, 0x00000014, 0x00000060, 0x00000005, 0x00050036,
138 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007,
139 0x0004003b, 0x00000007, 0x0000001b, 0x00000007, 0x0004003b, 0x00000007, 0x00000027, 0x00000007, 0x0004003b, 0x0000002c,
140 0x0000002d, 0x00000007, 0x0004003b, 0x00000007, 0x0000002f, 0x00000007, 0x0003003e, 0x00000008, 0x00000009, 0x000200f9,
141 0x0000000a, 0x000200f8, 0x0000000a, 0x000400f6, 0x0000000c, 0x0000000d, 0x00000000, 0x000200f9, 0x0000000e, 0x000200f8,
142 0x0000000e, 0x0004003d, 0x00000006, 0x0000000f, 0x00000008, 0x00050041, 0x00000016, 0x00000017, 0x00000013, 0x00000015,
143 0x0004003d, 0x00000006, 0x00000018, 0x00000017, 0x000500b0, 0x00000019, 0x0000001a, 0x0000000f, 0x00000018, 0x000400fa,
144 0x0000001a, 0x0000000b, 0x0000000c, 0x000200f8, 0x0000000b, 0x0004003d, 0x00000006, 0x00000023, 0x00000008, 0x00070041,
145 0x00000016, 0x00000025, 0x00000022, 0x00000015, 0x00000023, 0x00000024, 0x0004003d, 0x00000006, 0x00000026, 0x00000025,
146 0x0003003e, 0x0000001b, 0x00000026, 0x0004003d, 0x00000006, 0x00000028, 0x00000008, 0x00070041, 0x00000016, 0x0000002a,
147 0x00000022, 0x00000015, 0x00000028, 0x00000029, 0x0004003d, 0x00000006, 0x0000002b, 0x0000002a, 0x0003003e, 0x00000027,
148 0x0000002b, 0x0003003e, 0x0000002d, 0x0000002e, 0x0003003e, 0x0000002f, 0x00000009, 0x000200f9, 0x00000030, 0x000200f8,
149 0x00000030, 0x000400f6, 0x00000032, 0x00000033, 0x00000000, 0x000200f9, 0x00000034, 0x000200f8, 0x00000034, 0x0004003d,
150 0x00000006, 0x00000035, 0x0000002f, 0x00050041, 0x00000016, 0x00000037, 0x00000013, 0x00000036, 0x0004003d, 0x00000006,
151 0x00000038, 0x00000037, 0x000500b0, 0x00000019, 0x00000039, 0x00000035, 0x00000038, 0x000400fa, 0x00000039, 0x00000031,
152 0x00000032, 0x000200f8, 0x00000031, 0x0004003d, 0x00000006, 0x0000003a, 0x0000001b, 0x0004003d, 0x00000006, 0x0000003d,
153 0x0000002f, 0x00050084, 0x00000006, 0x0000003e, 0x0000003c, 0x0000003d, 0x00050080, 0x00000006, 0x0000003f, 0x0000003e,
154 0x00000009, 0x00060041, 0x00000016, 0x00000040, 0x00000013, 0x0000003b, 0x0000003f, 0x0004003d, 0x00000006, 0x00000041,
155 0x00000040, 0x000500aa, 0x00000019, 0x00000042, 0x0000003a, 0x00000041, 0x000300f7, 0x00000044, 0x00000000, 0x000400fa,
156 0x00000042, 0x00000043, 0x00000044, 0x000200f8, 0x00000043, 0x0004003d, 0x00000006, 0x00000045, 0x00000027, 0x0004003d,
157 0x00000006, 0x00000046, 0x0000002f, 0x00050084, 0x00000006, 0x00000047, 0x0000003c, 0x00000046, 0x00050080, 0x00000006,
158 0x00000049, 0x00000047, 0x00000048, 0x00060041, 0x00000016, 0x0000004a, 0x00000013, 0x0000003b, 0x00000049, 0x0004003d,
159 0x00000006, 0x0000004b, 0x0000004a, 0x000500aa, 0x00000019, 0x0000004c, 0x00000045, 0x0000004b, 0x000200f9, 0x00000044,
160 0x000200f8, 0x00000044, 0x000700f5, 0x00000019, 0x0000004d, 0x00000042, 0x00000031, 0x0000004c, 0x00000043, 0x000300f7,
161 0x0000004f, 0x00000000, 0x000400fa, 0x0000004d, 0x0000004e, 0x0000004f, 0x000200f8, 0x0000004e, 0x0003003e, 0x0000002d,
162 0x00000050, 0x000200f9, 0x00000032, 0x000200f8, 0x0000004f, 0x000200f9, 0x00000033, 0x000200f8, 0x00000033, 0x0004003d,
163 0x00000006, 0x00000052, 0x0000002f, 0x00050080, 0x00000006, 0x00000053, 0x00000052, 0x00000024, 0x0003003e, 0x0000002f,
164 0x00000053, 0x000200f9, 0x00000030, 0x000200f8, 0x00000032, 0x0004003d, 0x00000019, 0x00000054, 0x0000002d, 0x000400a8,
165 0x00000019, 0x00000055, 0x00000054, 0x000300f7, 0x00000057, 0x00000000, 0x000400fa, 0x00000055, 0x00000056, 0x00000057,
166 0x000200f8, 0x00000056, 0x00050041, 0x00000016, 0x00000059, 0x00000013, 0x00000058, 0x0004003d, 0x00000006, 0x0000005a,
167 0x00000059, 0x00050080, 0x00000006, 0x0000005b, 0x0000005a, 0x00000048, 0x00050041, 0x00000016, 0x0000005c, 0x00000013,
168 0x00000058, 0x0003003e, 0x0000005c, 0x0000005b, 0x0004003d, 0x00000006, 0x0000005e, 0x0000001b, 0x00050041, 0x00000016,
169 0x0000005f, 0x00000013, 0x0000005d, 0x0003003e, 0x0000005f, 0x0000005e, 0x0004003d, 0x00000006, 0x00000061, 0x00000027,
170 0x00050041, 0x00000016, 0x00000062, 0x00000013, 0x00000060, 0x0003003e, 0x00000062, 0x00000061, 0x0004003d, 0x00000006,
171 0x00000063, 0x00000008, 0x00050041, 0x00000016, 0x00000064, 0x00000013, 0x00000024, 0x0004003d, 0x00000006, 0x00000065,
172 0x00000064, 0x00070041, 0x00000016, 0x00000066, 0x00000022, 0x00000015, 0x00000063, 0x00000024, 0x0003003e, 0x00000066,
173 0x00000065, 0x0004003d, 0x00000006, 0x00000067, 0x00000008, 0x00050041, 0x00000016, 0x00000068, 0x00000013, 0x00000029,
174 0x0004003d, 0x00000006, 0x00000069, 0x00000068, 0x00070041, 0x00000016, 0x0000006a, 0x00000022, 0x00000015, 0x00000067,
175 0x00000029, 0x0003003e, 0x0000006a, 0x00000069, 0x000200f9, 0x00000057, 0x000200f8, 0x00000057, 0x000200f9, 0x0000000d,
176 0x000200f8, 0x0000000d, 0x0004003d, 0x00000006, 0x0000006b, 0x00000008, 0x00050080, 0x00000006, 0x0000006c, 0x0000006b,
177 0x00000024, 0x0003003e, 0x00000008, 0x0000006c, 0x000200f9, 0x0000000a, 0x000200f8, 0x0000000c, 0x000100fd, 0x00010038};
178
Karl Schultz7b024b42018-08-30 16:18:18 -0600179// Convenience function for reporting problems with setting up GPU Validation.
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700180template <typename T>
181void GpuAssisted::ReportSetupProblem(T object, const char *const specific_message) const {
182 LogError(object, "UNASSIGNED-GPU-Assisted Validation Error. ", "Detail: (%s)", specific_message);
Karl Schultz7b024b42018-08-30 16:18:18 -0600183}
184
Tony-LunarG5c38b182020-06-10 16:15:32 -0600185bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
186 bool result =
187 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
188 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
189 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
190 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
191 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
192 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
193 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
194 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
195 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
196 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
197 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
198 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
199 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
200 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
201 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
202 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
203 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
204 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
205 enabled_features.core12.descriptorBindingPartiallyBound ||
206 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
207 return result;
208}
209
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600210void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
211 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700212 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
213 // acceleration structure build validation will find and replace invalid acceleration structure
214 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600215 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
216 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
217 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700218 }
219}
220
Karl Schultz7b024b42018-08-30 16:18:18 -0600221// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600222void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
223 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
224 safe_VkDeviceCreateInfo *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600225 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600226 VkPhysicalDeviceFeatures features = {};
227 features.vertexPipelineStoresAndAtomics = true;
228 features.fragmentStoresAndAtomics = true;
229 features.shaderInt64 = true;
Tony-LunarGb5fae462020-03-05 12:43:25 -0700230 UtilPreCallRecordCreateDevice(gpu, modified_create_info, supported_features, features);
Karl Schultz7b024b42018-08-30 16:18:18 -0600231}
Karl Schultz7b024b42018-08-30 16:18:18 -0600232// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600233void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
234 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
235 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600236 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600237
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600238 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
239 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
240 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700241
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600242 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700243 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600244 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600245 return;
246 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600247
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600248 if (!device_gpu_assisted->enabled_features.core.fragmentStoresAndAtomics ||
249 !device_gpu_assisted->enabled_features.core.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700250 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600251 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
252 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600253 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600254 return;
255 }
256
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700257 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
258 !device_gpu_assisted->enabled_features.core.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700259 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
260 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600261 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600262 device_gpu_assisted->shaderInt64 = device_gpu_assisted->enabled_features.core.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600263 device_gpu_assisted->physicalDevice = physicalDevice;
264 device_gpu_assisted->device = *pDevice;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600265 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarG5c38b182020-06-10 16:15:32 -0600266 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600267 std::vector<VkDescriptorSetLayoutBinding> bindings;
268 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
269 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT | kShaderStageAllRayTracing,
270 NULL};
271 bindings.push_back(binding);
272 for (auto i = 1; i < 3; i++) {
273 binding.binding = i;
274 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600275 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700276 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600277 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600278}
279
Tony-LunarG588c7052020-04-23 10:47:21 -0600280void GpuAssisted::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
281 VkDeviceAddress address) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600282 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
283 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600284 if (buffer_state) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600285 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600286 buffer_state->deviceAddress = address;
287 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600288}
289
Tony-LunarG588c7052020-04-23 10:47:21 -0600290void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
291 VkDeviceAddress address) {
292 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
293}
294
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700295void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
296 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600297 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700298}
299
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600300void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600301 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600302 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG2966c732020-05-21 10:33:53 -0600303 ValidationStateTracker::PreCallRecordDestroyBuffer(device, buffer, pAllocator);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600304}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600305
Karl Schultz7b024b42018-08-30 16:18:18 -0600306// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600307void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600308 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700309 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600310 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -0600311}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600312
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600313void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600314 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700315 return;
316 }
317
Tony-LunarG99b880b2019-09-26 11:19:52 -0600318 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700319 if (as_validation_state.initialized) {
320 return;
321 }
322
323 if (!device_extensions.vk_nv_ray_tracing) {
324 return;
325 }
326
327 // Outline:
328 // - Create valid bottom level acceleration structure which acts as replacement
329 // - Create and load vertex buffer
330 // - Create and load index buffer
331 // - Create, allocate memory for, and bind memory for acceleration structure
332 // - Query acceleration structure handle
333 // - Create command pool and command buffer
334 // - Record build acceleration structure command
335 // - Submit command buffer and wait for completion
336 // - Cleanup
337 // - Create compute pipeline for validating instance buffers
338 // - Create descriptor set layout
339 // - Create pipeline layout
340 // - Create pipeline
341 // - Cleanup
342
343 VkResult result = VK_SUCCESS;
344
345 VkBuffer vbo = VK_NULL_HANDLE;
346 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
347 if (result == VK_SUCCESS) {
348 VkBufferCreateInfo vbo_ci = {};
349 vbo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
350 vbo_ci.size = sizeof(float) * 9;
351 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
352
353 VmaAllocationCreateInfo vbo_ai = {};
354 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
355 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
356
Tony-LunarG99b880b2019-09-26 11:19:52 -0600357 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700358 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700359 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700360 }
361 }
362
363 if (result == VK_SUCCESS) {
364 uint8_t *mapped_vbo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600365 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, (void **)&mapped_vbo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700366 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700367 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700368 } else {
369 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
370 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600371 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700372 }
373 }
374
375 VkBuffer ibo = VK_NULL_HANDLE;
376 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
377 if (result == VK_SUCCESS) {
378 VkBufferCreateInfo ibo_ci = {};
379 ibo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
380 ibo_ci.size = sizeof(uint32_t) * 3;
381 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
382
383 VmaAllocationCreateInfo ibo_ai = {};
384 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
385 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
386
Tony-LunarG99b880b2019-09-26 11:19:52 -0600387 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700388 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700389 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700390 }
391 }
392
393 if (result == VK_SUCCESS) {
394 uint8_t *mapped_ibo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600395 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, (void **)&mapped_ibo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700396 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700397 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700398 } else {
399 const std::vector<uint32_t> indicies = {0, 1, 2};
400 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600401 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700402 }
403 }
404
405 VkGeometryNV geometry = {};
406 geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
407 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
408 geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
409 geometry.geometry.triangles.vertexData = vbo;
410 geometry.geometry.triangles.vertexOffset = 0;
411 geometry.geometry.triangles.vertexCount = 3;
412 geometry.geometry.triangles.vertexStride = 12;
413 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
414 geometry.geometry.triangles.indexData = ibo;
415 geometry.geometry.triangles.indexOffset = 0;
416 geometry.geometry.triangles.indexCount = 3;
417 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
418 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
419 geometry.geometry.triangles.transformOffset = 0;
420 geometry.geometry.aabbs = {};
421 geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
422
423 VkAccelerationStructureCreateInfoNV as_ci = {};
424 as_ci.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
425 as_ci.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
426 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
427 as_ci.info.instanceCount = 0;
428 as_ci.info.geometryCount = 1;
429 as_ci.info.pGeometries = &geometry;
430 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600431 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700432 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700433 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700434 "Failed to create acceleration structure for acceleration structure build validation.");
435 }
436 }
437
438 VkMemoryRequirements2 as_mem_requirements = {};
439 if (result == VK_SUCCESS) {
440 VkAccelerationStructureMemoryRequirementsInfoNV as_mem_requirements_info = {};
441 as_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
442 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
443 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
444
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600445 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700446 }
447
448 VmaAllocationInfo as_memory_ai = {};
449 if (result == VK_SUCCESS) {
450 VmaAllocationCreateInfo as_memory_aci = {};
451 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
452
Tony-LunarG99b880b2019-09-26 11:19:52 -0600453 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
454 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700455 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700456 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700457 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
458 }
459 }
460
461 if (result == VK_SUCCESS) {
462 VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
463 as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
464 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
465 as_bind_info.memory = as_memory_ai.deviceMemory;
466 as_bind_info.memoryOffset = as_memory_ai.offset;
467
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600468 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700469 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700470 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700471 "Failed to bind acceleration structure memory for acceleration structure build validation.");
472 }
473 }
474
475 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600476 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
477 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700478 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700479 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700480 "Failed to get acceleration structure handle for acceleration structure build validation.");
481 }
482 }
483
484 VkMemoryRequirements2 scratch_mem_requirements = {};
485 if (result == VK_SUCCESS) {
486 VkAccelerationStructureMemoryRequirementsInfoNV scratch_mem_requirements_info = {};
487 scratch_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
488 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
489 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
490
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600491 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
492 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700493 }
494
495 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600496 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700497 if (result == VK_SUCCESS) {
498 VkBufferCreateInfo scratch_ci = {};
499 scratch_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
500 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
501 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700502 VmaAllocationCreateInfo scratch_aci = {};
503 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
504
Tony-LunarG18900282020-05-20 12:34:33 -0600505 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700506 if (result != VK_SUCCESS) {
Tony-LunarG18900282020-05-20 12:34:33 -0600507 ReportSetupProblem(device_gpuav->device,
508 "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700509 }
510 }
511
512 VkCommandPool command_pool = VK_NULL_HANDLE;
513 if (result == VK_SUCCESS) {
514 VkCommandPoolCreateInfo command_pool_ci = {};
515 command_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
516 command_pool_ci.queueFamilyIndex = 0;
517
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600518 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700519 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700520 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700521 }
522 }
523
524 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
525
526 if (result == VK_SUCCESS) {
527 VkCommandBufferAllocateInfo command_buffer_ai = {};
528 command_buffer_ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
529 command_buffer_ai.commandPool = command_pool;
530 command_buffer_ai.commandBufferCount = 1;
531 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
532
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600533 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700534 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700535 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700536 "Failed to create command buffer for acceleration structure build validation.");
537 }
538
539 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600540 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700541 }
542
543 if (result == VK_SUCCESS) {
544 VkCommandBufferBeginInfo command_buffer_bi = {};
545 command_buffer_bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
546
547 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
548 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700549 ReportSetupProblem(device_gpuav->device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700550 }
551 }
552
553 if (result == VK_SUCCESS) {
554 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
555 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
556 DispatchEndCommandBuffer(command_buffer);
557 }
558
559 VkQueue queue = VK_NULL_HANDLE;
560 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600561 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700562
563 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600564 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700565
566 VkSubmitInfo submit_info = {};
567 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
568 submit_info.commandBufferCount = 1;
569 submit_info.pCommandBuffers = &command_buffer;
570 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
571 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700572 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700573 "Failed to submit command buffer for acceleration structure build validation.");
574 }
575 }
576
577 if (result == VK_SUCCESS) {
578 result = DispatchQueueWaitIdle(queue);
579 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700580 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700581 }
582 }
583
584 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600585 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700586 }
587 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600588 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700589 }
590 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG18900282020-05-20 12:34:33 -0600591 vmaDestroyBuffer(device_gpuav->vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700592 }
593 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600594 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700595 }
596
Tony-LunarG99b880b2019-09-26 11:19:52 -0600597 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700598 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700599 "Failed to find descriptor set layout for acceleration structure build validation.");
600 result = VK_INCOMPLETE;
601 }
602
603 if (result == VK_SUCCESS) {
604 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
605 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
606 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600607 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600608 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700609 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700610 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700611 "Failed to create pipeline layout for acceleration structure build validation.");
612 }
613 }
614
615 VkShaderModule shader_module = VK_NULL_HANDLE;
616 if (result == VK_SUCCESS) {
617 VkShaderModuleCreateInfo shader_module_ci = {};
618 shader_module_ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
619 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
620 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
621
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600622 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700623 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700624 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700625 "Failed to create compute shader module for acceleration structure build validation.");
626 }
627 }
628
629 if (result == VK_SUCCESS) {
630 VkPipelineShaderStageCreateInfo pipeline_stage_ci = {};
631 pipeline_stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
632 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
633 pipeline_stage_ci.module = shader_module;
634 pipeline_stage_ci.pName = "main";
635
636 VkComputePipelineCreateInfo pipeline_ci = {};
637 pipeline_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
638 pipeline_ci.stage = pipeline_stage_ci;
639 pipeline_ci.layout = as_validation_state.pipeline_layout;
640
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600641 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
642 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700643 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700644 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700645 "Failed to create compute pipeline for acceleration structure build validation.");
646 }
647 }
648
649 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600650 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700651 }
652
653 if (result == VK_SUCCESS) {
654 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700655 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600656 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700657 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600658 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700659 }
660}
661
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600662void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600663 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700664 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
665 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
666 }
667 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
668 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
669 }
670 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
671 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
672 }
673 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600674 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700675 }
676}
677
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600678struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700679 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
680 VkPipeline pipeline = VK_NULL_HANDLE;
681 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
682 std::vector<VkDescriptorSet> descriptor_sets;
683 std::vector<std::vector<uint32_t>> dynamic_offsets;
684 uint32_t push_descriptor_set_index = 0;
685 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
686 std::vector<uint8_t> push_constants_data;
687 PushConstantRangesId push_constants_ranges;
688
689 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
690 pipeline_bind_point = bind_point;
691
692 LAST_BOUND_STATE &last_bound = cb_state->lastBound[bind_point];
693 if (last_bound.pipeline_state) {
694 pipeline = last_bound.pipeline_state->pipeline;
695 pipeline_layout = last_bound.pipeline_layout;
696 descriptor_sets.reserve(last_bound.per_set.size());
697 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
698 const auto *bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
699
700 descriptor_sets.push_back(bound_descriptor_set->GetSet());
701 if (bound_descriptor_set->IsPushDescriptor()) {
702 push_descriptor_set_index = static_cast<uint32_t>(i);
703 }
704 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
705 }
706
707 if (last_bound.push_descriptor_set) {
708 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
709 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500710 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700711 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500712 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700713 }
714 }
715 }
716
717 void Restore(VkCommandBuffer command_buffer) const {
718 if (pipeline != VK_NULL_HANDLE) {
719 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
720 if (!descriptor_sets.empty()) {
721 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
722 VkDescriptorSet descriptor_set = descriptor_sets[i];
723 if (descriptor_set != VK_NULL_HANDLE) {
724 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
725 static_cast<uint32_t>(i), 1, &descriptor_set,
726 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
727 }
728 }
729 }
730 if (!push_descriptor_set_writes.empty()) {
731 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
732 static_cast<uint32_t>(push_descriptor_set_writes.size()),
733 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
734 }
735 for (const auto &push_constant_range : *push_constants_ranges) {
736 if (push_constant_range.size == 0) continue;
737 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
738 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
739 }
740 }
741 }
742};
743
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600744void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
745 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
746 VkDeviceSize instanceOffset, VkBool32 update,
747 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
748 VkBuffer scratch, VkDeviceSize scratchOffset) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700749 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
750 return;
751 }
752
Tony-LunarG99b880b2019-09-26 11:19:52 -0600753 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700754 if (!as_validation_state.initialized) {
755 return;
756 }
757
758 // Empty acceleration structure is valid according to the spec.
759 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
760 return;
761 }
762
763 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
764 assert(cb_state != nullptr);
765
766 std::vector<uint64_t> current_valid_handles;
767 for (const auto &as_state_kv : accelerationStructureMap) {
768 const ACCELERATION_STRUCTURE_STATE &as_state = *as_state_kv.second;
Jeff Bolz95176d02020-04-01 00:36:16 -0500769 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700770 current_valid_handles.push_back(as_state.opaque_handle);
771 }
772 }
773
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600774 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700775 as_validation_buffer_info.acceleration_structure = dst;
776
777 const VkDeviceSize validation_buffer_size =
778 // One uint for number of instances to validate
779 4 +
780 // Two uint for the replacement acceleration structure handle
781 8 +
782 // One uint for number of invalid handles found
783 4 +
784 // Two uint for the first invalid handle found
785 8 +
786 // One uint for the number of current valid handles
787 4 +
788 // Two uint for each current valid handle
789 (8 * current_valid_handles.size());
790
791 VkBufferCreateInfo validation_buffer_create_info = {};
792 validation_buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
793 validation_buffer_create_info.size = validation_buffer_size;
794 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
795
796 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
797 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
798
Tony-LunarG99b880b2019-09-26 11:19:52 -0600799 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
800 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700801 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
802 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700803 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600804 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700805 return;
806 }
807
808 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600809 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700810 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700811 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600812 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700813 return;
814 }
815
816 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
817 mapped_validation_buffer->replacement_handle_bits_0 =
818 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
819 mapped_validation_buffer->replacement_handle_bits_1 =
820 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
821 mapped_validation_buffer->invalid_handle_found = 0;
822 mapped_validation_buffer->invalid_handle_bits_0 = 0;
823 mapped_validation_buffer->invalid_handle_bits_1 = 0;
824 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
825
826 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
827 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
828 const uint64_t current_valid_handle = current_valid_handles[i];
829
830 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
831 ++mapped_valid_handles;
832 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
833 ++mapped_valid_handles;
834 }
835
Tony-LunarG99b880b2019-09-26 11:19:52 -0600836 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700837
838 static constexpr const VkDeviceSize kInstanceSize = 64;
839 const VkDeviceSize instance_buffer_size = kInstanceSize * pInfo->instanceCount;
840
Tony-LunarG1dce2392019-10-23 16:49:29 -0600841 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
842 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700843 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700844 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600845 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700846 return;
847 }
848
849 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
850 descriptor_buffer_infos[0].buffer = instanceData;
851 descriptor_buffer_infos[0].offset = instanceOffset;
852 descriptor_buffer_infos[0].range = instance_buffer_size;
853 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
854 descriptor_buffer_infos[1].offset = 0;
855 descriptor_buffer_infos[1].range = validation_buffer_size;
856
857 VkWriteDescriptorSet descriptor_set_writes[2] = {};
858 descriptor_set_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
859 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
860 descriptor_set_writes[0].dstBinding = 0;
861 descriptor_set_writes[0].descriptorCount = 1;
862 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
863 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
864 descriptor_set_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
865 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
866 descriptor_set_writes[1].dstBinding = 1;
867 descriptor_set_writes[1].descriptorCount = 1;
868 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
869 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
870
871 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
872
873 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
874 VkMemoryBarrier memory_barrier = {};
875 memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
876 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
877 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
878 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
879 &memory_barrier, 0, nullptr, 0, nullptr);
880
881 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600882 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700883 restorable_state.Create(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
884
885 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
886 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
887 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
888 &as_validation_buffer_info.descriptor_set, 0, nullptr);
889 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
890
891 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
892 // have been replaced by the validation compute shader before any builds take place.
893 VkBufferMemoryBarrier instance_buffer_barrier = {};
894 instance_buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
895 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
896 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
897 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
898 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
899 instance_buffer_barrier.buffer = instanceData;
900 instance_buffer_barrier.offset = instanceOffset;
901 instance_buffer_barrier.size = instance_buffer_size;
902 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
903 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
904 nullptr);
905
906 // Restore the previous compute pipeline state.
907 restorable_state.Restore(commandBuffer);
908
909 as_validation_state.validation_buffers[commandBuffer].push_back(std::move(as_validation_buffer_info));
910}
911
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600912void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700913 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
914 return;
915 }
916
Tony-LunarG99b880b2019-09-26 11:19:52 -0600917 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700918 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[cb_node->commandBuffer];
919 for (const auto &as_validation_buffer_info : as_validation_buffer_infos) {
920 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
921
Tony-LunarG99b880b2019-09-26 11:19:52 -0600922 VkResult result =
923 vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700924 if (result == VK_SUCCESS) {
925 if (mapped_validation_buffer->invalid_handle_found > 0) {
926 uint64_t invalid_handle = 0;
927 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
928 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
929
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700930 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
931 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
932 "handle (%" PRIu64 ")",
933 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700934 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600935 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700936 }
937 }
938}
939
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600940void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
941 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
942 VkResult result) {
943 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600944 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600945 for (uint32_t i = 0; i < bindInfoCount; i++) {
946 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
947 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureState(info.accelerationStructure);
948 if (as_state) {
949 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
950 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600951 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600952}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700953
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600954// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
955void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
956 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
957 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600958 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600959 return;
960 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600961
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600962 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
963
Tony-LunarG99b880b2019-09-26 11:19:52 -0600964 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600965 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600966 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600967 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
968 << "Validation is not modifying the pipeline layout. "
969 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700970 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600971 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700972 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -0600973 }
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700974}
975
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600976void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
977 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
978 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600979 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
980
Karl Schultz7b024b42018-08-30 16:18:18 -0600981 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700982 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600983 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600984 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600985}
986
Karl Schultz7b024b42018-08-30 16:18:18 -0600987// Free the device memory and descriptor set associated with a command buffer.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600988void GpuAssisted::ResetCommandBuffer(VkCommandBuffer commandBuffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600989 if (aborted) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600990 return;
991 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600992 auto gpuav_buffer_list = GetBufferInfo(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600993 for (auto buffer_info : gpuav_buffer_list) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600994 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600995 if (buffer_info.di_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600996 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600997 }
998 if (buffer_info.bda_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600999 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -06001000 }
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001001 if (buffer_info.desc_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001002 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001003 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001004 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001005 command_buffer_map.erase(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -07001006
Tony-LunarG99b880b2019-09-26 11:19:52 -06001007 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -07001008 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[commandBuffer];
1009 for (auto &as_validation_buffer_info : as_validation_buffer_infos) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001010 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -07001011 as_validation_buffer_info.validation_buffer_allocation);
1012
1013 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001014 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool,
1015 as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001016 }
1017 }
1018 as_validation_info.validation_buffers.erase(commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001019}
Karl Schultz7b024b42018-08-30 16:18:18 -06001020// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001021bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1022 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1023 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1024 uint32_t bufferMemoryBarrierCount,
1025 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001026 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001027 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001028 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001029 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1030 "GPU_Assisted validation waits on queue completion. "
1031 "This wait could block the host's signaling of this event, resulting in deadlock.");
1032 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001033 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001034}
1035
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001036void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1037 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1038 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06001039 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001040 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1041 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1042 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001043 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1044 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001045 }
1046 }
1047}
1048
1049void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1050 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1051 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -06001052 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001053 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1054 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1055 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001056 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1057 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001058 }
1059 }
1060}
1061
1062void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1063 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1064 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1065 void *cgpl_state_data) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001066 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001067 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001068 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1069 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001070 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1071 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001072}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001073
1074void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1075 const VkComputePipelineCreateInfo *pCreateInfos,
1076 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1077 void *ccpl_state_data) {
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001078 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001079 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001080 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1081 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001082 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1083 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Jason Macnak67407e72019-07-11 11:05:09 -07001084}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001085
1086void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1087 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1088 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1089 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001090 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001091 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001092 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1093 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001094 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1095 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001096}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001097
1098void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1099 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1100 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1101 void *crtpl_state_data) {
1102 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1103 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001104 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1105 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001106 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1107 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
1108}
Karl Schultz7b024b42018-08-30 16:18:18 -06001109
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001110void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1111 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1112 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1113 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001114 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1115 pPipelines, result, cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001116 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001117}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001118
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001119void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1120 const VkComputePipelineCreateInfo *pCreateInfos,
1121 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1122 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001123 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1124 result, ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001125 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001126}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001127
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001128void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1129 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1130 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1131 VkResult result, void *crtpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001132 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1133 pPipelines, result, crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001134 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001135}
1136
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001137void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1138 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1139 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1140 VkResult result, void *crtpl_state_data) {
1141 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(device, pipelineCache, count, pCreateInfos, pAllocator,
1142 pPipelines, result, crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001143 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001144}
1145
1146// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001147void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001148 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001149 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001150 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001151 } else {
1152 ++it;
1153 }
1154 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001155 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001156}
1157
1158// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001159bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1160 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001161 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001162 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1163
1164 // Load original shader SPIR-V
1165 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1166 new_pgm.clear();
1167 new_pgm.reserve(num_words);
1168 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1169
1170 // Call the optimizer to instrument the shader.
1171 // Use the unique_shader_module_id as a shader ID so we can look up its handle later in the shader_map.
Tony-LunarGa77cade2019-03-06 10:49:22 -07001172 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001173 using namespace spvtools;
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06001174 spv_target_env target_env = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
Karl Schultz7b024b42018-08-30 16:18:18 -06001175 Optimizer optimizer(target_env);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001176 optimizer.RegisterPass(
Tony-LunarGab47cac2019-12-20 15:28:01 -07001177 CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing, descriptor_indexing));
Karl Schultz7b024b42018-08-30 16:18:18 -06001178 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG5c38b182020-06-10 16:15:32 -06001179 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64 &&
1180 enabled_features.core12.bufferDeviceAddress)
Tony-LunarG99b880b2019-09-26 11:19:52 -06001181 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Karl Schultz7b024b42018-08-30 16:18:18 -06001182 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm);
1183 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001184 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001185 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001186 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001187 return pass;
1188}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001189// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001190void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1191 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1192 void *csm_state_data) {
1193 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1194 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001195 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001196 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1197 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001198 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001199}
1200
Karl Schultz7b024b42018-08-30 16:18:18 -06001201// Generate the part of the message describing the violation.
1202static void GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg) {
1203 using namespace spvtools;
1204 std::ostringstream strm;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001205 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001206 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001207 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1208 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001209 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001210 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001211 case kInstErrorBindlessUninit: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001212 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized. ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001213 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001214 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001215 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001216 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001217 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1218 vuid_msg = "UNASSIGNED-Device address out of bounds";
1219 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001220 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001221 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001222 vuid_msg = "UNASSIGNED-Internal Error";
1223 assert(false);
1224 } break;
1225 }
1226 msg = strm.str();
1227}
1228
Karl Schultz7b024b42018-08-30 16:18:18 -06001229// Pull together all the information from the debug record to build the error message strings,
1230// and then assemble them into a single message string.
1231// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1232// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1233// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1234// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1235//
Tony-LunarG1dce2392019-10-23 16:49:29 -06001236void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, VkPipelineBindPoint pipeline_bind_point,
1237 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001238 using namespace spvtools;
1239 const uint32_t total_words = debug_output_buffer[0];
1240 // A zero here means that the shader instrumentation didn't write anything.
1241 // If you have nothing to say, don't say it here.
1242 if (0 == total_words) {
1243 return;
1244 }
1245 // The first word in the debug output buffer is the number of words that would have
1246 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1247 // The number of words actually written by the shaders is determined by the size of the buffer
1248 // we provide via the descriptor. So, we process only the number of words that can fit in the
1249 // buffer.
1250 // Each "report" written by the shader instrumentation is considered a "record". This function
1251 // is hard-coded to process only one record because it expects the buffer to be large enough to
1252 // hold only one record. If there is a desire to process more than one record, this function needs
1253 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001254 std::string validation_message;
1255 std::string stage_message;
1256 std::string common_message;
1257 std::string filename_message;
1258 std::string source_message;
1259 std::string vuid_msg;
1260 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1261 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1262 std::vector<unsigned int> pgm;
1263 // The first record starts at this offset after the total_words.
1264 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1265 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1266 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001267 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1268 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001269 shader_module_handle = it->second.shader_module;
1270 pipeline_handle = it->second.pipeline;
1271 pgm = it->second.pgm;
1272 }
1273 GenerateValidationMessage(debug_record, validation_message, vuid_msg);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001274 UtilGenerateStageMessage(debug_record, stage_message);
1275 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle, pipeline_bind_point,
1276 operation_index, common_message);
1277 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001278 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1279 filename_message.c_str(), source_message.c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001280 // The debug record at word kInstCommonOutSize is the number of words in the record
1281 // written by the shader. Clear the entire record plus the total_words word at the start.
Tony-LunarGab47cac2019-12-20 15:28:01 -07001282 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], (uint32_t)kInstMaxOutCnt);
Karl Schultz7b024b42018-08-30 16:18:18 -06001283 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1284}
1285
Tony-LunarG81efe392019-03-07 15:43:27 -07001286// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001287void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001288 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Tony-LunarG81efe392019-03-07 15:43:27 -07001289 uint32_t *pData;
1290 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001291 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001292 VkResult result = vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, (void **)&pData);
Tony-LunarG81efe392019-03-07 15:43:27 -07001293 if (result == VK_SUCCESS) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001294 for (auto update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001295 if (update.second->updated) pData[update.first] = 1;
1296 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001297 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001298 }
1299 }
1300 }
1301}
1302
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001303void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001304 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1305 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1306 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001307 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001308 UpdateInstrumentationBuffer(cb_node);
1309 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
1310 UpdateInstrumentationBuffer(secondaryCmdBuffer);
1311 }
1312 }
1313 }
1314}
1315
Karl Schultz58674242019-01-22 15:35:02 -07001316// Issue a memory barrier to make GPU-written data available to host.
1317// Wait for the queue to complete execution.
1318// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001319void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1320 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001321 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001322
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001323 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001324 bool buffers_present = false;
1325 // Don't QueueWaitIdle if there's nothing to process
1326 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1327 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1328 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
1329 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001330 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001331 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001332 if (GetBufferInfo(secondaryCmdBuffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd)
Jason Macnak83cfd582019-07-31 10:14:24 -07001333 buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001334 }
1335 }
1336 }
1337 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001338
Tony-LunarGb5fae462020-03-05 12:43:25 -07001339 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001340
Tony-LunarG152a88b2019-03-20 15:42:24 -06001341 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001342
Karl Schultz7b024b42018-08-30 16:18:18 -06001343 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1344 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1345 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001346 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001347 UtilProcessInstrumentationBuffer(queue, cb_node, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001348 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001349 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarGb5fae462020-03-05 12:43:25 -07001350 UtilProcessInstrumentationBuffer(queue, secondaryCmdBuffer, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001351 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001352 }
1353 }
1354 }
1355}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001356
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001357void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1358 uint32_t firstVertex, uint32_t firstInstance) {
1359 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1360}
1361
1362void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1363 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
1364 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1365}
1366
1367void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1368 uint32_t stride) {
1369 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1370}
1371
1372void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1373 uint32_t count, uint32_t stride) {
1374 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1375}
1376
1377void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
1378 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1379}
1380
1381void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
1382 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1383}
1384
1385void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1386 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1387 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1388 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1389 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1390 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1391 uint32_t width, uint32_t height, uint32_t depth) {
1392 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
1393}
1394
1395void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1396 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1397 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1398 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1399 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1400 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1401 uint32_t width, uint32_t height, uint32_t depth) {
1402 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1403 cb_state->hasTraceRaysCmd = true;
1404}
1405
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001406void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1407 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1408 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1409 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1410 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1411 uint32_t height, uint32_t depth) {
1412 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1413}
1414
1415void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1416 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1417 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1418 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1419 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1420 uint32_t height, uint32_t depth) {
1421 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1422 cb_state->hasTraceRaysCmd = true;
1423}
1424
1425void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1426 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1427 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1428 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1429 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, VkBuffer buffer,
1430 VkDeviceSize offset) {
1431 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1432}
1433
1434void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1435 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1436 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1437 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1438 const VkStridedBufferRegionKHR *pCallableShaderBindingTable,
1439 VkBuffer buffer, VkDeviceSize offset) {
1440 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1441 cb_state->hasTraceRaysCmd = true;
1442}
1443
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001444void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Jason Macnak67407e72019-07-11 11:05:09 -07001445 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1446 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001447 return;
1448 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001449 VkResult result;
1450
Tony-LunarG99b880b2019-09-26 11:19:52 -06001451 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001452
1453 std::vector<VkDescriptorSet> desc_sets;
1454 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001455 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001456 assert(result == VK_SUCCESS);
1457 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001458 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001459 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001460 return;
1461 }
1462
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001463 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001464 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001465
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001466 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001467 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001468 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001469 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001470 return;
1471 }
1472
Tony-LunarG81efe392019-03-07 15:43:27 -07001473 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001474 GpuAssistedDeviceMemoryBlock output_block = {};
Tony-LunarG0e564722019-03-19 16:09:14 -06001475 VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001476 bufferInfo.size = output_buffer_size;
Tony-LunarG0e564722019-03-19 16:09:14 -06001477 bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1478 VmaAllocationCreateInfo allocInfo = {};
1479 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001480 result = vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001481 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001482 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001483 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001484 return;
1485 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001486
Tony-LunarG81efe392019-03-07 15:43:27 -07001487 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGa77cade2019-03-06 10:49:22 -07001488 uint32_t *pData;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001489 result = vmaMapMemory(vmaAllocator, output_block.allocation, (void **)&pData);
Tony-LunarG0e564722019-03-19 16:09:14 -06001490 if (result == VK_SUCCESS) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001491 memset(pData, 0, output_buffer_size);
1492 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001493 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001494
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001495 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001496 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1497 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1498 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001499 uint32_t desc_count = 1;
1500 auto const &state = cb_node->lastBound[bind_point];
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001501 uint32_t number_of_sets = (uint32_t)state.per_set.size();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001502
Tony-LunarG81efe392019-03-07 15:43:27 -07001503 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1504 // and how big each of the bindings is
Tony-LunarG5c38b182020-06-10 16:15:32 -06001505 if (number_of_sets > 0 && descriptor_indexing) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001506 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1507 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001508 for (auto s : state.per_set) {
1509 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001510 if (desc && (desc->GetBindingCount() > 0)) {
1511 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001512 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1513 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001514 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1515 // blocks
1516 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1517 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001518 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1519 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1520 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001521 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001522 descriptor_count += desc->GetVariableDescriptorCount();
1523 } else {
1524 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1525 }
1526 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001527 }
1528 }
1529
Tony-LunarGa77cade2019-03-06 10:49:22 -07001530 // Note that the size of the input buffer is dependent on the maximum binding number, which
1531 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1532 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1533 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1534 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1535 uint32_t words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001536 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1537 bufferInfo.size = words_needed * 4;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001538 result =
1539 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &di_input_block.buffer, &di_input_block.allocation, nullptr);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001540 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001541 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001542 aborted = true;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001543 return;
1544 }
1545
Tony-LunarGa77cade2019-03-06 10:49:22 -07001546 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1547 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1548 // outline of the input buffer format
Tony-LunarG99b880b2019-09-26 11:19:52 -06001549 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, (void **)&pData);
Tony-LunarG76cdcac2019-05-22 16:13:12 -06001550 memset(pData, 0, static_cast<size_t>(bufferInfo.size));
Tony-LunarGa77cade2019-03-06 10:49:22 -07001551 // Pointer to a sets array that points into the sizes array
1552 uint32_t *sets_to_sizes = pData + 1;
1553 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1554 uint32_t *sizes = sets_to_sizes + number_of_sets;
1555 // Pointer to another sets array that points into the bindings array that points into the written array
1556 uint32_t *sets_to_bindings = sizes + binding_count;
1557 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1558 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1559 // Index of the next entry in the written array to be updated
1560 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001561 uint32_t bindCounter = number_of_sets + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001562 // Index of the start of the sets_to_bindings array
1563 pData[0] = number_of_sets + binding_count + 1;
1564
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001565 for (auto s : state.per_set) {
1566 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001567 if (desc && (desc->GetBindingCount() > 0)) {
1568 auto layout = desc->GetLayout();
1569 auto bindings = layout->GetSortedBindingSet();
Tony-LunarG81efe392019-03-07 15:43:27 -07001570 // For each set, fill in index of its bindings sizes in the sizes array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001571 *sets_to_sizes++ = bindCounter;
Tony-LunarG81efe392019-03-07 15:43:27 -07001572 // For each set, fill in the index of its bindings in the bindings_to_written array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001573 *sets_to_bindings++ = bindCounter + number_of_sets + binding_count;
Tony-LunarG81efe392019-03-07 15:43:27 -07001574 for (auto binding : bindings) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001575 // For each binding, fill in its size in the sizes array
Tony-LunarG7564b382019-08-21 10:11:35 -06001576 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1577 // blocks
1578 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1579 sizes[binding] = 1;
1580 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001581 sizes[binding] = desc->GetVariableDescriptorCount();
1582 } else {
1583 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
1584 }
1585 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1586 bindings_to_written[binding] = written_index;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001587
Tony-LunarG7564b382019-08-21 10:11:35 -06001588 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1589 // blocks
1590 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1591 pData[written_index++] = 1;
1592 continue;
1593 }
1594
Tony-LunarGa77cade2019-03-06 10:49:22 -07001595 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1596 // For each array element in the binding, update the written array with whether it has been written
1597 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1598 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
Tony-LunarG81efe392019-03-07 15:43:27 -07001599 if (descriptor->updated) {
1600 pData[written_index] = 1;
1601 } else if (desc->IsUpdateAfterBind(binding)) {
1602 // If it hasn't been written now and it's update after bind, put it in a list to check at QueueSubmit
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001603 di_input_block.update_at_submit[written_index] = descriptor;
Tony-LunarG81efe392019-03-07 15:43:27 -07001604 }
Tony-LunarGa77cade2019-03-06 10:49:22 -07001605 written_index++;
1606 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001607 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001608 auto last = desc->GetLayout()->GetMaxBinding();
1609 bindings_to_written += last + 1;
1610 bindCounter += last + 1;
1611 sizes += last + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001612 } else {
1613 *sets_to_sizes++ = 0;
1614 *sets_to_bindings++ = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001615 }
1616 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001617 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001618
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001619 di_input_desc_buffer_info.range = (words_needed * 4);
1620 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1621 di_input_desc_buffer_info.offset = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001622
1623 desc_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1624 desc_writes[1].dstBinding = 1;
1625 desc_writes[1].descriptorCount = 1;
1626 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001627 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001628 desc_writes[1].dstSet = desc_sets[0];
1629
1630 desc_count = 2;
Tony-LunarG0e564722019-03-19 16:09:14 -06001631 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001632
Tony-LunarGc111b242020-06-30 14:43:45 -06001633 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && buffer_map.size() &&
Tony-LunarG5c38b182020-06-10 16:15:32 -06001634 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001635 // Example BDA input buffer assuming 2 buffers using BDA:
1636 // Word 0 | Index of start of buffer sizes (in this case 5)
1637 // Word 1 | 0x0000000000000000
1638 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1639 // Word 3 | Device Address of second buffer
1640 // Word 4 | 0xffffffffffffffff
1641 // Word 5 | 0 (size of pretend buffer at word 1)
1642 // Word 6 | Size in bytes of first buffer
1643 // Word 7 | Size in bytes of second buffer
1644 // Word 8 | 0 (size of pretend buffer in word 4)
1645
Tony-LunarG99b880b2019-09-26 11:19:52 -06001646 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001647 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
1648 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1649 bufferInfo.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06001650 result =
1651 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001652 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001653 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001654 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001655 return;
1656 }
1657 uint64_t *bda_data;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001658 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, (void **)&bda_data);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001659 uint32_t address_index = 1;
1660 uint32_t size_index = 3 + num_buffers;
1661 memset(bda_data, 0, static_cast<size_t>(bufferInfo.size));
1662 bda_data[0] = size_index; // Start of buffer sizes
1663 bda_data[address_index++] = 0; // NULL address
1664 bda_data[size_index++] = 0;
1665
Tony-LunarG99b880b2019-09-26 11:19:52 -06001666 for (auto const &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001667 bda_data[address_index++] = value.first;
1668 bda_data[size_index++] = value.second;
1669 }
1670 bda_data[address_index] = UINTPTR_MAX;
1671 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001672 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001673
1674 bda_input_desc_buffer_info.range = (words_needed * 8);
1675 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
1676 bda_input_desc_buffer_info.offset = 0;
1677
1678 desc_writes[desc_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1679 desc_writes[desc_count].dstBinding = 2;
1680 desc_writes[desc_count].descriptorCount = 1;
1681 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1682 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
1683 desc_writes[desc_count].dstSet = desc_sets[0];
1684 desc_count++;
1685 }
1686
Tony-LunarGb2501d22019-01-28 09:59:13 -07001687 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001688 output_desc_buffer_info.buffer = output_block.buffer;
1689 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001690
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001691 desc_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1692 desc_writes[0].descriptorCount = 1;
1693 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1694 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
1695 desc_writes[0].dstSet = desc_sets[0];
1696 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001697
andreyg25ce2622019-04-05 23:07:59 +03001698 auto iter = cb_node->lastBound.find(bind_point); // find() allows read-only access to cb_state
Tony-LunarGb2501d22019-01-28 09:59:13 -07001699 if (iter != cb_node->lastBound.end()) {
1700 auto pipeline_state = iter->second.pipeline_state;
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001701 if (pipeline_state && (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
1702 !pipeline_state->pipeline_layout->destroyed) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001703 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06001704 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001705 }
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001706 if (pipeline_state && pipeline_state->pipeline_layout->destroyed) {
1707 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
1708 aborted = true;
1709 } else {
1710 // Record buffer and memory info in CB state tracking
1711 GetBufferInfo(cmd_buffer)
1712 .emplace_back(output_block, di_input_block, bda_input_block, desc_sets[0], desc_pool, bind_point);
1713 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001714 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001715 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001716 aborted = true;
1717 }
1718 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001719 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
1720 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
1721 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001722 return;
1723 }
1724}