blob: 2857c19b75dbae524871c55b870ad86e8b0b8591 [file] [log] [blame]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001/* Copyright (c) 2018-2021 The Khronos Group Inc.
2 * Copyright (c) 2018-2021 Valve Corporation
3 * Copyright (c) 2018-2021 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
Tony-LunarGc28e28a2020-08-14 10:37:48 -060021#include <climits>
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070022#include "gpu_validation.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060023#include "spirv-tools/optimizer.hpp"
24#include "spirv-tools/instrument.hpp"
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060025#include "layer_chassis_dispatch.h"
Tony-LunarG7de10e82020-11-24 11:31:55 -070026#include "gpu_vuids.h"
Jeremy Gebbena3705f42021-01-19 16:47:43 -070027#include "sync_utils.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060028
Jason Macnak67407e72019-07-11 11:05:09 -070029static const VkShaderStageFlags kShaderStageAllRayTracing =
30 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
31 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
32
Jason Macnak83cfd582019-07-31 10:14:24 -070033// Keep in sync with the GLSL shader below.
34struct GpuAccelerationStructureBuildValidationBuffer {
35 uint32_t instances_to_validate;
36 uint32_t replacement_handle_bits_0;
37 uint32_t replacement_handle_bits_1;
38 uint32_t invalid_handle_found;
39 uint32_t invalid_handle_bits_0;
40 uint32_t invalid_handle_bits_1;
41 uint32_t valid_handles_count;
42};
43
44// This is the GLSL source for the compute shader that is used during ray tracing acceleration structure
45// building validation which inspects instance buffers for top level acceleration structure builds and
46// reports and replaces invalid bottom level acceleration structure handles with good bottom level
47// acceleration structure handle so that applications can continue without undefined behavior long enough
48// to report errors.
49//
50// #version 450
51// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
52// struct VkGeometryInstanceNV {
53// uint unused[14];
54// uint handle_bits_0;
55// uint handle_bits_1;
56// };
57// layout(set=0, binding=0, std430) buffer InstanceBuffer {
58// VkGeometryInstanceNV instances[];
59// };
60// layout(set=0, binding=1, std430) buffer ValidationBuffer {
61// uint instances_to_validate;
62// uint replacement_handle_bits_0;
63// uint replacement_handle_bits_1;
64// uint invalid_handle_found;
65// uint invalid_handle_bits_0;
66// uint invalid_handle_bits_1;
67// uint valid_handles_count;
68// uint valid_handles[];
69// };
70// void main() {
71// for (uint instance_index = 0; instance_index < instances_to_validate; instance_index++) {
72// uint instance_handle_bits_0 = instances[instance_index].handle_bits_0;
73// uint instance_handle_bits_1 = instances[instance_index].handle_bits_1;
74// bool valid = false;
75// for (uint valid_handle_index = 0; valid_handle_index < valid_handles_count; valid_handle_index++) {
76// if (instance_handle_bits_0 == valid_handles[2*valid_handle_index+0] &&
77// instance_handle_bits_1 == valid_handles[2*valid_handle_index+1]) {
78// valid = true;
79// break;
80// }
81// }
82// if (!valid) {
83// invalid_handle_found += 1;
84// invalid_handle_bits_0 = instance_handle_bits_0;
85// invalid_handle_bits_1 = instance_handle_bits_1;
86// instances[instance_index].handle_bits_0 = replacement_handle_bits_0;
87// instances[instance_index].handle_bits_1 = replacement_handle_bits_1;
88// }
89// }
90// }
91//
92// To regenerate the spirv below:
93// 1. Save the above GLSL source to a file called validation_shader.comp.
94// 2. Run in terminal
95//
96// glslangValidator.exe -x -V validation_shader.comp -o validation_shader.comp.spv
97//
98// 4. Copy-paste the contents of validation_shader.comp.spv here (clang-format will fix up the alignment).
99static const uint32_t kComputeShaderSpirv[] = {
100 0x07230203, 0x00010000, 0x00080007, 0x0000006d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
101 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005, 0x00000004, 0x6e69616d,
102 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2,
103 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x00000008, 0x74736e69, 0x65636e61, 0x646e695f, 0x00007865,
104 0x00070005, 0x00000011, 0x696c6156, 0x69746164, 0x75426e6f, 0x72656666, 0x00000000, 0x00090006, 0x00000011, 0x00000000,
105 0x74736e69, 0x65636e61, 0x6f745f73, 0x6c61765f, 0x74616469, 0x00000065, 0x000a0006, 0x00000011, 0x00000001, 0x6c706572,
106 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x000a0006, 0x00000011, 0x00000002, 0x6c706572,
107 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00090006, 0x00000011, 0x00000003, 0x61766e69,
108 0x5f64696c, 0x646e6168, 0x665f656c, 0x646e756f, 0x00000000, 0x00090006, 0x00000011, 0x00000004, 0x61766e69, 0x5f64696c,
109 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00090006, 0x00000011, 0x00000005, 0x61766e69, 0x5f64696c, 0x646e6168,
110 0x625f656c, 0x5f737469, 0x00000031, 0x00080006, 0x00000011, 0x00000006, 0x696c6176, 0x61685f64, 0x656c646e, 0x6f635f73,
111 0x00746e75, 0x00070006, 0x00000011, 0x00000007, 0x696c6176, 0x61685f64, 0x656c646e, 0x00000073, 0x00030005, 0x00000013,
112 0x00000000, 0x00080005, 0x0000001b, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000305f, 0x00080005,
113 0x0000001e, 0x65476b56, 0x74656d6f, 0x6e497972, 0x6e617473, 0x564e6563, 0x00000000, 0x00050006, 0x0000001e, 0x00000000,
114 0x73756e75, 0x00006465, 0x00070006, 0x0000001e, 0x00000001, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00070006,
115 0x0000001e, 0x00000002, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00060005, 0x00000020, 0x74736e49, 0x65636e61,
116 0x66667542, 0x00007265, 0x00060006, 0x00000020, 0x00000000, 0x74736e69, 0x65636e61, 0x00000073, 0x00030005, 0x00000022,
117 0x00000000, 0x00080005, 0x00000027, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000315f, 0x00040005,
118 0x0000002d, 0x696c6176, 0x00000064, 0x00070005, 0x0000002f, 0x696c6176, 0x61685f64, 0x656c646e, 0x646e695f, 0x00007865,
119 0x00040047, 0x00000010, 0x00000006, 0x00000004, 0x00050048, 0x00000011, 0x00000000, 0x00000023, 0x00000000, 0x00050048,
120 0x00000011, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000011, 0x00000002, 0x00000023, 0x00000008, 0x00050048,
121 0x00000011, 0x00000003, 0x00000023, 0x0000000c, 0x00050048, 0x00000011, 0x00000004, 0x00000023, 0x00000010, 0x00050048,
122 0x00000011, 0x00000005, 0x00000023, 0x00000014, 0x00050048, 0x00000011, 0x00000006, 0x00000023, 0x00000018, 0x00050048,
123 0x00000011, 0x00000007, 0x00000023, 0x0000001c, 0x00030047, 0x00000011, 0x00000003, 0x00040047, 0x00000013, 0x00000022,
124 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000001, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00050048,
125 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000038, 0x00050048,
126 0x0000001e, 0x00000002, 0x00000023, 0x0000003c, 0x00040047, 0x0000001f, 0x00000006, 0x00000040, 0x00050048, 0x00000020,
127 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000003, 0x00040047, 0x00000022, 0x00000022, 0x00000000,
128 0x00040047, 0x00000022, 0x00000021, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015,
129 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x0004002b, 0x00000006, 0x00000009,
130 0x00000000, 0x0003001d, 0x00000010, 0x00000006, 0x000a001e, 0x00000011, 0x00000006, 0x00000006, 0x00000006, 0x00000006,
131 0x00000006, 0x00000006, 0x00000006, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012,
132 0x00000013, 0x00000002, 0x00040015, 0x00000014, 0x00000020, 0x00000001, 0x0004002b, 0x00000014, 0x00000015, 0x00000000,
133 0x00040020, 0x00000016, 0x00000002, 0x00000006, 0x00020014, 0x00000019, 0x0004002b, 0x00000006, 0x0000001c, 0x0000000e,
134 0x0004001c, 0x0000001d, 0x00000006, 0x0000001c, 0x0005001e, 0x0000001e, 0x0000001d, 0x00000006, 0x00000006, 0x0003001d,
135 0x0000001f, 0x0000001e, 0x0003001e, 0x00000020, 0x0000001f, 0x00040020, 0x00000021, 0x00000002, 0x00000020, 0x0004003b,
136 0x00000021, 0x00000022, 0x00000002, 0x0004002b, 0x00000014, 0x00000024, 0x00000001, 0x0004002b, 0x00000014, 0x00000029,
137 0x00000002, 0x00040020, 0x0000002c, 0x00000007, 0x00000019, 0x0003002a, 0x00000019, 0x0000002e, 0x0004002b, 0x00000014,
138 0x00000036, 0x00000006, 0x0004002b, 0x00000014, 0x0000003b, 0x00000007, 0x0004002b, 0x00000006, 0x0000003c, 0x00000002,
139 0x0004002b, 0x00000006, 0x00000048, 0x00000001, 0x00030029, 0x00000019, 0x00000050, 0x0004002b, 0x00000014, 0x00000058,
140 0x00000003, 0x0004002b, 0x00000014, 0x0000005d, 0x00000004, 0x0004002b, 0x00000014, 0x00000060, 0x00000005, 0x00050036,
141 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007,
142 0x0004003b, 0x00000007, 0x0000001b, 0x00000007, 0x0004003b, 0x00000007, 0x00000027, 0x00000007, 0x0004003b, 0x0000002c,
143 0x0000002d, 0x00000007, 0x0004003b, 0x00000007, 0x0000002f, 0x00000007, 0x0003003e, 0x00000008, 0x00000009, 0x000200f9,
144 0x0000000a, 0x000200f8, 0x0000000a, 0x000400f6, 0x0000000c, 0x0000000d, 0x00000000, 0x000200f9, 0x0000000e, 0x000200f8,
145 0x0000000e, 0x0004003d, 0x00000006, 0x0000000f, 0x00000008, 0x00050041, 0x00000016, 0x00000017, 0x00000013, 0x00000015,
146 0x0004003d, 0x00000006, 0x00000018, 0x00000017, 0x000500b0, 0x00000019, 0x0000001a, 0x0000000f, 0x00000018, 0x000400fa,
147 0x0000001a, 0x0000000b, 0x0000000c, 0x000200f8, 0x0000000b, 0x0004003d, 0x00000006, 0x00000023, 0x00000008, 0x00070041,
148 0x00000016, 0x00000025, 0x00000022, 0x00000015, 0x00000023, 0x00000024, 0x0004003d, 0x00000006, 0x00000026, 0x00000025,
149 0x0003003e, 0x0000001b, 0x00000026, 0x0004003d, 0x00000006, 0x00000028, 0x00000008, 0x00070041, 0x00000016, 0x0000002a,
150 0x00000022, 0x00000015, 0x00000028, 0x00000029, 0x0004003d, 0x00000006, 0x0000002b, 0x0000002a, 0x0003003e, 0x00000027,
151 0x0000002b, 0x0003003e, 0x0000002d, 0x0000002e, 0x0003003e, 0x0000002f, 0x00000009, 0x000200f9, 0x00000030, 0x000200f8,
152 0x00000030, 0x000400f6, 0x00000032, 0x00000033, 0x00000000, 0x000200f9, 0x00000034, 0x000200f8, 0x00000034, 0x0004003d,
153 0x00000006, 0x00000035, 0x0000002f, 0x00050041, 0x00000016, 0x00000037, 0x00000013, 0x00000036, 0x0004003d, 0x00000006,
154 0x00000038, 0x00000037, 0x000500b0, 0x00000019, 0x00000039, 0x00000035, 0x00000038, 0x000400fa, 0x00000039, 0x00000031,
155 0x00000032, 0x000200f8, 0x00000031, 0x0004003d, 0x00000006, 0x0000003a, 0x0000001b, 0x0004003d, 0x00000006, 0x0000003d,
156 0x0000002f, 0x00050084, 0x00000006, 0x0000003e, 0x0000003c, 0x0000003d, 0x00050080, 0x00000006, 0x0000003f, 0x0000003e,
157 0x00000009, 0x00060041, 0x00000016, 0x00000040, 0x00000013, 0x0000003b, 0x0000003f, 0x0004003d, 0x00000006, 0x00000041,
158 0x00000040, 0x000500aa, 0x00000019, 0x00000042, 0x0000003a, 0x00000041, 0x000300f7, 0x00000044, 0x00000000, 0x000400fa,
159 0x00000042, 0x00000043, 0x00000044, 0x000200f8, 0x00000043, 0x0004003d, 0x00000006, 0x00000045, 0x00000027, 0x0004003d,
160 0x00000006, 0x00000046, 0x0000002f, 0x00050084, 0x00000006, 0x00000047, 0x0000003c, 0x00000046, 0x00050080, 0x00000006,
161 0x00000049, 0x00000047, 0x00000048, 0x00060041, 0x00000016, 0x0000004a, 0x00000013, 0x0000003b, 0x00000049, 0x0004003d,
162 0x00000006, 0x0000004b, 0x0000004a, 0x000500aa, 0x00000019, 0x0000004c, 0x00000045, 0x0000004b, 0x000200f9, 0x00000044,
163 0x000200f8, 0x00000044, 0x000700f5, 0x00000019, 0x0000004d, 0x00000042, 0x00000031, 0x0000004c, 0x00000043, 0x000300f7,
164 0x0000004f, 0x00000000, 0x000400fa, 0x0000004d, 0x0000004e, 0x0000004f, 0x000200f8, 0x0000004e, 0x0003003e, 0x0000002d,
165 0x00000050, 0x000200f9, 0x00000032, 0x000200f8, 0x0000004f, 0x000200f9, 0x00000033, 0x000200f8, 0x00000033, 0x0004003d,
166 0x00000006, 0x00000052, 0x0000002f, 0x00050080, 0x00000006, 0x00000053, 0x00000052, 0x00000024, 0x0003003e, 0x0000002f,
167 0x00000053, 0x000200f9, 0x00000030, 0x000200f8, 0x00000032, 0x0004003d, 0x00000019, 0x00000054, 0x0000002d, 0x000400a8,
168 0x00000019, 0x00000055, 0x00000054, 0x000300f7, 0x00000057, 0x00000000, 0x000400fa, 0x00000055, 0x00000056, 0x00000057,
169 0x000200f8, 0x00000056, 0x00050041, 0x00000016, 0x00000059, 0x00000013, 0x00000058, 0x0004003d, 0x00000006, 0x0000005a,
170 0x00000059, 0x00050080, 0x00000006, 0x0000005b, 0x0000005a, 0x00000048, 0x00050041, 0x00000016, 0x0000005c, 0x00000013,
171 0x00000058, 0x0003003e, 0x0000005c, 0x0000005b, 0x0004003d, 0x00000006, 0x0000005e, 0x0000001b, 0x00050041, 0x00000016,
172 0x0000005f, 0x00000013, 0x0000005d, 0x0003003e, 0x0000005f, 0x0000005e, 0x0004003d, 0x00000006, 0x00000061, 0x00000027,
173 0x00050041, 0x00000016, 0x00000062, 0x00000013, 0x00000060, 0x0003003e, 0x00000062, 0x00000061, 0x0004003d, 0x00000006,
174 0x00000063, 0x00000008, 0x00050041, 0x00000016, 0x00000064, 0x00000013, 0x00000024, 0x0004003d, 0x00000006, 0x00000065,
175 0x00000064, 0x00070041, 0x00000016, 0x00000066, 0x00000022, 0x00000015, 0x00000063, 0x00000024, 0x0003003e, 0x00000066,
176 0x00000065, 0x0004003d, 0x00000006, 0x00000067, 0x00000008, 0x00050041, 0x00000016, 0x00000068, 0x00000013, 0x00000029,
177 0x0004003d, 0x00000006, 0x00000069, 0x00000068, 0x00070041, 0x00000016, 0x0000006a, 0x00000022, 0x00000015, 0x00000067,
178 0x00000029, 0x0003003e, 0x0000006a, 0x00000069, 0x000200f9, 0x00000057, 0x000200f8, 0x00000057, 0x000200f9, 0x0000000d,
179 0x000200f8, 0x0000000d, 0x0004003d, 0x00000006, 0x0000006b, 0x00000008, 0x00050080, 0x00000006, 0x0000006c, 0x0000006b,
180 0x00000024, 0x0003003e, 0x00000008, 0x0000006c, 0x000200f9, 0x0000000a, 0x000200f8, 0x0000000c, 0x000100fd, 0x00010038};
181
Karl Schultz7b024b42018-08-30 16:18:18 -0600182// Convenience function for reporting problems with setting up GPU Validation.
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700183template <typename T>
184void GpuAssisted::ReportSetupProblem(T object, const char *const specific_message) const {
185 LogError(object, "UNASSIGNED-GPU-Assisted Validation Error. ", "Detail: (%s)", specific_message);
Karl Schultz7b024b42018-08-30 16:18:18 -0600186}
187
Tony-LunarG5c38b182020-06-10 16:15:32 -0600188bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
189 bool result =
190 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
191 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
192 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
193 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
194 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
195 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
196 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
197 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
198 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
199 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
200 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
201 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
202 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
203 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
204 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
205 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
206 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
207 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
208 enabled_features.core12.descriptorBindingPartiallyBound ||
209 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
210 return result;
211}
212
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600213void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
214 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700215 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
216 // acceleration structure build validation will find and replace invalid acceleration structure
217 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600218 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
219 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
220 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700221 }
222}
223
Karl Schultz7b024b42018-08-30 16:18:18 -0600224// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600225void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
226 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600227 void *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600228 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600229 VkPhysicalDeviceFeatures features = {};
230 features.vertexPipelineStoresAndAtomics = true;
231 features.fragmentStoresAndAtomics = true;
232 features.shaderInt64 = true;
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600233 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), supported_features,
234 features);
Karl Schultz7b024b42018-08-30 16:18:18 -0600235}
Karl Schultz7b024b42018-08-30 16:18:18 -0600236// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600237void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
238 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
239 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600240 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600241
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600242 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
243 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
244 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700245
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600246 const char *bufferoob_string = getLayerOption("khronos_validation.gpuav_buffer_oob");
247 if (device_gpu_assisted->enabled_features.core.robustBufferAccess ||
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700248 device_gpu_assisted->enabled_features.robustness2_features.robustBufferAccess2) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600249 device_gpu_assisted->buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700250 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600251 device_gpu_assisted->buffer_oob_enabled = *bufferoob_string ? !strcmp(bufferoob_string, "true") : true;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700252 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600253
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600254 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700255 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600256 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600257 return;
258 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600259
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600260 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700261 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600262 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
263 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600264 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600265 return;
266 }
267
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700268 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600269 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700270 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
271 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600272 }
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600273 device_gpu_assisted->shaderInt64 = supported_features.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600274 device_gpu_assisted->physicalDevice = physicalDevice;
275 device_gpu_assisted->device = *pDevice;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600276 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarG5c38b182020-06-10 16:15:32 -0600277 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600278 std::vector<VkDescriptorSetLayoutBinding> bindings;
279 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -0600280 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
281 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
282 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600283 NULL};
284 bindings.push_back(binding);
285 for (auto i = 1; i < 3; i++) {
286 binding.binding = i;
287 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600288 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700289 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600290 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600291}
292
Mike Schuchardt2df08912020-12-15 16:28:09 -0800293void GpuAssisted::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600294 VkDeviceAddress address) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600295 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
296 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600297 if (buffer_state) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600298 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600299 buffer_state->deviceAddress = address;
300 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600301}
302
Mike Schuchardt2df08912020-12-15 16:28:09 -0800303void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600304 VkDeviceAddress address) {
305 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
306}
307
Mike Schuchardt2df08912020-12-15 16:28:09 -0800308void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700309 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600310 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700311}
312
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600313void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600314 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600315 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG2966c732020-05-21 10:33:53 -0600316 ValidationStateTracker::PreCallRecordDestroyBuffer(device, buffer, pAllocator);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600317}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600318
Karl Schultz7b024b42018-08-30 16:18:18 -0600319// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600320void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600321 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700322 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600323 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600324 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
325 if (vmaAllocator) {
326 vmaDestroyAllocator(vmaAllocator);
327 }
328 desc_set_manager.reset();
Karl Schultz7b024b42018-08-30 16:18:18 -0600329}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600330
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600331void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600332 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700333 return;
334 }
335
Tony-LunarG99b880b2019-09-26 11:19:52 -0600336 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700337 if (as_validation_state.initialized) {
338 return;
339 }
340
341 if (!device_extensions.vk_nv_ray_tracing) {
342 return;
343 }
344
345 // Outline:
346 // - Create valid bottom level acceleration structure which acts as replacement
347 // - Create and load vertex buffer
348 // - Create and load index buffer
349 // - Create, allocate memory for, and bind memory for acceleration structure
350 // - Query acceleration structure handle
351 // - Create command pool and command buffer
352 // - Record build acceleration structure command
353 // - Submit command buffer and wait for completion
354 // - Cleanup
355 // - Create compute pipeline for validating instance buffers
356 // - Create descriptor set layout
357 // - Create pipeline layout
358 // - Create pipeline
359 // - Cleanup
360
361 VkResult result = VK_SUCCESS;
362
363 VkBuffer vbo = VK_NULL_HANDLE;
364 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
365 if (result == VK_SUCCESS) {
366 VkBufferCreateInfo vbo_ci = {};
367 vbo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
368 vbo_ci.size = sizeof(float) * 9;
369 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
370
371 VmaAllocationCreateInfo vbo_ai = {};
372 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
373 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
374
Tony-LunarG99b880b2019-09-26 11:19:52 -0600375 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700376 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700377 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700378 }
379 }
380
381 if (result == VK_SUCCESS) {
382 uint8_t *mapped_vbo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700383 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700384 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700385 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700386 } else {
387 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
388 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600389 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700390 }
391 }
392
393 VkBuffer ibo = VK_NULL_HANDLE;
394 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
395 if (result == VK_SUCCESS) {
396 VkBufferCreateInfo ibo_ci = {};
397 ibo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
398 ibo_ci.size = sizeof(uint32_t) * 3;
399 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
400
401 VmaAllocationCreateInfo ibo_ai = {};
402 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
403 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
404
Tony-LunarG99b880b2019-09-26 11:19:52 -0600405 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700406 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700407 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700408 }
409 }
410
411 if (result == VK_SUCCESS) {
412 uint8_t *mapped_ibo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700413 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700414 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700415 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700416 } else {
417 const std::vector<uint32_t> indicies = {0, 1, 2};
418 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600419 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700420 }
421 }
422
423 VkGeometryNV geometry = {};
424 geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
425 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
426 geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
427 geometry.geometry.triangles.vertexData = vbo;
428 geometry.geometry.triangles.vertexOffset = 0;
429 geometry.geometry.triangles.vertexCount = 3;
430 geometry.geometry.triangles.vertexStride = 12;
431 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
432 geometry.geometry.triangles.indexData = ibo;
433 geometry.geometry.triangles.indexOffset = 0;
434 geometry.geometry.triangles.indexCount = 3;
435 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
436 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
437 geometry.geometry.triangles.transformOffset = 0;
438 geometry.geometry.aabbs = {};
439 geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
440
441 VkAccelerationStructureCreateInfoNV as_ci = {};
442 as_ci.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
443 as_ci.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
444 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
445 as_ci.info.instanceCount = 0;
446 as_ci.info.geometryCount = 1;
447 as_ci.info.pGeometries = &geometry;
448 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600449 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700450 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700451 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700452 "Failed to create acceleration structure for acceleration structure build validation.");
453 }
454 }
455
456 VkMemoryRequirements2 as_mem_requirements = {};
457 if (result == VK_SUCCESS) {
458 VkAccelerationStructureMemoryRequirementsInfoNV as_mem_requirements_info = {};
459 as_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
460 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
461 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
462
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600463 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700464 }
465
466 VmaAllocationInfo as_memory_ai = {};
467 if (result == VK_SUCCESS) {
468 VmaAllocationCreateInfo as_memory_aci = {};
469 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
470
Tony-LunarG99b880b2019-09-26 11:19:52 -0600471 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
472 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700473 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700474 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700475 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
476 }
477 }
478
479 if (result == VK_SUCCESS) {
480 VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
481 as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
482 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
483 as_bind_info.memory = as_memory_ai.deviceMemory;
484 as_bind_info.memoryOffset = as_memory_ai.offset;
485
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600486 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700487 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700488 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700489 "Failed to bind acceleration structure memory for acceleration structure build validation.");
490 }
491 }
492
493 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600494 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
495 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700496 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700497 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700498 "Failed to get acceleration structure handle for acceleration structure build validation.");
499 }
500 }
501
502 VkMemoryRequirements2 scratch_mem_requirements = {};
503 if (result == VK_SUCCESS) {
504 VkAccelerationStructureMemoryRequirementsInfoNV scratch_mem_requirements_info = {};
505 scratch_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
506 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
507 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
508
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600509 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
510 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700511 }
512
513 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600514 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700515 if (result == VK_SUCCESS) {
516 VkBufferCreateInfo scratch_ci = {};
517 scratch_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
518 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
519 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700520 VmaAllocationCreateInfo scratch_aci = {};
521 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
522
Tony-LunarG18900282020-05-20 12:34:33 -0600523 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700524 if (result != VK_SUCCESS) {
Tony-LunarG18900282020-05-20 12:34:33 -0600525 ReportSetupProblem(device_gpuav->device,
526 "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700527 }
528 }
529
530 VkCommandPool command_pool = VK_NULL_HANDLE;
531 if (result == VK_SUCCESS) {
532 VkCommandPoolCreateInfo command_pool_ci = {};
533 command_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
534 command_pool_ci.queueFamilyIndex = 0;
535
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600536 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700537 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700538 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700539 }
540 }
541
542 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
543
544 if (result == VK_SUCCESS) {
545 VkCommandBufferAllocateInfo command_buffer_ai = {};
546 command_buffer_ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
547 command_buffer_ai.commandPool = command_pool;
548 command_buffer_ai.commandBufferCount = 1;
549 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
550
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600551 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700552 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700553 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700554 "Failed to create command buffer for acceleration structure build validation.");
555 }
556
557 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600558 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700559 }
560
561 if (result == VK_SUCCESS) {
562 VkCommandBufferBeginInfo command_buffer_bi = {};
563 command_buffer_bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
564
565 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
566 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700567 ReportSetupProblem(device_gpuav->device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700568 }
569 }
570
571 if (result == VK_SUCCESS) {
572 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
573 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
574 DispatchEndCommandBuffer(command_buffer);
575 }
576
577 VkQueue queue = VK_NULL_HANDLE;
578 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600579 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700580
581 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600582 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700583
584 VkSubmitInfo submit_info = {};
585 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
586 submit_info.commandBufferCount = 1;
587 submit_info.pCommandBuffers = &command_buffer;
588 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
589 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700590 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700591 "Failed to submit command buffer for acceleration structure build validation.");
592 }
593 }
594
595 if (result == VK_SUCCESS) {
596 result = DispatchQueueWaitIdle(queue);
597 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700598 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700599 }
600 }
601
602 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600603 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700604 }
605 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600606 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700607 }
608 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG18900282020-05-20 12:34:33 -0600609 vmaDestroyBuffer(device_gpuav->vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700610 }
611 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600612 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700613 }
614
Tony-LunarG99b880b2019-09-26 11:19:52 -0600615 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700616 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700617 "Failed to find descriptor set layout for acceleration structure build validation.");
618 result = VK_INCOMPLETE;
619 }
620
621 if (result == VK_SUCCESS) {
622 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
623 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
624 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600625 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600626 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700627 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700628 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700629 "Failed to create pipeline layout for acceleration structure build validation.");
630 }
631 }
632
633 VkShaderModule shader_module = VK_NULL_HANDLE;
634 if (result == VK_SUCCESS) {
635 VkShaderModuleCreateInfo shader_module_ci = {};
636 shader_module_ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
637 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
638 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
639
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600640 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700641 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700642 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700643 "Failed to create compute shader module for acceleration structure build validation.");
644 }
645 }
646
647 if (result == VK_SUCCESS) {
648 VkPipelineShaderStageCreateInfo pipeline_stage_ci = {};
649 pipeline_stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
650 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
651 pipeline_stage_ci.module = shader_module;
652 pipeline_stage_ci.pName = "main";
653
654 VkComputePipelineCreateInfo pipeline_ci = {};
655 pipeline_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
656 pipeline_ci.stage = pipeline_stage_ci;
657 pipeline_ci.layout = as_validation_state.pipeline_layout;
658
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600659 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
660 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700661 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700662 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700663 "Failed to create compute pipeline for acceleration structure build validation.");
664 }
665 }
666
667 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600668 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700669 }
670
671 if (result == VK_SUCCESS) {
672 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700673 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600674 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700675 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600676 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700677 }
678}
679
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600680void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600681 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700682 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
683 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
684 }
685 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
686 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
687 }
688 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
689 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
690 }
691 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600692 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700693 }
694}
695
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600696struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700697 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
698 VkPipeline pipeline = VK_NULL_HANDLE;
699 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
700 std::vector<VkDescriptorSet> descriptor_sets;
701 std::vector<std::vector<uint32_t>> dynamic_offsets;
702 uint32_t push_descriptor_set_index = 0;
703 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
704 std::vector<uint8_t> push_constants_data;
705 PushConstantRangesId push_constants_ranges;
706
707 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
708 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600709 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700710
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600711 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700712 if (last_bound.pipeline_state) {
713 pipeline = last_bound.pipeline_state->pipeline;
714 pipeline_layout = last_bound.pipeline_layout;
715 descriptor_sets.reserve(last_bound.per_set.size());
716 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
717 const auto *bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
718
719 descriptor_sets.push_back(bound_descriptor_set->GetSet());
720 if (bound_descriptor_set->IsPushDescriptor()) {
721 push_descriptor_set_index = static_cast<uint32_t>(i);
722 }
723 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
724 }
725
726 if (last_bound.push_descriptor_set) {
727 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
728 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500729 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700730 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500731 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700732 }
733 }
734 }
735
736 void Restore(VkCommandBuffer command_buffer) const {
737 if (pipeline != VK_NULL_HANDLE) {
738 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
739 if (!descriptor_sets.empty()) {
740 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
741 VkDescriptorSet descriptor_set = descriptor_sets[i];
742 if (descriptor_set != VK_NULL_HANDLE) {
743 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
744 static_cast<uint32_t>(i), 1, &descriptor_set,
745 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
746 }
747 }
748 }
749 if (!push_descriptor_set_writes.empty()) {
750 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
751 static_cast<uint32_t>(push_descriptor_set_writes.size()),
752 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
753 }
754 for (const auto &push_constant_range : *push_constants_ranges) {
755 if (push_constant_range.size == 0) continue;
756 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
757 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
758 }
759 }
760 }
761};
762
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600763void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
764 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
765 VkDeviceSize instanceOffset, VkBool32 update,
766 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
767 VkBuffer scratch, VkDeviceSize scratchOffset) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700768 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
769 return;
770 }
771
Tony-LunarG99b880b2019-09-26 11:19:52 -0600772 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700773 if (!as_validation_state.initialized) {
774 return;
775 }
776
777 // Empty acceleration structure is valid according to the spec.
778 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
779 return;
780 }
781
782 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
783 assert(cb_state != nullptr);
784
785 std::vector<uint64_t> current_valid_handles;
786 for (const auto &as_state_kv : accelerationStructureMap) {
787 const ACCELERATION_STRUCTURE_STATE &as_state = *as_state_kv.second;
Jeff Bolz95176d02020-04-01 00:36:16 -0500788 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700789 current_valid_handles.push_back(as_state.opaque_handle);
790 }
791 }
792
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600793 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700794 as_validation_buffer_info.acceleration_structure = dst;
795
796 const VkDeviceSize validation_buffer_size =
797 // One uint for number of instances to validate
798 4 +
799 // Two uint for the replacement acceleration structure handle
800 8 +
801 // One uint for number of invalid handles found
802 4 +
803 // Two uint for the first invalid handle found
804 8 +
805 // One uint for the number of current valid handles
806 4 +
807 // Two uint for each current valid handle
808 (8 * current_valid_handles.size());
809
810 VkBufferCreateInfo validation_buffer_create_info = {};
811 validation_buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
812 validation_buffer_create_info.size = validation_buffer_size;
813 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
814
815 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
816 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
817
Tony-LunarG99b880b2019-09-26 11:19:52 -0600818 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
819 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700820 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
821 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700822 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600823 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700824 return;
825 }
826
827 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700828 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
829 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700830 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700831 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600832 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700833 return;
834 }
835
836 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
837 mapped_validation_buffer->replacement_handle_bits_0 =
838 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
839 mapped_validation_buffer->replacement_handle_bits_1 =
840 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
841 mapped_validation_buffer->invalid_handle_found = 0;
842 mapped_validation_buffer->invalid_handle_bits_0 = 0;
843 mapped_validation_buffer->invalid_handle_bits_1 = 0;
844 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
845
846 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
847 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
848 const uint64_t current_valid_handle = current_valid_handles[i];
849
850 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
851 ++mapped_valid_handles;
852 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
853 ++mapped_valid_handles;
854 }
855
Tony-LunarG99b880b2019-09-26 11:19:52 -0600856 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700857
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700858 static constexpr const VkDeviceSize k_instance_size = 64;
859 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700860
Tony-LunarG1dce2392019-10-23 16:49:29 -0600861 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
862 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700863 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700864 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600865 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700866 return;
867 }
868
869 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
870 descriptor_buffer_infos[0].buffer = instanceData;
871 descriptor_buffer_infos[0].offset = instanceOffset;
872 descriptor_buffer_infos[0].range = instance_buffer_size;
873 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
874 descriptor_buffer_infos[1].offset = 0;
875 descriptor_buffer_infos[1].range = validation_buffer_size;
876
877 VkWriteDescriptorSet descriptor_set_writes[2] = {};
878 descriptor_set_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
879 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
880 descriptor_set_writes[0].dstBinding = 0;
881 descriptor_set_writes[0].descriptorCount = 1;
882 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
883 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
884 descriptor_set_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
885 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
886 descriptor_set_writes[1].dstBinding = 1;
887 descriptor_set_writes[1].descriptorCount = 1;
888 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
889 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
890
891 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
892
893 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
894 VkMemoryBarrier memory_barrier = {};
895 memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
896 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
897 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
898 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
899 &memory_barrier, 0, nullptr, 0, nullptr);
900
901 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600902 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700903 restorable_state.Create(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
904
905 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
906 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
907 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
908 &as_validation_buffer_info.descriptor_set, 0, nullptr);
909 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
910
911 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
912 // have been replaced by the validation compute shader before any builds take place.
913 VkBufferMemoryBarrier instance_buffer_barrier = {};
914 instance_buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
915 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
916 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
917 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
918 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
919 instance_buffer_barrier.buffer = instanceData;
920 instance_buffer_barrier.offset = instanceOffset;
921 instance_buffer_barrier.size = instance_buffer_size;
922 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
923 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
924 nullptr);
925
926 // Restore the previous compute pipeline state.
927 restorable_state.Restore(commandBuffer);
928
929 as_validation_state.validation_buffers[commandBuffer].push_back(std::move(as_validation_buffer_info));
930}
931
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600932void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700933 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
934 return;
935 }
936
Tony-LunarG99b880b2019-09-26 11:19:52 -0600937 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700938 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[cb_node->commandBuffer];
939 for (const auto &as_validation_buffer_info : as_validation_buffer_infos) {
940 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
941
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700942 VkResult result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
943 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700944 if (result == VK_SUCCESS) {
945 if (mapped_validation_buffer->invalid_handle_found > 0) {
946 uint64_t invalid_handle = 0;
947 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
948 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
949
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700950 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
951 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
952 "handle (%" PRIu64 ")",
953 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700954 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600955 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700956 }
957 }
958}
959
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600960void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
961 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
962 VkResult result) {
963 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600964 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600965 for (uint32_t i = 0; i < bindInfoCount; i++) {
966 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
sourav parmarcd5fb182020-07-17 12:58:44 -0700967 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600968 if (as_state) {
969 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
970 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600971 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600972}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700973
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600974// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
975void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
976 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
977 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600978 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600979 return;
980 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600981
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600982 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
983
Tony-LunarG99b880b2019-09-26 11:19:52 -0600984 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600985 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600986 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600987 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
988 << "Validation is not modifying the pipeline layout. "
989 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700990 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600991 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700992 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -0600993 }
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700994}
995
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600996void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
997 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
998 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600999 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
1000
Karl Schultz7b024b42018-08-30 16:18:18 -06001001 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001002 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001003 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -06001004 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001005}
1006
Karl Schultz7b024b42018-08-30 16:18:18 -06001007// Free the device memory and descriptor set associated with a command buffer.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001008void GpuAssisted::ResetCommandBuffer(VkCommandBuffer commandBuffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001009 if (aborted) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001010 return;
1011 }
Tony-LunarG1dce2392019-10-23 16:49:29 -06001012 auto gpuav_buffer_list = GetBufferInfo(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001013 for (auto buffer_info : gpuav_buffer_list) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001014 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001015 if (buffer_info.di_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001016 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001017 }
1018 if (buffer_info.bda_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001019 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -06001020 }
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001021 if (buffer_info.desc_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001022 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001023 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001024 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001025 command_buffer_map.erase(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -07001026
Tony-LunarG99b880b2019-09-26 11:19:52 -06001027 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -07001028 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[commandBuffer];
1029 for (auto &as_validation_buffer_info : as_validation_buffer_infos) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001030 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -07001031 as_validation_buffer_info.validation_buffer_allocation);
1032
1033 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001034 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool,
1035 as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001036 }
1037 }
1038 as_validation_info.validation_buffers.erase(commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001039}
Karl Schultz7b024b42018-08-30 16:18:18 -06001040// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001041bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1042 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1043 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1044 uint32_t bufferMemoryBarrierCount,
1045 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001046 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001047 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001048 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001049 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1050 "GPU_Assisted validation waits on queue completion. "
1051 "This wait could block the host's signaling of this event, resulting in deadlock.");
1052 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001053 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001054}
1055
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001056bool GpuAssisted::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1057 const VkDependencyInfoKHR *pDependencyInfos) const {
1058 VkPipelineStageFlags2KHR srcStageMask = 0;
1059
1060 for (uint32_t i = 0; i < eventCount; i++) {
1061 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
1062 srcStageMask = stage_masks.src;
1063 }
1064
1065 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
1066 ReportSetupProblem(commandBuffer,
1067 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1068 "GPU_Assisted validation waits on queue completion. "
1069 "This wait could block the host's signaling of this event, resulting in deadlock.");
1070 }
1071 return false;
1072}
1073
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001074void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1075 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1076 // 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 -06001077 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001078 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1079 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1080 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001081 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1082 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001083 }
1084 }
1085}
1086
1087void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1088 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1089 // 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 -06001090 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001091 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1092 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1093 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001094 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1095 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001096 }
1097 }
1098}
1099
1100void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1101 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1102 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1103 void *cgpl_state_data) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001104 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001105 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001106 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1107 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001108 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1109 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001110}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001111
1112void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1113 const VkComputePipelineCreateInfo *pCreateInfos,
1114 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1115 void *ccpl_state_data) {
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001116 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001117 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001118 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1119 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001120 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1121 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Jason Macnak67407e72019-07-11 11:05:09 -07001122}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001123
1124void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1125 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1126 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1127 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001128 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001129 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001130 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1131 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001132 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1133 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001134}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001135
sourav parmarcd5fb182020-07-17 12:58:44 -07001136void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1137 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001138 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1139 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1140 void *crtpl_state_data) {
1141 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1142 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001143 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1144 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001145 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1146 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
1147}
Karl Schultz7b024b42018-08-30 16:18:18 -06001148
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001149void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1150 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1151 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1152 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001153 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1154 pPipelines, result, cgpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001155 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
1156 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001157 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001158}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001159
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001160void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1161 const VkComputePipelineCreateInfo *pCreateInfos,
1162 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1163 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001164 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1165 result, ccpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001166 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
1167 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001168 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001169}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001170
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001171void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1172 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1173 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1174 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001175 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001176 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1177 pPipelines, result, crtpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001178 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001179 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001180}
1181
sourav parmarcd5fb182020-07-17 12:58:44 -07001182void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1183 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001184 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1185 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1186 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001187 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
sourav parmarcd5fb182020-07-17 12:58:44 -07001188 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
1189 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001190 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001191 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001192}
1193
1194// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001195void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001196 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001197 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001198 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001199 } else {
1200 ++it;
1201 }
1202 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001203 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001204}
1205
1206// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001207bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1208 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001209 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001210 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1211
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001212 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001213 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1214 switch (level) {
1215 case SPV_MSG_FATAL:
1216 case SPV_MSG_INTERNAL_ERROR:
1217 case SPV_MSG_ERROR:
1218 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1219 position.index, message);
1220 break;
1221 default:
1222 break;
1223 }
1224 };
1225
Karl Schultz7b024b42018-08-30 16:18:18 -06001226 // Load original shader SPIR-V
1227 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1228 new_pgm.clear();
1229 new_pgm.reserve(num_words);
1230 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1231
1232 // Call the optimizer to instrument the shader.
1233 // 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 -07001234 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001235 using namespace spvtools;
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06001236 spv_target_env target_env = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001237 spvtools::ValidatorOptions val_options;
1238 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1239 spvtools::OptimizerOptions opt_options;
1240 opt_options.set_run_validator(true);
1241 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001242 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001243 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001244 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001245 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Karl Schultz7b024b42018-08-30 16:18:18 -06001246 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG5c38b182020-06-10 16:15:32 -06001247 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64 &&
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001248 enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001249 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001250 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001251 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001252 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001253 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001254 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001255 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001256 return pass;
1257}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001258// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001259void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1260 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1261 void *csm_state_data) {
1262 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1263 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001264 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001265 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1266 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001267 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001268}
1269
Karl Schultz7b024b42018-08-30 16:18:18 -06001270// Generate the part of the message describing the violation.
Tony-LunarG7de10e82020-11-24 11:31:55 -07001271static void GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg, CMD_TYPE cmd_type) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001272 using namespace spvtools;
1273 std::ostringstream strm;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001274 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001275 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001276 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1277 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001278 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001279 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001280 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001281 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001282 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001283 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001284 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001285 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001286 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1287 vuid_msg = "UNASSIGNED-Device address out of bounds";
1288 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001289 case kInstErrorBuffOOBUniform:
1290 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001291 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1292 if (size == 0) {
1293 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1294 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1295 } else {
1296 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1297 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001298 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
1299 const GpuVuid vuid = GetGpuVuid(cmd_type);
1300 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1301 vuid_msg = vuid.uniform_access_oob;
1302 else
1303 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001304 }
1305 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001306 case kInstErrorBuffOOBUniformTexel:
1307 case kInstErrorBuffOOBStorageTexel: {
1308 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1309 if (size == 0) {
1310 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1311 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1312 }
1313 else {
1314 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1315 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1316 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
1317 const GpuVuid vuid = GetGpuVuid(cmd_type);
1318 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1319 vuid_msg = vuid.uniform_access_oob;
1320 else
1321 vuid_msg = vuid.storage_access_oob;
1322 } break;
1323 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001324 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001325 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001326 vuid_msg = "UNASSIGNED-Internal Error";
1327 assert(false);
1328 } break;
1329 }
1330 msg = strm.str();
1331}
1332
Karl Schultz7b024b42018-08-30 16:18:18 -06001333// Pull together all the information from the debug record to build the error message strings,
1334// and then assemble them into a single message string.
1335// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1336// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1337// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1338// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1339//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001340void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001341 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001342 using namespace spvtools;
1343 const uint32_t total_words = debug_output_buffer[0];
1344 // A zero here means that the shader instrumentation didn't write anything.
1345 // If you have nothing to say, don't say it here.
1346 if (0 == total_words) {
1347 return;
1348 }
1349 // The first word in the debug output buffer is the number of words that would have
1350 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1351 // The number of words actually written by the shaders is determined by the size of the buffer
1352 // we provide via the descriptor. So, we process only the number of words that can fit in the
1353 // buffer.
1354 // Each "report" written by the shader instrumentation is considered a "record". This function
1355 // is hard-coded to process only one record because it expects the buffer to be large enough to
1356 // hold only one record. If there is a desire to process more than one record, this function needs
1357 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001358 std::string validation_message;
1359 std::string stage_message;
1360 std::string common_message;
1361 std::string filename_message;
1362 std::string source_message;
1363 std::string vuid_msg;
1364 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1365 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1366 std::vector<unsigned int> pgm;
1367 // The first record starts at this offset after the total_words.
1368 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1369 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1370 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001371 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1372 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001373 shader_module_handle = it->second.shader_module;
1374 pipeline_handle = it->second.pipeline;
1375 pgm = it->second.pgm;
1376 }
Tony-LunarG7de10e82020-11-24 11:31:55 -07001377 GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info.cmd_type);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001378 UtilGenerateStageMessage(debug_record, stage_message);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001379 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle, buffer_info.pipeline_bind_point,
Tony-LunarGb5fae462020-03-05 12:43:25 -07001380 operation_index, common_message);
1381 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001382 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1383 filename_message.c_str(), source_message.c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001384 // The debug record at word kInstCommonOutSize is the number of words in the record
1385 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001386 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001387 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1388}
1389
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001390void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1391 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1392 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001393 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001394 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001395 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001396 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1397 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1398 }
1399 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1400 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001401 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001402 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001403 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001404 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1405 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1406 }
1407 } else {
1408 pData[index] = 1;
1409 }
1410}
1411
Tony-LunarG81efe392019-03-07 15:43:27 -07001412// 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 -06001413void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001414 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001415 uint32_t *data;
Tony-LunarG81efe392019-03-07 15:43:27 -07001416 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001417 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001418 VkResult result =
1419 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001420 if (result == VK_SUCCESS) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001421 for (auto update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001422 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001423 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001424 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001425 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001426 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001427 }
1428 }
1429 }
1430}
1431
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001432void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
1433 auto cb_node = GetCBState(command_buffer);
1434 UpdateInstrumentationBuffer(cb_node);
1435 for (auto secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
1436 UpdateInstrumentationBuffer(secondary_cmd_buffer);
1437 }
1438}
1439
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001440void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001441 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1442 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1443 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001444 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001445 }
1446 }
1447}
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001448void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1449 VkFence fence) {
1450 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1451 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1452 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1453 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1454 }
1455 }
1456}
1457
1458bool GpuAssisted::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
1459 bool buffers_present = false;
1460 auto cb_node = GetCBState(command_buffer);
1461
1462 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) {
1463 buffers_present = true;
1464 }
1465 for (auto secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
1466 if (GetBufferInfo(secondary_cmd_buffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) {
1467 buffers_present = true;
1468 }
1469 }
1470 return buffers_present;
1471}
1472
1473void GpuAssisted::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
1474 auto cb_node = GetCBState(command_buffer);
1475
1476 UtilProcessInstrumentationBuffer(queue, cb_node, this);
1477 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
1478 for (auto secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
1479 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
1480 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
1481 }
1482}
Tony-LunarG81efe392019-03-07 15:43:27 -07001483
Karl Schultz58674242019-01-22 15:35:02 -07001484// Issue a memory barrier to make GPU-written data available to host.
1485// Wait for the queue to complete execution.
1486// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001487void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1488 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001489 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001490
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001491 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001492 bool buffers_present = false;
1493 // Don't QueueWaitIdle if there's nothing to process
1494 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1495 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1496 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001497 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001498 }
1499 }
1500 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001501
Tony-LunarGb5fae462020-03-05 12:43:25 -07001502 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001503
Tony-LunarG152a88b2019-03-20 15:42:24 -06001504 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001505
Karl Schultz7b024b42018-08-30 16:18:18 -06001506 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1507 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1508 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001509 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
1510 }
1511 }
1512}
1513
1514void GpuAssisted::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1515 VkFence fence, VkResult result) {
1516 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
1517
1518 if (aborted || (result != VK_SUCCESS)) return;
1519 bool buffers_present = false;
1520 // Don't QueueWaitIdle if there's nothing to process
1521 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1522 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1523 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1524 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
1525 }
1526 }
1527 if (!buffers_present) return;
1528
1529 UtilSubmitBarrier(queue, this);
1530
1531 DispatchQueueWaitIdle(queue);
1532
1533 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1534 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1535 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1536 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001537 }
1538 }
1539}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001540
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001541void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1542 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001543 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001544}
1545
1546void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1547 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001548 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001549}
1550
1551void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1552 uint32_t stride) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001553 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001554}
1555
1556void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1557 uint32_t count, uint32_t stride) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001558 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001559}
1560
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001561void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1562 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1563 uint32_t stride) {
1564 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1565 maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001566 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001567}
1568
1569void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1570 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1571 uint32_t stride) {
1572 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1573 maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001574 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001575}
1576
Tony-LunarG54176fb2020-12-02 10:47:22 -07001577void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1578 uint32_t firstInstance, VkBuffer counterBuffer,
1579 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1580 uint32_t vertexStride) {
1581 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1582 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001583 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001584}
1585
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001586void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1587 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1588 uint32_t maxDrawCount, uint32_t stride) {
1589 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1590 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001591 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001592}
1593
1594void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1595 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1596 uint32_t maxDrawCount, uint32_t stride) {
1597 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1598 maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001599 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001600}
1601
1602void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1603 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001604 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001605}
1606
1607void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1608 uint32_t drawCount, uint32_t stride) {
1609 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001610 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001611}
1612
1613void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1614 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1615 uint32_t maxDrawCount, uint32_t stride) {
1616 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1617 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001618 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001619}
1620
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001621void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001622 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001623}
1624
1625void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001626 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001627}
1628
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001629void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1630 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1631 uint32_t groupCountZ) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001632 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001633}
1634
Tony-LunarG52c8c602020-09-10 16:29:56 -06001635void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1636 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1637 uint32_t groupCountZ) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001638 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001639}
1640
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001641void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1642 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1643 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1644 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1645 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1646 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1647 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001648 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001649}
1650
1651void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1652 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1653 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1654 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1655 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1656 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1657 uint32_t width, uint32_t height, uint32_t depth) {
1658 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1659 cb_state->hasTraceRaysCmd = true;
1660}
1661
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001662void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001663 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1664 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1665 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1666 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001667 uint32_t height, uint32_t depth) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001668 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001669}
1670
1671void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001672 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1673 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1674 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1675 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001676 uint32_t height, uint32_t depth) {
1677 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1678 cb_state->hasTraceRaysCmd = true;
1679}
1680
1681void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001682 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1683 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1684 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1685 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001686 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001687 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001688}
1689
1690void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001691 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1692 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1693 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1694 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001695 VkDeviceAddress indirectDeviceAddress) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001696 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1697 cb_state->hasTraceRaysCmd = true;
1698}
1699
Tony-LunarG7de10e82020-11-24 11:31:55 -07001700void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
1701 CMD_TYPE cmd_type) {
Jason Macnak67407e72019-07-11 11:05:09 -07001702 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1703 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001704 return;
1705 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001706 VkResult result;
1707
Tony-LunarG99b880b2019-09-26 11:19:52 -06001708 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001709
1710 std::vector<VkDescriptorSet> desc_sets;
1711 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001712 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001713 assert(result == VK_SUCCESS);
1714 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001715 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001716 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001717 return;
1718 }
1719
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001720 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001721 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001722
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001723 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001724 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001725 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001726 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001727 return;
1728 }
1729
Tony-LunarG81efe392019-03-07 15:43:27 -07001730 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001731 GpuAssistedDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001732 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
1733 buffer_info.size = output_buffer_size;
1734 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1735 VmaAllocationCreateInfo alloc_info = {};
1736 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
1737 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001738 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001739 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001740 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001741 return;
1742 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001743
Tony-LunarG81efe392019-03-07 15:43:27 -07001744 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001745 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001746 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001747 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001748 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001749 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001750 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001751
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001752 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001753 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1754 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1755 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001756 uint32_t desc_count = 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06001757 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1758 auto const &state = cb_node->lastBound[lv_bind_point];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001759 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001760
Tony-LunarGe29097a2020-12-03 10:59:19 -07001761 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001762 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1763 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001764 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001765 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1766 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001767 for (auto s : state.per_set) {
1768 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001769 if (desc && (desc->GetBindingCount() > 0)) {
1770 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001771 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1772 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001773 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1774 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07001775 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
1776 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001777 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001778 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1779 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1780 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001781 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001782 descriptor_count += desc->GetVariableDescriptorCount();
1783 } else {
1784 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1785 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07001786 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1787 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
1788 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07001789 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1790 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1791 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001792 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001793 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001794 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001795 }
1796 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001797
Tony-LunarGe29097a2020-12-03 10:59:19 -07001798 if (descriptor_indexing || has_buffers) {
1799 // Note that the size of the input buffer is dependent on the maximum binding number, which
1800 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1801 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1802 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1803 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1804 uint32_t words_needed;
1805 if (descriptor_indexing) {
1806 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
1807 } else {
1808 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
1809 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001810 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1811 buffer_info.size = words_needed * 4;
1812 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
1813 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07001814 if (result != VK_SUCCESS) {
1815 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
1816 aborted = true;
1817 return;
1818 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001819
Tony-LunarGe29097a2020-12-03 10:59:19 -07001820 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1821 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1822 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001823 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
1824 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001825
Tony-LunarGe29097a2020-12-03 10:59:19 -07001826 // Descriptor indexing needs the number of descriptors at each binding.
1827 if (descriptor_indexing) {
1828 // Pointer to a sets array that points into the sizes array
1829 uint32_t *sets_to_sizes = data_ptr + 1;
1830 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1831 uint32_t *sizes = sets_to_sizes + number_of_sets;
1832 // Pointer to another sets array that points into the bindings array that points into the written array
1833 uint32_t *sets_to_bindings = sizes + binding_count;
1834 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1835 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1836 // Index of the next entry in the written array to be updated
1837 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
1838 uint32_t bind_counter = number_of_sets + 1;
1839 // Index of the start of the sets_to_bindings array
1840 data_ptr[0] = number_of_sets + binding_count + 1;
1841
1842 for (auto s : state.per_set) {
1843 auto desc = s.bound_descriptor_set;
1844 if (desc && (desc->GetBindingCount() > 0)) {
1845 auto layout = desc->GetLayout();
1846 auto bindings = layout->GetSortedBindingSet();
1847 // For each set, fill in index of its bindings sizes in the sizes array
1848 *sets_to_sizes++ = bind_counter;
1849 // For each set, fill in the index of its bindings in the bindings_to_written array
1850 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
1851 for (auto binding : bindings) {
1852 // For each binding, fill in its size in the sizes array
1853 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1854 // uniform blocks
1855 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1856 sizes[binding] = 1;
1857 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
1858 sizes[binding] = desc->GetVariableDescriptorCount();
1859 } else {
1860 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
1861 }
1862 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1863 bindings_to_written[binding] = written_index;
1864
1865 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1866 // uniform blocks
1867 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1868 data_ptr[written_index++] = UINT_MAX;
1869 continue;
1870 }
1871
1872 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1873 // For each array element in the binding, update the written array with whether it has been written
1874 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1875 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
1876 if (descriptor->updated) {
1877 SetDescriptorInitialized(data_ptr, written_index, descriptor);
1878 } else if (desc->IsUpdateAfterBind(binding)) {
1879 // If it hasn't been written now and it's update after bind, put it in a list to check at
1880 // QueueSubmit
1881 di_input_block.update_at_submit[written_index] = descriptor;
1882 }
1883 written_index++;
1884 }
1885 }
1886 auto last = desc->GetLayout()->GetMaxBinding();
1887 bindings_to_written += last + 1;
1888 bind_counter += last + 1;
1889 sizes += last + 1;
1890 } else {
1891 *sets_to_sizes++ = 0;
1892 *sets_to_bindings++ = 0;
1893 }
1894 }
1895 } else {
1896 // If no descriptor indexing, we don't need number of descriptors at each binding, so
1897 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
1898
1899 // Pointer to sets array that points into the bindings array that points into the written array
1900 uint32_t *sets_to_bindings = data_ptr + 1;
1901 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1902 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1903 // Index of the next entry in the written array to be updated
1904 uint32_t written_index = 1 + number_of_sets + binding_count;
1905 uint32_t bind_counter = number_of_sets + 1;
1906 data_ptr[0] = 1;
1907
1908 for (auto s : state.per_set) {
1909 auto desc = s.bound_descriptor_set;
1910 if (desc && (desc->GetBindingCount() > 0)) {
1911 auto layout = desc->GetLayout();
1912 auto bindings = layout->GetSortedBindingSet();
1913 *sets_to_bindings++ = bind_counter;
1914 for (auto binding : bindings) {
1915 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1916 bindings_to_written[binding] = written_index;
1917
1918 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1919 // uniform blocks
1920 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1921 data_ptr[written_index++] = UINT_MAX;
1922 continue;
1923 }
1924
1925 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1926
1927 // For each array element in the binding, update the written array with whether it has been written
1928 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1929 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
1930 if (descriptor->updated) {
1931 SetDescriptorInitialized(data_ptr, written_index, descriptor);
1932 } else if (desc->IsUpdateAfterBind(binding)) {
1933 // If it hasn't been written now and it's update after bind, put it in a list to check at
1934 // QueueSubmit
1935 di_input_block.update_at_submit[written_index] = descriptor;
1936 }
1937 written_index++;
1938 }
1939 }
1940 auto last = desc->GetLayout()->GetMaxBinding();
1941 bindings_to_written += last + 1;
1942 bind_counter += last + 1;
1943 } else {
1944 *sets_to_bindings++ = 0;
1945 }
1946 }
1947 }
1948 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
1949
1950 di_input_desc_buffer_info.range = (words_needed * 4);
1951 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1952 di_input_desc_buffer_info.offset = 0;
1953
1954 desc_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1955 desc_writes[1].dstBinding = 1;
1956 desc_writes[1].descriptorCount = 1;
1957 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1958 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
1959 desc_writes[1].dstSet = desc_sets[0];
1960
1961 desc_count = 2;
1962 }
Tony-LunarG0e564722019-03-19 16:09:14 -06001963 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001964
Tony-LunarGc111b242020-06-30 14:43:45 -06001965 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 -06001966 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001967 // Example BDA input buffer assuming 2 buffers using BDA:
1968 // Word 0 | Index of start of buffer sizes (in this case 5)
1969 // Word 1 | 0x0000000000000000
1970 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1971 // Word 3 | Device Address of second buffer
1972 // Word 4 | 0xffffffffffffffff
1973 // Word 5 | 0 (size of pretend buffer at word 1)
1974 // Word 6 | Size in bytes of first buffer
1975 // Word 7 | Size in bytes of second buffer
1976 // Word 8 | 0 (size of pretend buffer in word 4)
1977
Tony-LunarG99b880b2019-09-26 11:19:52 -06001978 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001979 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001980 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1981 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06001982 result =
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001983 vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001984 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001985 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001986 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001987 return;
1988 }
1989 uint64_t *bda_data;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001990 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001991 uint32_t address_index = 1;
1992 uint32_t size_index = 3 + num_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001993 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001994 bda_data[0] = size_index; // Start of buffer sizes
1995 bda_data[address_index++] = 0; // NULL address
1996 bda_data[size_index++] = 0;
1997
Tony-LunarG99b880b2019-09-26 11:19:52 -06001998 for (auto const &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001999 bda_data[address_index++] = value.first;
2000 bda_data[size_index++] = value.second;
2001 }
2002 bda_data[address_index] = UINTPTR_MAX;
2003 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06002004 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002005
2006 bda_input_desc_buffer_info.range = (words_needed * 8);
2007 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2008 bda_input_desc_buffer_info.offset = 0;
2009
2010 desc_writes[desc_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2011 desc_writes[desc_count].dstBinding = 2;
2012 desc_writes[desc_count].descriptorCount = 1;
2013 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2014 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2015 desc_writes[desc_count].dstSet = desc_sets[0];
2016 desc_count++;
2017 }
2018
Tony-LunarGb2501d22019-01-28 09:59:13 -07002019 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002020 output_desc_buffer_info.buffer = output_block.buffer;
2021 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002022
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002023 desc_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2024 desc_writes[0].descriptorCount = 1;
2025 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2026 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2027 desc_writes[0].dstSet = desc_sets[0];
2028 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002029
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002030 const auto *pipeline_state = state.pipeline_state;
2031 if (pipeline_state) {
2032 if ((pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002033 !pipeline_state->pipeline_layout->destroyed) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002034 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002035 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002036 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002037 if (pipeline_state->pipeline_layout->destroyed) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002038 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2039 aborted = true;
2040 } else {
2041 // Record buffer and memory info in CB state tracking
2042 GetBufferInfo(cmd_buffer)
Tony-LunarG7de10e82020-11-24 11:31:55 -07002043 .emplace_back(output_block, di_input_block, bda_input_block, desc_sets[0], desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002044 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002045 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002046 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002047 aborted = true;
2048 }
2049 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002050 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2051 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2052 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002053 return;
2054 }
2055}