blob: 27d3ab181d846ce8c2b542d0d0aef05c26a9efb0 [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-LunarG04dc83c2020-07-07 13:53:02 -0600248 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700249 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600250 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
251 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600252 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600253 return;
254 }
255
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700256 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600257 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700258 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
259 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600260 }
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600261 device_gpu_assisted->shaderInt64 = supported_features.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600262 device_gpu_assisted->physicalDevice = physicalDevice;
263 device_gpu_assisted->device = *pDevice;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600264 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarG5c38b182020-06-10 16:15:32 -0600265 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600266 std::vector<VkDescriptorSetLayoutBinding> bindings;
267 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
268 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT | kShaderStageAllRayTracing,
269 NULL};
270 bindings.push_back(binding);
271 for (auto i = 1; i < 3; i++) {
272 binding.binding = i;
273 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600274 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700275 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600276 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600277}
278
Tony-LunarG588c7052020-04-23 10:47:21 -0600279void GpuAssisted::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
280 VkDeviceAddress address) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600281 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
282 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600283 if (buffer_state) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600284 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600285 buffer_state->deviceAddress = address;
286 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600287}
288
Tony-LunarG588c7052020-04-23 10:47:21 -0600289void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
290 VkDeviceAddress address) {
291 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
292}
293
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700294void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
295 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600296 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700297}
298
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600299void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600300 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600301 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG2966c732020-05-21 10:33:53 -0600302 ValidationStateTracker::PreCallRecordDestroyBuffer(device, buffer, pAllocator);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600303}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600304
Karl Schultz7b024b42018-08-30 16:18:18 -0600305// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600306void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600307 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700308 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600309 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -0600310}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600311
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600312void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600313 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700314 return;
315 }
316
Tony-LunarG99b880b2019-09-26 11:19:52 -0600317 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700318 if (as_validation_state.initialized) {
319 return;
320 }
321
322 if (!device_extensions.vk_nv_ray_tracing) {
323 return;
324 }
325
326 // Outline:
327 // - Create valid bottom level acceleration structure which acts as replacement
328 // - Create and load vertex buffer
329 // - Create and load index buffer
330 // - Create, allocate memory for, and bind memory for acceleration structure
331 // - Query acceleration structure handle
332 // - Create command pool and command buffer
333 // - Record build acceleration structure command
334 // - Submit command buffer and wait for completion
335 // - Cleanup
336 // - Create compute pipeline for validating instance buffers
337 // - Create descriptor set layout
338 // - Create pipeline layout
339 // - Create pipeline
340 // - Cleanup
341
342 VkResult result = VK_SUCCESS;
343
344 VkBuffer vbo = VK_NULL_HANDLE;
345 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
346 if (result == VK_SUCCESS) {
347 VkBufferCreateInfo vbo_ci = {};
348 vbo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
349 vbo_ci.size = sizeof(float) * 9;
350 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
351
352 VmaAllocationCreateInfo vbo_ai = {};
353 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
354 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
355
Tony-LunarG99b880b2019-09-26 11:19:52 -0600356 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700357 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700358 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700359 }
360 }
361
362 if (result == VK_SUCCESS) {
363 uint8_t *mapped_vbo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600364 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, (void **)&mapped_vbo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700365 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700366 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700367 } else {
368 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
369 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600370 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700371 }
372 }
373
374 VkBuffer ibo = VK_NULL_HANDLE;
375 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
376 if (result == VK_SUCCESS) {
377 VkBufferCreateInfo ibo_ci = {};
378 ibo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
379 ibo_ci.size = sizeof(uint32_t) * 3;
380 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
381
382 VmaAllocationCreateInfo ibo_ai = {};
383 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
384 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
385
Tony-LunarG99b880b2019-09-26 11:19:52 -0600386 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700387 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700388 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700389 }
390 }
391
392 if (result == VK_SUCCESS) {
393 uint8_t *mapped_ibo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600394 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, (void **)&mapped_ibo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700395 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700396 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700397 } else {
398 const std::vector<uint32_t> indicies = {0, 1, 2};
399 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600400 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700401 }
402 }
403
404 VkGeometryNV geometry = {};
405 geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
406 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
407 geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
408 geometry.geometry.triangles.vertexData = vbo;
409 geometry.geometry.triangles.vertexOffset = 0;
410 geometry.geometry.triangles.vertexCount = 3;
411 geometry.geometry.triangles.vertexStride = 12;
412 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
413 geometry.geometry.triangles.indexData = ibo;
414 geometry.geometry.triangles.indexOffset = 0;
415 geometry.geometry.triangles.indexCount = 3;
416 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
417 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
418 geometry.geometry.triangles.transformOffset = 0;
419 geometry.geometry.aabbs = {};
420 geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
421
422 VkAccelerationStructureCreateInfoNV as_ci = {};
423 as_ci.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
424 as_ci.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
425 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
426 as_ci.info.instanceCount = 0;
427 as_ci.info.geometryCount = 1;
428 as_ci.info.pGeometries = &geometry;
429 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600430 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700431 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700432 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700433 "Failed to create acceleration structure for acceleration structure build validation.");
434 }
435 }
436
437 VkMemoryRequirements2 as_mem_requirements = {};
438 if (result == VK_SUCCESS) {
439 VkAccelerationStructureMemoryRequirementsInfoNV as_mem_requirements_info = {};
440 as_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
441 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
442 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
443
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600444 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700445 }
446
447 VmaAllocationInfo as_memory_ai = {};
448 if (result == VK_SUCCESS) {
449 VmaAllocationCreateInfo as_memory_aci = {};
450 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
451
Tony-LunarG99b880b2019-09-26 11:19:52 -0600452 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
453 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700454 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700455 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700456 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
457 }
458 }
459
460 if (result == VK_SUCCESS) {
461 VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
462 as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
463 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
464 as_bind_info.memory = as_memory_ai.deviceMemory;
465 as_bind_info.memoryOffset = as_memory_ai.offset;
466
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600467 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700468 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700469 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700470 "Failed to bind acceleration structure memory for acceleration structure build validation.");
471 }
472 }
473
474 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600475 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
476 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700477 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700478 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700479 "Failed to get acceleration structure handle for acceleration structure build validation.");
480 }
481 }
482
483 VkMemoryRequirements2 scratch_mem_requirements = {};
484 if (result == VK_SUCCESS) {
485 VkAccelerationStructureMemoryRequirementsInfoNV scratch_mem_requirements_info = {};
486 scratch_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
487 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
488 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
489
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600490 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
491 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700492 }
493
494 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600495 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700496 if (result == VK_SUCCESS) {
497 VkBufferCreateInfo scratch_ci = {};
498 scratch_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
499 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
500 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700501 VmaAllocationCreateInfo scratch_aci = {};
502 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
503
Tony-LunarG18900282020-05-20 12:34:33 -0600504 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700505 if (result != VK_SUCCESS) {
Tony-LunarG18900282020-05-20 12:34:33 -0600506 ReportSetupProblem(device_gpuav->device,
507 "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700508 }
509 }
510
511 VkCommandPool command_pool = VK_NULL_HANDLE;
512 if (result == VK_SUCCESS) {
513 VkCommandPoolCreateInfo command_pool_ci = {};
514 command_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
515 command_pool_ci.queueFamilyIndex = 0;
516
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600517 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700518 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700519 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700520 }
521 }
522
523 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
524
525 if (result == VK_SUCCESS) {
526 VkCommandBufferAllocateInfo command_buffer_ai = {};
527 command_buffer_ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
528 command_buffer_ai.commandPool = command_pool;
529 command_buffer_ai.commandBufferCount = 1;
530 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
531
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600532 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700533 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700534 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700535 "Failed to create command buffer for acceleration structure build validation.");
536 }
537
538 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600539 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700540 }
541
542 if (result == VK_SUCCESS) {
543 VkCommandBufferBeginInfo command_buffer_bi = {};
544 command_buffer_bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
545
546 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
547 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700548 ReportSetupProblem(device_gpuav->device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700549 }
550 }
551
552 if (result == VK_SUCCESS) {
553 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
554 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
555 DispatchEndCommandBuffer(command_buffer);
556 }
557
558 VkQueue queue = VK_NULL_HANDLE;
559 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600560 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700561
562 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600563 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700564
565 VkSubmitInfo submit_info = {};
566 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
567 submit_info.commandBufferCount = 1;
568 submit_info.pCommandBuffers = &command_buffer;
569 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
570 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700571 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700572 "Failed to submit command buffer for acceleration structure build validation.");
573 }
574 }
575
576 if (result == VK_SUCCESS) {
577 result = DispatchQueueWaitIdle(queue);
578 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700579 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700580 }
581 }
582
583 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600584 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700585 }
586 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600587 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700588 }
589 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG18900282020-05-20 12:34:33 -0600590 vmaDestroyBuffer(device_gpuav->vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700591 }
592 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600593 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700594 }
595
Tony-LunarG99b880b2019-09-26 11:19:52 -0600596 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700597 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700598 "Failed to find descriptor set layout for acceleration structure build validation.");
599 result = VK_INCOMPLETE;
600 }
601
602 if (result == VK_SUCCESS) {
603 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
604 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
605 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600606 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600607 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700608 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700609 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700610 "Failed to create pipeline layout for acceleration structure build validation.");
611 }
612 }
613
614 VkShaderModule shader_module = VK_NULL_HANDLE;
615 if (result == VK_SUCCESS) {
616 VkShaderModuleCreateInfo shader_module_ci = {};
617 shader_module_ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
618 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
619 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
620
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600621 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700622 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700623 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700624 "Failed to create compute shader module for acceleration structure build validation.");
625 }
626 }
627
628 if (result == VK_SUCCESS) {
629 VkPipelineShaderStageCreateInfo pipeline_stage_ci = {};
630 pipeline_stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
631 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
632 pipeline_stage_ci.module = shader_module;
633 pipeline_stage_ci.pName = "main";
634
635 VkComputePipelineCreateInfo pipeline_ci = {};
636 pipeline_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
637 pipeline_ci.stage = pipeline_stage_ci;
638 pipeline_ci.layout = as_validation_state.pipeline_layout;
639
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600640 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
641 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700642 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700643 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700644 "Failed to create compute pipeline for acceleration structure build validation.");
645 }
646 }
647
648 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600649 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700650 }
651
652 if (result == VK_SUCCESS) {
653 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700654 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600655 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700656 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600657 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700658 }
659}
660
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600661void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600662 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700663 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
664 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
665 }
666 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
667 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
668 }
669 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
670 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
671 }
672 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600673 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700674 }
675}
676
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600677struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700678 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
679 VkPipeline pipeline = VK_NULL_HANDLE;
680 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
681 std::vector<VkDescriptorSet> descriptor_sets;
682 std::vector<std::vector<uint32_t>> dynamic_offsets;
683 uint32_t push_descriptor_set_index = 0;
684 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
685 std::vector<uint8_t> push_constants_data;
686 PushConstantRangesId push_constants_ranges;
687
688 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
689 pipeline_bind_point = bind_point;
690
691 LAST_BOUND_STATE &last_bound = cb_state->lastBound[bind_point];
692 if (last_bound.pipeline_state) {
693 pipeline = last_bound.pipeline_state->pipeline;
694 pipeline_layout = last_bound.pipeline_layout;
695 descriptor_sets.reserve(last_bound.per_set.size());
696 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
697 const auto *bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
698
699 descriptor_sets.push_back(bound_descriptor_set->GetSet());
700 if (bound_descriptor_set->IsPushDescriptor()) {
701 push_descriptor_set_index = static_cast<uint32_t>(i);
702 }
703 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
704 }
705
706 if (last_bound.push_descriptor_set) {
707 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
708 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500709 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700710 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500711 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700712 }
713 }
714 }
715
716 void Restore(VkCommandBuffer command_buffer) const {
717 if (pipeline != VK_NULL_HANDLE) {
718 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
719 if (!descriptor_sets.empty()) {
720 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
721 VkDescriptorSet descriptor_set = descriptor_sets[i];
722 if (descriptor_set != VK_NULL_HANDLE) {
723 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
724 static_cast<uint32_t>(i), 1, &descriptor_set,
725 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
726 }
727 }
728 }
729 if (!push_descriptor_set_writes.empty()) {
730 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
731 static_cast<uint32_t>(push_descriptor_set_writes.size()),
732 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
733 }
734 for (const auto &push_constant_range : *push_constants_ranges) {
735 if (push_constant_range.size == 0) continue;
736 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
737 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
738 }
739 }
740 }
741};
742
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600743void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
744 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
745 VkDeviceSize instanceOffset, VkBool32 update,
746 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
747 VkBuffer scratch, VkDeviceSize scratchOffset) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700748 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
749 return;
750 }
751
Tony-LunarG99b880b2019-09-26 11:19:52 -0600752 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700753 if (!as_validation_state.initialized) {
754 return;
755 }
756
757 // Empty acceleration structure is valid according to the spec.
758 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
759 return;
760 }
761
762 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
763 assert(cb_state != nullptr);
764
765 std::vector<uint64_t> current_valid_handles;
766 for (const auto &as_state_kv : accelerationStructureMap) {
767 const ACCELERATION_STRUCTURE_STATE &as_state = *as_state_kv.second;
Jeff Bolz95176d02020-04-01 00:36:16 -0500768 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700769 current_valid_handles.push_back(as_state.opaque_handle);
770 }
771 }
772
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600773 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700774 as_validation_buffer_info.acceleration_structure = dst;
775
776 const VkDeviceSize validation_buffer_size =
777 // One uint for number of instances to validate
778 4 +
779 // Two uint for the replacement acceleration structure handle
780 8 +
781 // One uint for number of invalid handles found
782 4 +
783 // Two uint for the first invalid handle found
784 8 +
785 // One uint for the number of current valid handles
786 4 +
787 // Two uint for each current valid handle
788 (8 * current_valid_handles.size());
789
790 VkBufferCreateInfo validation_buffer_create_info = {};
791 validation_buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
792 validation_buffer_create_info.size = validation_buffer_size;
793 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
794
795 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
796 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
797
Tony-LunarG99b880b2019-09-26 11:19:52 -0600798 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
799 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700800 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
801 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700802 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600803 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700804 return;
805 }
806
807 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600808 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700809 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700810 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600811 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700812 return;
813 }
814
815 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
816 mapped_validation_buffer->replacement_handle_bits_0 =
817 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
818 mapped_validation_buffer->replacement_handle_bits_1 =
819 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
820 mapped_validation_buffer->invalid_handle_found = 0;
821 mapped_validation_buffer->invalid_handle_bits_0 = 0;
822 mapped_validation_buffer->invalid_handle_bits_1 = 0;
823 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
824
825 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
826 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
827 const uint64_t current_valid_handle = current_valid_handles[i];
828
829 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
830 ++mapped_valid_handles;
831 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
832 ++mapped_valid_handles;
833 }
834
Tony-LunarG99b880b2019-09-26 11:19:52 -0600835 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700836
837 static constexpr const VkDeviceSize kInstanceSize = 64;
838 const VkDeviceSize instance_buffer_size = kInstanceSize * pInfo->instanceCount;
839
Tony-LunarG1dce2392019-10-23 16:49:29 -0600840 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
841 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700842 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700843 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600844 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700845 return;
846 }
847
848 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
849 descriptor_buffer_infos[0].buffer = instanceData;
850 descriptor_buffer_infos[0].offset = instanceOffset;
851 descriptor_buffer_infos[0].range = instance_buffer_size;
852 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
853 descriptor_buffer_infos[1].offset = 0;
854 descriptor_buffer_infos[1].range = validation_buffer_size;
855
856 VkWriteDescriptorSet descriptor_set_writes[2] = {};
857 descriptor_set_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
858 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
859 descriptor_set_writes[0].dstBinding = 0;
860 descriptor_set_writes[0].descriptorCount = 1;
861 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
862 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
863 descriptor_set_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
864 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
865 descriptor_set_writes[1].dstBinding = 1;
866 descriptor_set_writes[1].descriptorCount = 1;
867 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
868 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
869
870 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
871
872 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
873 VkMemoryBarrier memory_barrier = {};
874 memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
875 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
876 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
877 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
878 &memory_barrier, 0, nullptr, 0, nullptr);
879
880 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600881 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700882 restorable_state.Create(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
883
884 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
885 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
886 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
887 &as_validation_buffer_info.descriptor_set, 0, nullptr);
888 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
889
890 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
891 // have been replaced by the validation compute shader before any builds take place.
892 VkBufferMemoryBarrier instance_buffer_barrier = {};
893 instance_buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
894 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
895 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
896 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
897 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
898 instance_buffer_barrier.buffer = instanceData;
899 instance_buffer_barrier.offset = instanceOffset;
900 instance_buffer_barrier.size = instance_buffer_size;
901 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
902 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
903 nullptr);
904
905 // Restore the previous compute pipeline state.
906 restorable_state.Restore(commandBuffer);
907
908 as_validation_state.validation_buffers[commandBuffer].push_back(std::move(as_validation_buffer_info));
909}
910
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600911void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700912 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
913 return;
914 }
915
Tony-LunarG99b880b2019-09-26 11:19:52 -0600916 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700917 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[cb_node->commandBuffer];
918 for (const auto &as_validation_buffer_info : as_validation_buffer_infos) {
919 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
920
Tony-LunarG99b880b2019-09-26 11:19:52 -0600921 VkResult result =
922 vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700923 if (result == VK_SUCCESS) {
924 if (mapped_validation_buffer->invalid_handle_found > 0) {
925 uint64_t invalid_handle = 0;
926 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
927 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
928
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700929 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
930 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
931 "handle (%" PRIu64 ")",
932 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700933 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600934 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700935 }
936 }
937}
938
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600939void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
940 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
941 VkResult result) {
942 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600943 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600944 for (uint32_t i = 0; i < bindInfoCount; i++) {
945 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
946 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureState(info.accelerationStructure);
947 if (as_state) {
948 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
949 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600950 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600951}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700952
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600953// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
954void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
955 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
956 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600957 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600958 return;
959 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600960
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600961 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
962
Tony-LunarG99b880b2019-09-26 11:19:52 -0600963 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600964 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600965 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600966 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
967 << "Validation is not modifying the pipeline layout. "
968 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700969 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600970 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700971 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -0600972 }
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700973}
974
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600975void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
976 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
977 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600978 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
979
Karl Schultz7b024b42018-08-30 16:18:18 -0600980 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700981 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600982 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600983 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600984}
985
Karl Schultz7b024b42018-08-30 16:18:18 -0600986// Free the device memory and descriptor set associated with a command buffer.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600987void GpuAssisted::ResetCommandBuffer(VkCommandBuffer commandBuffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600988 if (aborted) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600989 return;
990 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600991 auto gpuav_buffer_list = GetBufferInfo(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600992 for (auto buffer_info : gpuav_buffer_list) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600993 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600994 if (buffer_info.di_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600995 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600996 }
997 if (buffer_info.bda_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600998 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600999 }
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001000 if (buffer_info.desc_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001001 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001002 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001003 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001004 command_buffer_map.erase(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -07001005
Tony-LunarG99b880b2019-09-26 11:19:52 -06001006 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -07001007 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[commandBuffer];
1008 for (auto &as_validation_buffer_info : as_validation_buffer_infos) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001009 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -07001010 as_validation_buffer_info.validation_buffer_allocation);
1011
1012 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001013 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool,
1014 as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001015 }
1016 }
1017 as_validation_info.validation_buffers.erase(commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001018}
Karl Schultz7b024b42018-08-30 16:18:18 -06001019// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001020bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1021 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1022 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1023 uint32_t bufferMemoryBarrierCount,
1024 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001025 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001026 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001027 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001028 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1029 "GPU_Assisted validation waits on queue completion. "
1030 "This wait could block the host's signaling of this event, resulting in deadlock.");
1031 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001032 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001033}
1034
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001035void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1036 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1037 // 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 -06001038 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001039 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1040 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1041 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001042 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1043 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001044 }
1045 }
1046}
1047
1048void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1049 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1050 // 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 -06001051 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001052 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1053 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1054 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001055 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1056 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001057 }
1058 }
1059}
1060
1061void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1062 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1063 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1064 void *cgpl_state_data) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001065 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001066 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001067 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1068 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001069 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1070 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001071}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001072
1073void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1074 const VkComputePipelineCreateInfo *pCreateInfos,
1075 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1076 void *ccpl_state_data) {
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001077 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001078 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001079 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1080 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001081 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1082 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Jason Macnak67407e72019-07-11 11:05:09 -07001083}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001084
1085void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1086 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1087 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1088 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001089 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001090 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001091 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1092 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001093 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1094 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001095}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001096
1097void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1098 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1099 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1100 void *crtpl_state_data) {
1101 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1102 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001103 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1104 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001105 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1106 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
1107}
Karl Schultz7b024b42018-08-30 16:18:18 -06001108
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001109void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1110 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1111 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1112 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001113 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1114 pPipelines, result, cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001115 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001116}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001117
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001118void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1119 const VkComputePipelineCreateInfo *pCreateInfos,
1120 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1121 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001122 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1123 result, ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001124 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001125}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001126
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001127void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1128 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1129 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1130 VkResult result, void *crtpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001131 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1132 pPipelines, result, crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001133 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001134}
1135
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001136void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1137 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1138 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1139 VkResult result, void *crtpl_state_data) {
1140 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(device, pipelineCache, count, pCreateInfos, pAllocator,
1141 pPipelines, result, crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001142 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001143}
1144
1145// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001146void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001147 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001148 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001149 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001150 } else {
1151 ++it;
1152 }
1153 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001154 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001155}
1156
1157// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001158bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1159 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001160 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001161 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1162
1163 // Load original shader SPIR-V
1164 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1165 new_pgm.clear();
1166 new_pgm.reserve(num_words);
1167 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1168
1169 // Call the optimizer to instrument the shader.
1170 // 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 -07001171 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001172 using namespace spvtools;
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06001173 spv_target_env target_env = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
Karl Schultz7b024b42018-08-30 16:18:18 -06001174 Optimizer optimizer(target_env);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001175 optimizer.RegisterPass(
Tony-LunarGab47cac2019-12-20 15:28:01 -07001176 CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing, descriptor_indexing));
Karl Schultz7b024b42018-08-30 16:18:18 -06001177 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG5c38b182020-06-10 16:15:32 -06001178 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64 &&
1179 enabled_features.core12.bufferDeviceAddress)
Tony-LunarG99b880b2019-09-26 11:19:52 -06001180 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Karl Schultz7b024b42018-08-30 16:18:18 -06001181 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm);
1182 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001183 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001184 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001185 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001186 return pass;
1187}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001188// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001189void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1190 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1191 void *csm_state_data) {
1192 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1193 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001194 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001195 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1196 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001197 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001198}
1199
Karl Schultz7b024b42018-08-30 16:18:18 -06001200// Generate the part of the message describing the violation.
1201static void GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg) {
1202 using namespace spvtools;
1203 std::ostringstream strm;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001204 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001205 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001206 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1207 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001208 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001209 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001210 case kInstErrorBindlessUninit: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001211 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized. ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001212 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001213 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001214 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001215 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001216 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1217 vuid_msg = "UNASSIGNED-Device address out of bounds";
1218 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001219 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001220 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001221 vuid_msg = "UNASSIGNED-Internal Error";
1222 assert(false);
1223 } break;
1224 }
1225 msg = strm.str();
1226}
1227
Karl Schultz7b024b42018-08-30 16:18:18 -06001228// Pull together all the information from the debug record to build the error message strings,
1229// and then assemble them into a single message string.
1230// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1231// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1232// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1233// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1234//
Tony-LunarG1dce2392019-10-23 16:49:29 -06001235void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, VkPipelineBindPoint pipeline_bind_point,
1236 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001237 using namespace spvtools;
1238 const uint32_t total_words = debug_output_buffer[0];
1239 // A zero here means that the shader instrumentation didn't write anything.
1240 // If you have nothing to say, don't say it here.
1241 if (0 == total_words) {
1242 return;
1243 }
1244 // The first word in the debug output buffer is the number of words that would have
1245 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1246 // The number of words actually written by the shaders is determined by the size of the buffer
1247 // we provide via the descriptor. So, we process only the number of words that can fit in the
1248 // buffer.
1249 // Each "report" written by the shader instrumentation is considered a "record". This function
1250 // is hard-coded to process only one record because it expects the buffer to be large enough to
1251 // hold only one record. If there is a desire to process more than one record, this function needs
1252 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001253 std::string validation_message;
1254 std::string stage_message;
1255 std::string common_message;
1256 std::string filename_message;
1257 std::string source_message;
1258 std::string vuid_msg;
1259 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1260 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1261 std::vector<unsigned int> pgm;
1262 // The first record starts at this offset after the total_words.
1263 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1264 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1265 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001266 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1267 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001268 shader_module_handle = it->second.shader_module;
1269 pipeline_handle = it->second.pipeline;
1270 pgm = it->second.pgm;
1271 }
1272 GenerateValidationMessage(debug_record, validation_message, vuid_msg);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001273 UtilGenerateStageMessage(debug_record, stage_message);
1274 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle, pipeline_bind_point,
1275 operation_index, common_message);
1276 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001277 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1278 filename_message.c_str(), source_message.c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001279 // The debug record at word kInstCommonOutSize is the number of words in the record
1280 // written by the shader. Clear the entire record plus the total_words word at the start.
Tony-LunarGab47cac2019-12-20 15:28:01 -07001281 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], (uint32_t)kInstMaxOutCnt);
Karl Schultz7b024b42018-08-30 16:18:18 -06001282 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1283}
1284
Tony-LunarG81efe392019-03-07 15:43:27 -07001285// 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 -06001286void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001287 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Tony-LunarG81efe392019-03-07 15:43:27 -07001288 uint32_t *pData;
1289 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001290 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001291 VkResult result = vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, (void **)&pData);
Tony-LunarG81efe392019-03-07 15:43:27 -07001292 if (result == VK_SUCCESS) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001293 for (auto update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001294 if (update.second->updated) pData[update.first] = 1;
1295 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001296 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001297 }
1298 }
1299 }
1300}
1301
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001302void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001303 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1304 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1305 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001306 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001307 UpdateInstrumentationBuffer(cb_node);
1308 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
1309 UpdateInstrumentationBuffer(secondaryCmdBuffer);
1310 }
1311 }
1312 }
1313}
1314
Karl Schultz58674242019-01-22 15:35:02 -07001315// Issue a memory barrier to make GPU-written data available to host.
1316// Wait for the queue to complete execution.
1317// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001318void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1319 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001320 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001321
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001322 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001323 bool buffers_present = false;
1324 // Don't QueueWaitIdle if there's nothing to process
1325 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1326 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1327 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
1328 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001329 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001330 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001331 if (GetBufferInfo(secondaryCmdBuffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd)
Jason Macnak83cfd582019-07-31 10:14:24 -07001332 buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001333 }
1334 }
1335 }
1336 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001337
Tony-LunarGb5fae462020-03-05 12:43:25 -07001338 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001339
Tony-LunarG152a88b2019-03-20 15:42:24 -06001340 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001341
Karl Schultz7b024b42018-08-30 16:18:18 -06001342 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1343 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1344 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001345 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001346 UtilProcessInstrumentationBuffer(queue, cb_node, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001347 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001348 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarGb5fae462020-03-05 12:43:25 -07001349 UtilProcessInstrumentationBuffer(queue, secondaryCmdBuffer, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001350 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001351 }
1352 }
1353 }
1354}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001355
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001356void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1357 uint32_t firstVertex, uint32_t firstInstance) {
1358 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1359}
1360
1361void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1362 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
1363 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1364}
1365
1366void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1367 uint32_t stride) {
1368 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1369}
1370
1371void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1372 uint32_t count, uint32_t stride) {
1373 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1374}
1375
1376void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
1377 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1378}
1379
1380void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
1381 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1382}
1383
1384void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1385 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1386 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1387 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1388 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1389 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1390 uint32_t width, uint32_t height, uint32_t depth) {
1391 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
1392}
1393
1394void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1395 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1396 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1397 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1398 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1399 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1400 uint32_t width, uint32_t height, uint32_t depth) {
1401 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1402 cb_state->hasTraceRaysCmd = true;
1403}
1404
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001405void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1406 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1407 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1408 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1409 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1410 uint32_t height, uint32_t depth) {
1411 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1412}
1413
1414void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1415 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1416 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1417 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1418 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1419 uint32_t height, uint32_t depth) {
1420 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1421 cb_state->hasTraceRaysCmd = true;
1422}
1423
1424void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1425 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1426 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1427 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1428 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, VkBuffer buffer,
1429 VkDeviceSize offset) {
1430 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1431}
1432
1433void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1434 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1435 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1436 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1437 const VkStridedBufferRegionKHR *pCallableShaderBindingTable,
1438 VkBuffer buffer, VkDeviceSize offset) {
1439 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1440 cb_state->hasTraceRaysCmd = true;
1441}
1442
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001443void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Jason Macnak67407e72019-07-11 11:05:09 -07001444 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1445 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001446 return;
1447 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001448 VkResult result;
1449
Tony-LunarG99b880b2019-09-26 11:19:52 -06001450 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001451
1452 std::vector<VkDescriptorSet> desc_sets;
1453 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001454 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001455 assert(result == VK_SUCCESS);
1456 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001457 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001458 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001459 return;
1460 }
1461
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001462 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001463 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001464
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001465 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001466 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001467 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001468 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001469 return;
1470 }
1471
Tony-LunarG81efe392019-03-07 15:43:27 -07001472 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001473 GpuAssistedDeviceMemoryBlock output_block = {};
Tony-LunarG0e564722019-03-19 16:09:14 -06001474 VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001475 bufferInfo.size = output_buffer_size;
Tony-LunarG0e564722019-03-19 16:09:14 -06001476 bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1477 VmaAllocationCreateInfo allocInfo = {};
1478 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001479 result = vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001480 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001481 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001482 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001483 return;
1484 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001485
Tony-LunarG81efe392019-03-07 15:43:27 -07001486 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGa77cade2019-03-06 10:49:22 -07001487 uint32_t *pData;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001488 result = vmaMapMemory(vmaAllocator, output_block.allocation, (void **)&pData);
Tony-LunarG0e564722019-03-19 16:09:14 -06001489 if (result == VK_SUCCESS) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001490 memset(pData, 0, output_buffer_size);
1491 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001492 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001493
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001494 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001495 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1496 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1497 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001498 uint32_t desc_count = 1;
1499 auto const &state = cb_node->lastBound[bind_point];
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001500 uint32_t number_of_sets = (uint32_t)state.per_set.size();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001501
Tony-LunarG81efe392019-03-07 15:43:27 -07001502 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1503 // and how big each of the bindings is
Tony-LunarG5c38b182020-06-10 16:15:32 -06001504 if (number_of_sets > 0 && descriptor_indexing) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001505 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1506 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001507 for (auto s : state.per_set) {
1508 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001509 if (desc && (desc->GetBindingCount() > 0)) {
1510 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001511 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1512 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001513 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1514 // blocks
1515 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1516 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001517 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1518 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1519 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001520 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001521 descriptor_count += desc->GetVariableDescriptorCount();
1522 } else {
1523 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1524 }
1525 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001526 }
1527 }
1528
Tony-LunarGa77cade2019-03-06 10:49:22 -07001529 // Note that the size of the input buffer is dependent on the maximum binding number, which
1530 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1531 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1532 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1533 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1534 uint32_t words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001535 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1536 bufferInfo.size = words_needed * 4;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001537 result =
1538 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &di_input_block.buffer, &di_input_block.allocation, nullptr);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001539 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001540 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001541 aborted = true;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001542 return;
1543 }
1544
Tony-LunarGa77cade2019-03-06 10:49:22 -07001545 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1546 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1547 // outline of the input buffer format
Tony-LunarG99b880b2019-09-26 11:19:52 -06001548 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, (void **)&pData);
Tony-LunarG76cdcac2019-05-22 16:13:12 -06001549 memset(pData, 0, static_cast<size_t>(bufferInfo.size));
Tony-LunarGa77cade2019-03-06 10:49:22 -07001550 // Pointer to a sets array that points into the sizes array
1551 uint32_t *sets_to_sizes = pData + 1;
1552 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1553 uint32_t *sizes = sets_to_sizes + number_of_sets;
1554 // Pointer to another sets array that points into the bindings array that points into the written array
1555 uint32_t *sets_to_bindings = sizes + binding_count;
1556 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1557 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1558 // Index of the next entry in the written array to be updated
1559 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001560 uint32_t bindCounter = number_of_sets + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001561 // Index of the start of the sets_to_bindings array
1562 pData[0] = number_of_sets + binding_count + 1;
1563
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001564 for (auto s : state.per_set) {
1565 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001566 if (desc && (desc->GetBindingCount() > 0)) {
1567 auto layout = desc->GetLayout();
1568 auto bindings = layout->GetSortedBindingSet();
Tony-LunarG81efe392019-03-07 15:43:27 -07001569 // For each set, fill in index of its bindings sizes in the sizes array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001570 *sets_to_sizes++ = bindCounter;
Tony-LunarG81efe392019-03-07 15:43:27 -07001571 // For each set, fill in the index of its bindings in the bindings_to_written array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001572 *sets_to_bindings++ = bindCounter + number_of_sets + binding_count;
Tony-LunarG81efe392019-03-07 15:43:27 -07001573 for (auto binding : bindings) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001574 // For each binding, fill in its size in the sizes array
Tony-LunarG7564b382019-08-21 10:11:35 -06001575 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1576 // blocks
1577 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1578 sizes[binding] = 1;
1579 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001580 sizes[binding] = desc->GetVariableDescriptorCount();
1581 } else {
1582 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
1583 }
1584 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1585 bindings_to_written[binding] = written_index;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001586
Tony-LunarG7564b382019-08-21 10:11:35 -06001587 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1588 // blocks
1589 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1590 pData[written_index++] = 1;
1591 continue;
1592 }
1593
Tony-LunarGa77cade2019-03-06 10:49:22 -07001594 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1595 // For each array element in the binding, update the written array with whether it has been written
1596 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1597 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
Tony-LunarG81efe392019-03-07 15:43:27 -07001598 if (descriptor->updated) {
1599 pData[written_index] = 1;
1600 } else if (desc->IsUpdateAfterBind(binding)) {
1601 // 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 -06001602 di_input_block.update_at_submit[written_index] = descriptor;
Tony-LunarG81efe392019-03-07 15:43:27 -07001603 }
Tony-LunarGa77cade2019-03-06 10:49:22 -07001604 written_index++;
1605 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001606 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001607 auto last = desc->GetLayout()->GetMaxBinding();
1608 bindings_to_written += last + 1;
1609 bindCounter += last + 1;
1610 sizes += last + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001611 } else {
1612 *sets_to_sizes++ = 0;
1613 *sets_to_bindings++ = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001614 }
1615 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001616 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001617
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001618 di_input_desc_buffer_info.range = (words_needed * 4);
1619 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1620 di_input_desc_buffer_info.offset = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001621
1622 desc_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1623 desc_writes[1].dstBinding = 1;
1624 desc_writes[1].descriptorCount = 1;
1625 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001626 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001627 desc_writes[1].dstSet = desc_sets[0];
1628
1629 desc_count = 2;
Tony-LunarG0e564722019-03-19 16:09:14 -06001630 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001631
Tony-LunarGc111b242020-06-30 14:43:45 -06001632 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 -06001633 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001634 // Example BDA input buffer assuming 2 buffers using BDA:
1635 // Word 0 | Index of start of buffer sizes (in this case 5)
1636 // Word 1 | 0x0000000000000000
1637 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1638 // Word 3 | Device Address of second buffer
1639 // Word 4 | 0xffffffffffffffff
1640 // Word 5 | 0 (size of pretend buffer at word 1)
1641 // Word 6 | Size in bytes of first buffer
1642 // Word 7 | Size in bytes of second buffer
1643 // Word 8 | 0 (size of pretend buffer in word 4)
1644
Tony-LunarG99b880b2019-09-26 11:19:52 -06001645 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001646 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
1647 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1648 bufferInfo.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06001649 result =
1650 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001651 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001652 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001653 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001654 return;
1655 }
1656 uint64_t *bda_data;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001657 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, (void **)&bda_data);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001658 uint32_t address_index = 1;
1659 uint32_t size_index = 3 + num_buffers;
1660 memset(bda_data, 0, static_cast<size_t>(bufferInfo.size));
1661 bda_data[0] = size_index; // Start of buffer sizes
1662 bda_data[address_index++] = 0; // NULL address
1663 bda_data[size_index++] = 0;
1664
Tony-LunarG99b880b2019-09-26 11:19:52 -06001665 for (auto const &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001666 bda_data[address_index++] = value.first;
1667 bda_data[size_index++] = value.second;
1668 }
1669 bda_data[address_index] = UINTPTR_MAX;
1670 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001671 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001672
1673 bda_input_desc_buffer_info.range = (words_needed * 8);
1674 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
1675 bda_input_desc_buffer_info.offset = 0;
1676
1677 desc_writes[desc_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1678 desc_writes[desc_count].dstBinding = 2;
1679 desc_writes[desc_count].descriptorCount = 1;
1680 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1681 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
1682 desc_writes[desc_count].dstSet = desc_sets[0];
1683 desc_count++;
1684 }
1685
Tony-LunarGb2501d22019-01-28 09:59:13 -07001686 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001687 output_desc_buffer_info.buffer = output_block.buffer;
1688 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001689
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001690 desc_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1691 desc_writes[0].descriptorCount = 1;
1692 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1693 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
1694 desc_writes[0].dstSet = desc_sets[0];
1695 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001696
andreyg25ce2622019-04-05 23:07:59 +03001697 auto iter = cb_node->lastBound.find(bind_point); // find() allows read-only access to cb_state
Tony-LunarGb2501d22019-01-28 09:59:13 -07001698 if (iter != cb_node->lastBound.end()) {
1699 auto pipeline_state = iter->second.pipeline_state;
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001700 if (pipeline_state && (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
1701 !pipeline_state->pipeline_layout->destroyed) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001702 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06001703 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001704 }
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001705 if (pipeline_state && pipeline_state->pipeline_layout->destroyed) {
1706 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
1707 aborted = true;
1708 } else {
1709 // Record buffer and memory info in CB state tracking
1710 GetBufferInfo(cmd_buffer)
1711 .emplace_back(output_block, di_input_block, bda_input_block, desc_sets[0], desc_pool, bind_point);
1712 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001713 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001714 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001715 aborted = true;
1716 }
1717 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001718 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
1719 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
1720 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001721 return;
1722 }
1723}