blob: 787e246786943ed5d62c51cfa32b3ee42842fa62 [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>
Tony-LunarGa3ec16c2021-04-06 12:19:57 -060022#include <cmath>
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070023#include "gpu_validation.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060024#include "spirv-tools/optimizer.hpp"
25#include "spirv-tools/instrument.hpp"
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060026#include "layer_chassis_dispatch.h"
Tony-LunarG7de10e82020-11-24 11:31:55 -070027#include "gpu_vuids.h"
Jeremy Gebbena3705f42021-01-19 16:47:43 -070028#include "sync_utils.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060029
Jason Macnak67407e72019-07-11 11:05:09 -070030static const VkShaderStageFlags kShaderStageAllRayTracing =
31 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
32 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
33
Jason Macnak83cfd582019-07-31 10:14:24 -070034// Keep in sync with the GLSL shader below.
35struct GpuAccelerationStructureBuildValidationBuffer {
36 uint32_t instances_to_validate;
37 uint32_t replacement_handle_bits_0;
38 uint32_t replacement_handle_bits_1;
39 uint32_t invalid_handle_found;
40 uint32_t invalid_handle_bits_0;
41 uint32_t invalid_handle_bits_1;
42 uint32_t valid_handles_count;
43};
44
45// This is the GLSL source for the compute shader that is used during ray tracing acceleration structure
46// building validation which inspects instance buffers for top level acceleration structure builds and
47// reports and replaces invalid bottom level acceleration structure handles with good bottom level
48// acceleration structure handle so that applications can continue without undefined behavior long enough
49// to report errors.
50//
51// #version 450
52// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
53// struct VkGeometryInstanceNV {
54// uint unused[14];
55// uint handle_bits_0;
56// uint handle_bits_1;
57// };
58// layout(set=0, binding=0, std430) buffer InstanceBuffer {
59// VkGeometryInstanceNV instances[];
60// };
61// layout(set=0, binding=1, std430) buffer ValidationBuffer {
62// uint instances_to_validate;
63// uint replacement_handle_bits_0;
64// uint replacement_handle_bits_1;
65// uint invalid_handle_found;
66// uint invalid_handle_bits_0;
67// uint invalid_handle_bits_1;
68// uint valid_handles_count;
69// uint valid_handles[];
70// };
71// void main() {
72// for (uint instance_index = 0; instance_index < instances_to_validate; instance_index++) {
73// uint instance_handle_bits_0 = instances[instance_index].handle_bits_0;
74// uint instance_handle_bits_1 = instances[instance_index].handle_bits_1;
75// bool valid = false;
76// for (uint valid_handle_index = 0; valid_handle_index < valid_handles_count; valid_handle_index++) {
77// if (instance_handle_bits_0 == valid_handles[2*valid_handle_index+0] &&
78// instance_handle_bits_1 == valid_handles[2*valid_handle_index+1]) {
79// valid = true;
80// break;
81// }
82// }
83// if (!valid) {
84// invalid_handle_found += 1;
85// invalid_handle_bits_0 = instance_handle_bits_0;
86// invalid_handle_bits_1 = instance_handle_bits_1;
87// instances[instance_index].handle_bits_0 = replacement_handle_bits_0;
88// instances[instance_index].handle_bits_1 = replacement_handle_bits_1;
89// }
90// }
91// }
92//
93// To regenerate the spirv below:
94// 1. Save the above GLSL source to a file called validation_shader.comp.
95// 2. Run in terminal
96//
97// glslangValidator.exe -x -V validation_shader.comp -o validation_shader.comp.spv
98//
99// 4. Copy-paste the contents of validation_shader.comp.spv here (clang-format will fix up the alignment).
100static const uint32_t kComputeShaderSpirv[] = {
101 0x07230203, 0x00010000, 0x00080007, 0x0000006d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
102 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005, 0x00000004, 0x6e69616d,
103 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2,
104 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x00000008, 0x74736e69, 0x65636e61, 0x646e695f, 0x00007865,
105 0x00070005, 0x00000011, 0x696c6156, 0x69746164, 0x75426e6f, 0x72656666, 0x00000000, 0x00090006, 0x00000011, 0x00000000,
106 0x74736e69, 0x65636e61, 0x6f745f73, 0x6c61765f, 0x74616469, 0x00000065, 0x000a0006, 0x00000011, 0x00000001, 0x6c706572,
107 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x000a0006, 0x00000011, 0x00000002, 0x6c706572,
108 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00090006, 0x00000011, 0x00000003, 0x61766e69,
109 0x5f64696c, 0x646e6168, 0x665f656c, 0x646e756f, 0x00000000, 0x00090006, 0x00000011, 0x00000004, 0x61766e69, 0x5f64696c,
110 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00090006, 0x00000011, 0x00000005, 0x61766e69, 0x5f64696c, 0x646e6168,
111 0x625f656c, 0x5f737469, 0x00000031, 0x00080006, 0x00000011, 0x00000006, 0x696c6176, 0x61685f64, 0x656c646e, 0x6f635f73,
112 0x00746e75, 0x00070006, 0x00000011, 0x00000007, 0x696c6176, 0x61685f64, 0x656c646e, 0x00000073, 0x00030005, 0x00000013,
113 0x00000000, 0x00080005, 0x0000001b, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000305f, 0x00080005,
114 0x0000001e, 0x65476b56, 0x74656d6f, 0x6e497972, 0x6e617473, 0x564e6563, 0x00000000, 0x00050006, 0x0000001e, 0x00000000,
115 0x73756e75, 0x00006465, 0x00070006, 0x0000001e, 0x00000001, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00070006,
116 0x0000001e, 0x00000002, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00060005, 0x00000020, 0x74736e49, 0x65636e61,
117 0x66667542, 0x00007265, 0x00060006, 0x00000020, 0x00000000, 0x74736e69, 0x65636e61, 0x00000073, 0x00030005, 0x00000022,
118 0x00000000, 0x00080005, 0x00000027, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000315f, 0x00040005,
119 0x0000002d, 0x696c6176, 0x00000064, 0x00070005, 0x0000002f, 0x696c6176, 0x61685f64, 0x656c646e, 0x646e695f, 0x00007865,
120 0x00040047, 0x00000010, 0x00000006, 0x00000004, 0x00050048, 0x00000011, 0x00000000, 0x00000023, 0x00000000, 0x00050048,
121 0x00000011, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000011, 0x00000002, 0x00000023, 0x00000008, 0x00050048,
122 0x00000011, 0x00000003, 0x00000023, 0x0000000c, 0x00050048, 0x00000011, 0x00000004, 0x00000023, 0x00000010, 0x00050048,
123 0x00000011, 0x00000005, 0x00000023, 0x00000014, 0x00050048, 0x00000011, 0x00000006, 0x00000023, 0x00000018, 0x00050048,
124 0x00000011, 0x00000007, 0x00000023, 0x0000001c, 0x00030047, 0x00000011, 0x00000003, 0x00040047, 0x00000013, 0x00000022,
125 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000001, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00050048,
126 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000038, 0x00050048,
127 0x0000001e, 0x00000002, 0x00000023, 0x0000003c, 0x00040047, 0x0000001f, 0x00000006, 0x00000040, 0x00050048, 0x00000020,
128 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000003, 0x00040047, 0x00000022, 0x00000022, 0x00000000,
129 0x00040047, 0x00000022, 0x00000021, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015,
130 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x0004002b, 0x00000006, 0x00000009,
131 0x00000000, 0x0003001d, 0x00000010, 0x00000006, 0x000a001e, 0x00000011, 0x00000006, 0x00000006, 0x00000006, 0x00000006,
132 0x00000006, 0x00000006, 0x00000006, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012,
133 0x00000013, 0x00000002, 0x00040015, 0x00000014, 0x00000020, 0x00000001, 0x0004002b, 0x00000014, 0x00000015, 0x00000000,
134 0x00040020, 0x00000016, 0x00000002, 0x00000006, 0x00020014, 0x00000019, 0x0004002b, 0x00000006, 0x0000001c, 0x0000000e,
135 0x0004001c, 0x0000001d, 0x00000006, 0x0000001c, 0x0005001e, 0x0000001e, 0x0000001d, 0x00000006, 0x00000006, 0x0003001d,
136 0x0000001f, 0x0000001e, 0x0003001e, 0x00000020, 0x0000001f, 0x00040020, 0x00000021, 0x00000002, 0x00000020, 0x0004003b,
137 0x00000021, 0x00000022, 0x00000002, 0x0004002b, 0x00000014, 0x00000024, 0x00000001, 0x0004002b, 0x00000014, 0x00000029,
138 0x00000002, 0x00040020, 0x0000002c, 0x00000007, 0x00000019, 0x0003002a, 0x00000019, 0x0000002e, 0x0004002b, 0x00000014,
139 0x00000036, 0x00000006, 0x0004002b, 0x00000014, 0x0000003b, 0x00000007, 0x0004002b, 0x00000006, 0x0000003c, 0x00000002,
140 0x0004002b, 0x00000006, 0x00000048, 0x00000001, 0x00030029, 0x00000019, 0x00000050, 0x0004002b, 0x00000014, 0x00000058,
141 0x00000003, 0x0004002b, 0x00000014, 0x0000005d, 0x00000004, 0x0004002b, 0x00000014, 0x00000060, 0x00000005, 0x00050036,
142 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007,
143 0x0004003b, 0x00000007, 0x0000001b, 0x00000007, 0x0004003b, 0x00000007, 0x00000027, 0x00000007, 0x0004003b, 0x0000002c,
144 0x0000002d, 0x00000007, 0x0004003b, 0x00000007, 0x0000002f, 0x00000007, 0x0003003e, 0x00000008, 0x00000009, 0x000200f9,
145 0x0000000a, 0x000200f8, 0x0000000a, 0x000400f6, 0x0000000c, 0x0000000d, 0x00000000, 0x000200f9, 0x0000000e, 0x000200f8,
146 0x0000000e, 0x0004003d, 0x00000006, 0x0000000f, 0x00000008, 0x00050041, 0x00000016, 0x00000017, 0x00000013, 0x00000015,
147 0x0004003d, 0x00000006, 0x00000018, 0x00000017, 0x000500b0, 0x00000019, 0x0000001a, 0x0000000f, 0x00000018, 0x000400fa,
148 0x0000001a, 0x0000000b, 0x0000000c, 0x000200f8, 0x0000000b, 0x0004003d, 0x00000006, 0x00000023, 0x00000008, 0x00070041,
149 0x00000016, 0x00000025, 0x00000022, 0x00000015, 0x00000023, 0x00000024, 0x0004003d, 0x00000006, 0x00000026, 0x00000025,
150 0x0003003e, 0x0000001b, 0x00000026, 0x0004003d, 0x00000006, 0x00000028, 0x00000008, 0x00070041, 0x00000016, 0x0000002a,
151 0x00000022, 0x00000015, 0x00000028, 0x00000029, 0x0004003d, 0x00000006, 0x0000002b, 0x0000002a, 0x0003003e, 0x00000027,
152 0x0000002b, 0x0003003e, 0x0000002d, 0x0000002e, 0x0003003e, 0x0000002f, 0x00000009, 0x000200f9, 0x00000030, 0x000200f8,
153 0x00000030, 0x000400f6, 0x00000032, 0x00000033, 0x00000000, 0x000200f9, 0x00000034, 0x000200f8, 0x00000034, 0x0004003d,
154 0x00000006, 0x00000035, 0x0000002f, 0x00050041, 0x00000016, 0x00000037, 0x00000013, 0x00000036, 0x0004003d, 0x00000006,
155 0x00000038, 0x00000037, 0x000500b0, 0x00000019, 0x00000039, 0x00000035, 0x00000038, 0x000400fa, 0x00000039, 0x00000031,
156 0x00000032, 0x000200f8, 0x00000031, 0x0004003d, 0x00000006, 0x0000003a, 0x0000001b, 0x0004003d, 0x00000006, 0x0000003d,
157 0x0000002f, 0x00050084, 0x00000006, 0x0000003e, 0x0000003c, 0x0000003d, 0x00050080, 0x00000006, 0x0000003f, 0x0000003e,
158 0x00000009, 0x00060041, 0x00000016, 0x00000040, 0x00000013, 0x0000003b, 0x0000003f, 0x0004003d, 0x00000006, 0x00000041,
159 0x00000040, 0x000500aa, 0x00000019, 0x00000042, 0x0000003a, 0x00000041, 0x000300f7, 0x00000044, 0x00000000, 0x000400fa,
160 0x00000042, 0x00000043, 0x00000044, 0x000200f8, 0x00000043, 0x0004003d, 0x00000006, 0x00000045, 0x00000027, 0x0004003d,
161 0x00000006, 0x00000046, 0x0000002f, 0x00050084, 0x00000006, 0x00000047, 0x0000003c, 0x00000046, 0x00050080, 0x00000006,
162 0x00000049, 0x00000047, 0x00000048, 0x00060041, 0x00000016, 0x0000004a, 0x00000013, 0x0000003b, 0x00000049, 0x0004003d,
163 0x00000006, 0x0000004b, 0x0000004a, 0x000500aa, 0x00000019, 0x0000004c, 0x00000045, 0x0000004b, 0x000200f9, 0x00000044,
164 0x000200f8, 0x00000044, 0x000700f5, 0x00000019, 0x0000004d, 0x00000042, 0x00000031, 0x0000004c, 0x00000043, 0x000300f7,
165 0x0000004f, 0x00000000, 0x000400fa, 0x0000004d, 0x0000004e, 0x0000004f, 0x000200f8, 0x0000004e, 0x0003003e, 0x0000002d,
166 0x00000050, 0x000200f9, 0x00000032, 0x000200f8, 0x0000004f, 0x000200f9, 0x00000033, 0x000200f8, 0x00000033, 0x0004003d,
167 0x00000006, 0x00000052, 0x0000002f, 0x00050080, 0x00000006, 0x00000053, 0x00000052, 0x00000024, 0x0003003e, 0x0000002f,
168 0x00000053, 0x000200f9, 0x00000030, 0x000200f8, 0x00000032, 0x0004003d, 0x00000019, 0x00000054, 0x0000002d, 0x000400a8,
169 0x00000019, 0x00000055, 0x00000054, 0x000300f7, 0x00000057, 0x00000000, 0x000400fa, 0x00000055, 0x00000056, 0x00000057,
170 0x000200f8, 0x00000056, 0x00050041, 0x00000016, 0x00000059, 0x00000013, 0x00000058, 0x0004003d, 0x00000006, 0x0000005a,
171 0x00000059, 0x00050080, 0x00000006, 0x0000005b, 0x0000005a, 0x00000048, 0x00050041, 0x00000016, 0x0000005c, 0x00000013,
172 0x00000058, 0x0003003e, 0x0000005c, 0x0000005b, 0x0004003d, 0x00000006, 0x0000005e, 0x0000001b, 0x00050041, 0x00000016,
173 0x0000005f, 0x00000013, 0x0000005d, 0x0003003e, 0x0000005f, 0x0000005e, 0x0004003d, 0x00000006, 0x00000061, 0x00000027,
174 0x00050041, 0x00000016, 0x00000062, 0x00000013, 0x00000060, 0x0003003e, 0x00000062, 0x00000061, 0x0004003d, 0x00000006,
175 0x00000063, 0x00000008, 0x00050041, 0x00000016, 0x00000064, 0x00000013, 0x00000024, 0x0004003d, 0x00000006, 0x00000065,
176 0x00000064, 0x00070041, 0x00000016, 0x00000066, 0x00000022, 0x00000015, 0x00000063, 0x00000024, 0x0003003e, 0x00000066,
177 0x00000065, 0x0004003d, 0x00000006, 0x00000067, 0x00000008, 0x00050041, 0x00000016, 0x00000068, 0x00000013, 0x00000029,
178 0x0004003d, 0x00000006, 0x00000069, 0x00000068, 0x00070041, 0x00000016, 0x0000006a, 0x00000022, 0x00000015, 0x00000067,
179 0x00000029, 0x0003003e, 0x0000006a, 0x00000069, 0x000200f9, 0x00000057, 0x000200f8, 0x00000057, 0x000200f9, 0x0000000d,
180 0x000200f8, 0x0000000d, 0x0004003d, 0x00000006, 0x0000006b, 0x00000008, 0x00050080, 0x00000006, 0x0000006c, 0x0000006b,
181 0x00000024, 0x0003003e, 0x00000008, 0x0000006c, 0x000200f9, 0x0000000a, 0x000200f8, 0x0000000c, 0x000100fd, 0x00010038};
182
Karl Schultz7b024b42018-08-30 16:18:18 -0600183// Convenience function for reporting problems with setting up GPU Validation.
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700184template <typename T>
185void GpuAssisted::ReportSetupProblem(T object, const char *const specific_message) const {
186 LogError(object, "UNASSIGNED-GPU-Assisted Validation Error. ", "Detail: (%s)", specific_message);
Karl Schultz7b024b42018-08-30 16:18:18 -0600187}
188
Tony-LunarG5c38b182020-06-10 16:15:32 -0600189bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
190 bool result =
191 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
192 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
193 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
194 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
195 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
196 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
197 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
198 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
199 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
200 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
201 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
202 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
203 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
204 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
205 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
206 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
207 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
208 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
209 enabled_features.core12.descriptorBindingPartiallyBound ||
210 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
211 return result;
212}
213
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600214void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
215 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700216 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
217 // acceleration structure build validation will find and replace invalid acceleration structure
218 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600219 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
220 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
221 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700222 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600223
224 // Validating DrawIndirectCount countBuffer will require validation shader to bind the count buffer as a storage buffer
225 if (validate_draw_indirect_count && cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) {
226 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
227 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700228}
229
Karl Schultz7b024b42018-08-30 16:18:18 -0600230// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600231void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
232 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600233 void *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600234 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600235 VkPhysicalDeviceFeatures features = {};
236 features.vertexPipelineStoresAndAtomics = true;
237 features.fragmentStoresAndAtomics = true;
238 features.shaderInt64 = true;
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600239 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), supported_features,
240 features);
Karl Schultz7b024b42018-08-30 16:18:18 -0600241}
Karl Schultz7b024b42018-08-30 16:18:18 -0600242// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600243void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
244 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
245 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600246 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600247
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600248 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
249 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
250 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700251
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600252 if (device_gpu_assisted->enabled_features.core.robustBufferAccess ||
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700253 device_gpu_assisted->enabled_features.robustness2_features.robustBufferAccess2) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600254 device_gpu_assisted->buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700255 } else {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600256 const char *bufferoob_string = getLayerOption("khronos_validation.gpuav_buffer_oob");
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600257 device_gpu_assisted->buffer_oob_enabled = *bufferoob_string ? !strcmp(bufferoob_string, "true") : true;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700258 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600259
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600260 if (((api_version >= VK_API_VERSION_1_2) && (enabled_features.core12.drawIndirectCount == VK_FALSE)) ||
261 (device_extensions.vk_khr_draw_indirect_count != kEnabledByCreateinfo)) {
262 device_gpu_assisted->validate_draw_indirect_count = false;
263 } else {
264 const char *draw_indirect_count_string = getLayerOption("khronos_validation.draw_direct_count_val");
265 device_gpu_assisted->validate_draw_indirect_count =
266 *draw_indirect_count_string ? !strcmp(draw_indirect_count_string, "true") : true;
267 }
268
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600269 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700270 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600271 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600272 return;
273 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600274
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600275 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700276 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600277 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
278 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600279 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600280 return;
281 }
282
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700283 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600284 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700285 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
286 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600287 }
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600288 device_gpu_assisted->shaderInt64 = supported_features.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600289 device_gpu_assisted->physicalDevice = physicalDevice;
290 device_gpu_assisted->device = *pDevice;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600291 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarG5c38b182020-06-10 16:15:32 -0600292 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600293 std::vector<VkDescriptorSetLayoutBinding> bindings;
294 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -0600295 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
296 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
297 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600298 NULL};
299 bindings.push_back(binding);
300 for (auto i = 1; i < 3; i++) {
301 binding.binding = i;
302 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600303 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700304 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600305 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600306}
307
Mike Schuchardt2df08912020-12-15 16:28:09 -0800308void GpuAssisted::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600309 VkDeviceAddress address) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600310 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
311 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600312 if (buffer_state) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600313 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600314 buffer_state->deviceAddress = address;
315 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600316}
317
Mike Schuchardt2df08912020-12-15 16:28:09 -0800318void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600319 VkDeviceAddress address) {
320 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
321}
322
Mike Schuchardt2df08912020-12-15 16:28:09 -0800323void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700324 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600325 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700326}
327
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600328void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600329 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600330 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG2966c732020-05-21 10:33:53 -0600331 ValidationStateTracker::PreCallRecordDestroyBuffer(device, buffer, pAllocator);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600332}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600333
Karl Schultz7b024b42018-08-30 16:18:18 -0600334// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600335void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600336 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700337 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600338 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600339 if (pre_draw_validation_state.globals_created) {
340 DispatchDestroyShaderModule(device, pre_draw_validation_state.validation_shader_module, nullptr);
341 DispatchDestroyDescriptorSetLayout(device, pre_draw_validation_state.validation_ds_layout, nullptr);
342 DispatchDestroyPipelineLayout(device, pre_draw_validation_state.validation_pipeline_layout, nullptr);
343 for (auto it = pre_draw_validation_state.renderpass_to_pipeline.begin();
344 it != pre_draw_validation_state.renderpass_to_pipeline.end(); ++it) {
345 DispatchDestroyPipeline(device, it->second, nullptr);
346 }
347 pre_draw_validation_state.renderpass_to_pipeline.clear();
348 pre_draw_validation_state.globals_created = false;
349 }
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600350 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
351 if (vmaAllocator) {
352 vmaDestroyAllocator(vmaAllocator);
353 }
354 desc_set_manager.reset();
Karl Schultz7b024b42018-08-30 16:18:18 -0600355}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600356
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600357void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600358 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700359 return;
360 }
361
Tony-LunarG99b880b2019-09-26 11:19:52 -0600362 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700363 if (as_validation_state.initialized) {
364 return;
365 }
366
367 if (!device_extensions.vk_nv_ray_tracing) {
368 return;
369 }
370
371 // Outline:
372 // - Create valid bottom level acceleration structure which acts as replacement
373 // - Create and load vertex buffer
374 // - Create and load index buffer
375 // - Create, allocate memory for, and bind memory for acceleration structure
376 // - Query acceleration structure handle
377 // - Create command pool and command buffer
378 // - Record build acceleration structure command
379 // - Submit command buffer and wait for completion
380 // - Cleanup
381 // - Create compute pipeline for validating instance buffers
382 // - Create descriptor set layout
383 // - Create pipeline layout
384 // - Create pipeline
385 // - Cleanup
386
387 VkResult result = VK_SUCCESS;
388
389 VkBuffer vbo = VK_NULL_HANDLE;
390 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
391 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600392 auto vbo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700393 vbo_ci.size = sizeof(float) * 9;
394 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
395
396 VmaAllocationCreateInfo vbo_ai = {};
397 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
398 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
399
Tony-LunarG99b880b2019-09-26 11:19:52 -0600400 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700401 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700402 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700403 }
404 }
405
406 if (result == VK_SUCCESS) {
407 uint8_t *mapped_vbo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700408 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700409 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700410 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700411 } else {
412 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
413 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600414 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700415 }
416 }
417
418 VkBuffer ibo = VK_NULL_HANDLE;
419 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
420 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600421 auto ibo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700422 ibo_ci.size = sizeof(uint32_t) * 3;
423 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
424
425 VmaAllocationCreateInfo ibo_ai = {};
426 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
427 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
428
Tony-LunarG99b880b2019-09-26 11:19:52 -0600429 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700430 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700431 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700432 }
433 }
434
435 if (result == VK_SUCCESS) {
436 uint8_t *mapped_ibo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700437 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700438 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700439 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700440 } else {
441 const std::vector<uint32_t> indicies = {0, 1, 2};
442 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600443 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700444 }
445 }
446
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600447 auto geometry = LvlInitStruct<VkGeometryNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700448 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600449 geometry.geometry.triangles = LvlInitStruct<VkGeometryTrianglesNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700450 geometry.geometry.triangles.vertexData = vbo;
451 geometry.geometry.triangles.vertexOffset = 0;
452 geometry.geometry.triangles.vertexCount = 3;
453 geometry.geometry.triangles.vertexStride = 12;
454 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
455 geometry.geometry.triangles.indexData = ibo;
456 geometry.geometry.triangles.indexOffset = 0;
457 geometry.geometry.triangles.indexCount = 3;
458 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
459 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
460 geometry.geometry.triangles.transformOffset = 0;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600461 geometry.geometry.aabbs = LvlInitStruct<VkGeometryAABBNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700462
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600463 auto as_ci = LvlInitStruct<VkAccelerationStructureCreateInfoNV>();
464 as_ci.info = LvlInitStruct<VkAccelerationStructureInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700465 as_ci.info.instanceCount = 0;
466 as_ci.info.geometryCount = 1;
467 as_ci.info.pGeometries = &geometry;
468 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600469 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700470 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700471 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700472 "Failed to create acceleration structure for acceleration structure build validation.");
473 }
474 }
475
476 VkMemoryRequirements2 as_mem_requirements = {};
477 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600478 auto as_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700479 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
480 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
481
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600482 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700483 }
484
485 VmaAllocationInfo as_memory_ai = {};
486 if (result == VK_SUCCESS) {
487 VmaAllocationCreateInfo as_memory_aci = {};
488 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
489
Tony-LunarG99b880b2019-09-26 11:19:52 -0600490 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
491 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700492 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700493 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700494 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
495 }
496 }
497
498 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600499 auto as_bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700500 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
501 as_bind_info.memory = as_memory_ai.deviceMemory;
502 as_bind_info.memoryOffset = as_memory_ai.offset;
503
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600504 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700505 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700506 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700507 "Failed to bind acceleration structure memory for acceleration structure build validation.");
508 }
509 }
510
511 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600512 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
513 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700514 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700515 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700516 "Failed to get acceleration structure handle for acceleration structure build validation.");
517 }
518 }
519
520 VkMemoryRequirements2 scratch_mem_requirements = {};
521 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600522 auto scratch_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700523 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
524 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
525
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600526 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
527 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700528 }
529
530 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600531 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700532 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600533 auto scratch_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700534 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
535 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700536 VmaAllocationCreateInfo scratch_aci = {};
537 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
538
Tony-LunarG18900282020-05-20 12:34:33 -0600539 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700540 if (result != VK_SUCCESS) {
Tony-LunarG18900282020-05-20 12:34:33 -0600541 ReportSetupProblem(device_gpuav->device,
542 "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700543 }
544 }
545
546 VkCommandPool command_pool = VK_NULL_HANDLE;
547 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600548 auto command_pool_ci = LvlInitStruct<VkCommandPoolCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700549 command_pool_ci.queueFamilyIndex = 0;
550
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600551 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700552 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700553 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700554 }
555 }
556
557 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
558
559 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600560 auto command_buffer_ai = LvlInitStruct<VkCommandBufferAllocateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700561 command_buffer_ai.commandPool = command_pool;
562 command_buffer_ai.commandBufferCount = 1;
563 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
564
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600565 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700566 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700567 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700568 "Failed to create command buffer for acceleration structure build validation.");
569 }
570
571 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600572 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700573 }
574
575 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600576 auto command_buffer_bi = LvlInitStruct<VkCommandBufferBeginInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700577
578 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
579 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700580 ReportSetupProblem(device_gpuav->device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700581 }
582 }
583
584 if (result == VK_SUCCESS) {
585 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
586 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
587 DispatchEndCommandBuffer(command_buffer);
588 }
589
590 VkQueue queue = VK_NULL_HANDLE;
591 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600592 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700593
594 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600595 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700596
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600597 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700598 submit_info.commandBufferCount = 1;
599 submit_info.pCommandBuffers = &command_buffer;
600 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
601 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700602 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700603 "Failed to submit command buffer for acceleration structure build validation.");
604 }
605 }
606
607 if (result == VK_SUCCESS) {
608 result = DispatchQueueWaitIdle(queue);
609 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700610 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700611 }
612 }
613
614 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600615 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700616 }
617 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600618 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700619 }
620 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG18900282020-05-20 12:34:33 -0600621 vmaDestroyBuffer(device_gpuav->vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700622 }
623 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600624 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700625 }
626
Tony-LunarG99b880b2019-09-26 11:19:52 -0600627 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700628 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700629 "Failed to find descriptor set layout for acceleration structure build validation.");
630 result = VK_INCOMPLETE;
631 }
632
633 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600634 auto pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700635 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600636 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600637 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700638 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700639 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700640 "Failed to create pipeline layout for acceleration structure build validation.");
641 }
642 }
643
644 VkShaderModule shader_module = VK_NULL_HANDLE;
645 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600646 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700647 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
648 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
649
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600650 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700651 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700652 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700653 "Failed to create compute shader module for acceleration structure build validation.");
654 }
655 }
656
657 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600658 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700659 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
660 pipeline_stage_ci.module = shader_module;
661 pipeline_stage_ci.pName = "main";
662
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600663 auto pipeline_ci = LvlInitStruct<VkComputePipelineCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700664 pipeline_ci.stage = pipeline_stage_ci;
665 pipeline_ci.layout = as_validation_state.pipeline_layout;
666
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600667 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
668 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700669 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700670 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700671 "Failed to create compute pipeline for acceleration structure build validation.");
672 }
673 }
674
675 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600676 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700677 }
678
679 if (result == VK_SUCCESS) {
680 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700681 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600682 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700683 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600684 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700685 }
686}
687
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600688void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600689 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700690 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
691 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
692 }
693 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
694 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
695 }
696 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
697 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
698 }
699 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600700 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700701 }
702}
703
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600704struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700705 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
706 VkPipeline pipeline = VK_NULL_HANDLE;
707 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
708 std::vector<VkDescriptorSet> descriptor_sets;
709 std::vector<std::vector<uint32_t>> dynamic_offsets;
710 uint32_t push_descriptor_set_index = 0;
711 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
712 std::vector<uint8_t> push_constants_data;
713 PushConstantRangesId push_constants_ranges;
714
715 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
716 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600717 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700718
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600719 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700720 if (last_bound.pipeline_state) {
721 pipeline = last_bound.pipeline_state->pipeline;
722 pipeline_layout = last_bound.pipeline_layout;
723 descriptor_sets.reserve(last_bound.per_set.size());
724 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
725 const auto *bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
726
727 descriptor_sets.push_back(bound_descriptor_set->GetSet());
728 if (bound_descriptor_set->IsPushDescriptor()) {
729 push_descriptor_set_index = static_cast<uint32_t>(i);
730 }
731 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
732 }
733
734 if (last_bound.push_descriptor_set) {
735 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
736 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500737 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700738 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500739 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700740 }
741 }
742 }
743
744 void Restore(VkCommandBuffer command_buffer) const {
745 if (pipeline != VK_NULL_HANDLE) {
746 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
747 if (!descriptor_sets.empty()) {
748 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
749 VkDescriptorSet descriptor_set = descriptor_sets[i];
750 if (descriptor_set != VK_NULL_HANDLE) {
751 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
752 static_cast<uint32_t>(i), 1, &descriptor_set,
753 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
754 }
755 }
756 }
757 if (!push_descriptor_set_writes.empty()) {
758 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
759 static_cast<uint32_t>(push_descriptor_set_writes.size()),
760 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
761 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600762 if (!push_constants_data.empty()) {
763 for (const auto &push_constant_range : *push_constants_ranges) {
764 if (push_constant_range.size == 0) continue;
765 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
766 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
767 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700768 }
769 }
770 }
771};
772
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600773void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
774 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
775 VkDeviceSize instanceOffset, VkBool32 update,
776 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
777 VkBuffer scratch, VkDeviceSize scratchOffset) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700778 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
779 return;
780 }
781
Tony-LunarG99b880b2019-09-26 11:19:52 -0600782 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700783 if (!as_validation_state.initialized) {
784 return;
785 }
786
787 // Empty acceleration structure is valid according to the spec.
788 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
789 return;
790 }
791
792 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
793 assert(cb_state != nullptr);
794
795 std::vector<uint64_t> current_valid_handles;
796 for (const auto &as_state_kv : accelerationStructureMap) {
797 const ACCELERATION_STRUCTURE_STATE &as_state = *as_state_kv.second;
Jeff Bolz95176d02020-04-01 00:36:16 -0500798 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700799 current_valid_handles.push_back(as_state.opaque_handle);
800 }
801 }
802
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600803 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700804 as_validation_buffer_info.acceleration_structure = dst;
805
806 const VkDeviceSize validation_buffer_size =
807 // One uint for number of instances to validate
808 4 +
809 // Two uint for the replacement acceleration structure handle
810 8 +
811 // One uint for number of invalid handles found
812 4 +
813 // Two uint for the first invalid handle found
814 8 +
815 // One uint for the number of current valid handles
816 4 +
817 // Two uint for each current valid handle
818 (8 * current_valid_handles.size());
819
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600820 auto validation_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700821 validation_buffer_create_info.size = validation_buffer_size;
822 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
823
824 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
825 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
826
Tony-LunarG99b880b2019-09-26 11:19:52 -0600827 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
828 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700829 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
830 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700831 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600832 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700833 return;
834 }
835
836 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700837 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
838 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700839 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700840 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600841 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700842 return;
843 }
844
845 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
846 mapped_validation_buffer->replacement_handle_bits_0 =
847 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
848 mapped_validation_buffer->replacement_handle_bits_1 =
849 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
850 mapped_validation_buffer->invalid_handle_found = 0;
851 mapped_validation_buffer->invalid_handle_bits_0 = 0;
852 mapped_validation_buffer->invalid_handle_bits_1 = 0;
853 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
854
855 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
856 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
857 const uint64_t current_valid_handle = current_valid_handles[i];
858
859 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
860 ++mapped_valid_handles;
861 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
862 ++mapped_valid_handles;
863 }
864
Tony-LunarG99b880b2019-09-26 11:19:52 -0600865 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700866
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700867 static constexpr const VkDeviceSize k_instance_size = 64;
868 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700869
Tony-LunarG1dce2392019-10-23 16:49:29 -0600870 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
871 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700872 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700873 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600874 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700875 return;
876 }
877
878 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
879 descriptor_buffer_infos[0].buffer = instanceData;
880 descriptor_buffer_infos[0].offset = instanceOffset;
881 descriptor_buffer_infos[0].range = instance_buffer_size;
882 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
883 descriptor_buffer_infos[1].offset = 0;
884 descriptor_buffer_infos[1].range = validation_buffer_size;
885
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600886 VkWriteDescriptorSet descriptor_set_writes[2] = {
887 LvlInitStruct<VkWriteDescriptorSet>(),
888 LvlInitStruct<VkWriteDescriptorSet>(),
889 };
Jason Macnak83cfd582019-07-31 10:14:24 -0700890 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
891 descriptor_set_writes[0].dstBinding = 0;
892 descriptor_set_writes[0].descriptorCount = 1;
893 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
894 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
Jason Macnak83cfd582019-07-31 10:14:24 -0700895 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
896 descriptor_set_writes[1].dstBinding = 1;
897 descriptor_set_writes[1].descriptorCount = 1;
898 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
899 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
900
901 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
902
903 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600904 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700905 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
906 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
907 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
908 &memory_barrier, 0, nullptr, 0, nullptr);
909
910 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600911 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700912 restorable_state.Create(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
913
914 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
915 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
916 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
917 &as_validation_buffer_info.descriptor_set, 0, nullptr);
918 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
919
920 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
921 // have been replaced by the validation compute shader before any builds take place.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600922 auto instance_buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700923 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
924 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
925 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
926 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
927 instance_buffer_barrier.buffer = instanceData;
928 instance_buffer_barrier.offset = instanceOffset;
929 instance_buffer_barrier.size = instance_buffer_size;
930 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
931 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
932 nullptr);
933
934 // Restore the previous compute pipeline state.
935 restorable_state.Restore(commandBuffer);
936
937 as_validation_state.validation_buffers[commandBuffer].push_back(std::move(as_validation_buffer_info));
938}
939
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600940void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700941 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
942 return;
943 }
944
Tony-LunarG99b880b2019-09-26 11:19:52 -0600945 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700946 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[cb_node->commandBuffer];
947 for (const auto &as_validation_buffer_info : as_validation_buffer_infos) {
948 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
949
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700950 VkResult result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
951 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700952 if (result == VK_SUCCESS) {
953 if (mapped_validation_buffer->invalid_handle_found > 0) {
954 uint64_t invalid_handle = 0;
955 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
956 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
957
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700958 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
959 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
960 "handle (%" PRIu64 ")",
961 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700962 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600963 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700964 }
965 }
966}
967
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600968void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
969 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
970 VkResult result) {
971 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600972 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600973 for (uint32_t i = 0; i < bindInfoCount; i++) {
974 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
sourav parmarcd5fb182020-07-17 12:58:44 -0700975 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureStateNV(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600976 if (as_state) {
977 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
978 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600979 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600980}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700981
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600982// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
983void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
984 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
985 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600986 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600987 return;
988 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600989
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600990 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
991
Tony-LunarG99b880b2019-09-26 11:19:52 -0600992 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600993 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600994 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600995 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
996 << "Validation is not modifying the pipeline layout. "
997 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700998 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600999 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -07001000 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -06001001 }
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -07001002}
1003
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001004void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
1005 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
1006 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001007 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
1008
Karl Schultz7b024b42018-08-30 16:18:18 -06001009 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001010 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001011 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -06001012 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001013}
1014
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001015// Free the device memory and descriptor set(s) associated with a command buffer.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001016void GpuAssisted::ResetCommandBuffer(VkCommandBuffer commandBuffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001017 if (aborted) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001018 return;
1019 }
Tony-LunarG1dce2392019-10-23 16:49:29 -06001020 auto gpuav_buffer_list = GetBufferInfo(commandBuffer);
John Zulauf79f06582021-02-27 18:38:39 -07001021 for (const auto &buffer_info : gpuav_buffer_list) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001022 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001023 if (buffer_info.di_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001024 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001025 }
1026 if (buffer_info.bda_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001027 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -06001028 }
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001029 if (buffer_info.desc_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001030 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarGdcbc2c32019-05-06 10:17:44 -06001031 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001032 if (buffer_info.pre_draw_resources.desc_set != VK_NULL_HANDLE) {
1033 desc_set_manager->PutBackDescriptorSet(buffer_info.pre_draw_resources.desc_pool,
1034 buffer_info.pre_draw_resources.desc_set);
1035 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001036 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001037 command_buffer_map.erase(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -07001038
Tony-LunarG99b880b2019-09-26 11:19:52 -06001039 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -07001040 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[commandBuffer];
1041 for (auto &as_validation_buffer_info : as_validation_buffer_infos) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001042 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -07001043 as_validation_buffer_info.validation_buffer_allocation);
1044
1045 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001046 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool,
1047 as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001048 }
1049 }
1050 as_validation_info.validation_buffers.erase(commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001051}
Karl Schultz7b024b42018-08-30 16:18:18 -06001052// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001053bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1054 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1055 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1056 uint32_t bufferMemoryBarrierCount,
1057 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001058 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001059 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001060 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001061 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1062 "GPU_Assisted validation waits on queue completion. "
1063 "This wait could block the host's signaling of this event, resulting in deadlock.");
1064 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001065 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001066}
1067
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001068bool GpuAssisted::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1069 const VkDependencyInfoKHR *pDependencyInfos) const {
1070 VkPipelineStageFlags2KHR srcStageMask = 0;
1071
1072 for (uint32_t i = 0; i < eventCount; i++) {
1073 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
1074 srcStageMask = stage_masks.src;
1075 }
1076
1077 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
1078 ReportSetupProblem(commandBuffer,
1079 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1080 "GPU_Assisted validation waits on queue completion. "
1081 "This wait could block the host's signaling of this event, resulting in deadlock.");
1082 }
1083 return false;
1084}
1085
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001086void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1087 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1088 // 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 -06001089 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001090 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1091 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1092 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001093 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1094 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001095 }
1096 }
1097}
1098
1099void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1100 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1101 // 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 -06001102 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001103 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1104 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1105 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001106 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1107 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001108 }
1109 }
1110}
1111
1112void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1113 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1114 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1115 void *cgpl_state_data) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001116 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001117 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001118 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1119 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001120 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1121 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001122}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001123
1124void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1125 const VkComputePipelineCreateInfo *pCreateInfos,
1126 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1127 void *ccpl_state_data) {
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001128 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001129 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001130 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1131 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001132 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1133 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Jason Macnak67407e72019-07-11 11:05:09 -07001134}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001135
1136void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1137 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1138 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1139 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001140 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001141 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001142 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1143 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001144 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1145 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001146}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001147
sourav parmarcd5fb182020-07-17 12:58:44 -07001148void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1149 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001150 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1151 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1152 void *crtpl_state_data) {
1153 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1154 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001155 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1156 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001157 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1158 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
1159}
Karl Schultz7b024b42018-08-30 16:18:18 -06001160
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001161void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1162 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1163 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1164 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001165 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1166 pPipelines, result, cgpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001167 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
1168 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001169 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001170}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001171
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001172void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1173 const VkComputePipelineCreateInfo *pCreateInfos,
1174 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1175 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001176 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1177 result, ccpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001178 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
1179 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001180 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001181}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001182
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001183void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1184 const VkRayTracingPipelineCreateInfoNV *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);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001188 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1189 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_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001192}
1193
sourav parmarcd5fb182020-07-17 12:58:44 -07001194void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1195 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001196 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1197 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1198 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001199 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
sourav parmarcd5fb182020-07-17 12:58:44 -07001200 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
1201 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001202 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001203 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001204}
1205
1206// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001207void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001208 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001209 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001210 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001211 } else {
1212 ++it;
1213 }
1214 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001215 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001216}
1217
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001218void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1219 const VkAllocationCallbacks *pAllocator) {
1220 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(renderPass);
1221 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1222 DispatchDestroyPipeline(device, pipeline->second, nullptr);
1223 pre_draw_validation_state.renderpass_to_pipeline.erase(pipeline);
1224 }
1225}
1226
Karl Schultz7b024b42018-08-30 16:18:18 -06001227// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001228bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1229 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001230 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001231 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1232
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001233 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001234 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1235 switch (level) {
1236 case SPV_MSG_FATAL:
1237 case SPV_MSG_INTERNAL_ERROR:
1238 case SPV_MSG_ERROR:
1239 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1240 position.index, message);
1241 break;
1242 default:
1243 break;
1244 }
1245 };
1246
Karl Schultz7b024b42018-08-30 16:18:18 -06001247 // Load original shader SPIR-V
1248 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1249 new_pgm.clear();
1250 new_pgm.reserve(num_words);
1251 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1252
1253 // Call the optimizer to instrument the shader.
1254 // 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 -07001255 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001256 using namespace spvtools;
Tony-LunarG8a51b7d2020-07-01 15:57:23 -06001257 spv_target_env target_env = PickSpirvEnv(api_version, (device_extensions.vk_khr_spirv_1_4 != kNotEnabled));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001258 spvtools::ValidatorOptions val_options;
1259 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1260 spvtools::OptimizerOptions opt_options;
1261 opt_options.set_run_validator(true);
1262 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001263 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001264 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001265 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001266 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Karl Schultz7b024b42018-08-30 16:18:18 -06001267 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG5c38b182020-06-10 16:15:32 -06001268 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64 &&
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001269 enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001270 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001271 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001272 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001273 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001274 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001275 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001276 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001277 return pass;
1278}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001279// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001280void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1281 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1282 void *csm_state_data) {
1283 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1284 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001285 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001286 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1287 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001288 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001289}
Tony-LunarG63f82e02021-04-12 16:13:48 -06001290static const int kInstErrorPreDrawValidate = spvtools::kInstErrorBuffOOBStorageTexel + 1; // TODO - get this into instrument.hpp
1291static const int kPreDrawValidateSubError = spvtools::kInstValidationOutError + 1;
1292static const int pre_draw_count_too_big_error = 1; // TODO - share this with the shader code
Karl Schultz7b024b42018-08-30 16:18:18 -06001293
Karl Schultz7b024b42018-08-30 16:18:18 -06001294// Generate the part of the message describing the violation.
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001295static bool GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg, GpuAssistedBufferInfo buf_info) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001296 using namespace spvtools;
1297 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001298 bool return_code = true;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001299 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001300 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001301 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1302 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001303 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001304 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001305 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001306 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001307 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001308 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001309 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001310 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001311 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1312 vuid_msg = "UNASSIGNED-Device address out of bounds";
1313 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001314 case kInstErrorBuffOOBUniform:
1315 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001316 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1317 if (size == 0) {
1318 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1319 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1320 } else {
1321 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1322 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001323 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001324 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001325 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1326 vuid_msg = vuid.uniform_access_oob;
1327 else
1328 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001329 }
1330 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001331 case kInstErrorBuffOOBUniformTexel:
1332 case kInstErrorBuffOOBStorageTexel: {
1333 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1334 if (size == 0) {
1335 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1336 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001337 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001338 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001339 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1340 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001341 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001342 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1343 vuid_msg = vuid.uniform_access_oob;
1344 else
1345 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001346 }
Tony-LunarG63f82e02021-04-12 16:13:48 -06001347 } break;
1348 case kInstErrorPreDrawValidate: {
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001349 // Buffer size must be >= (stride × (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
Tony-LunarG63f82e02021-04-12 16:13:48 -06001350 if (debug_record[kPreDrawValidateSubError] == pre_draw_count_too_big_error) {
Tony-LunarG63f82e02021-04-12 16:13:48 -06001351 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001352 uint32_t stride = buf_info.pre_draw_resources.stride;
1353 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
1354 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
1355 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1356 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
1357 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
1358 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001359 if (count == 1) {
1360 vuid_msg = vuid.count_exceeds_bufsize_1;
1361 } else {
1362 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001363 }
1364 }
1365 return_code = false;
1366 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001367 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001368 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001369 vuid_msg = "UNASSIGNED-Internal Error";
1370 assert(false);
1371 } break;
1372 }
1373 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001374 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001375}
1376
Karl Schultz7b024b42018-08-30 16:18:18 -06001377// Pull together all the information from the debug record to build the error message strings,
1378// and then assemble them into a single message string.
1379// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1380// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1381// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1382// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1383//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001384void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001385 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001386 using namespace spvtools;
1387 const uint32_t total_words = debug_output_buffer[0];
1388 // A zero here means that the shader instrumentation didn't write anything.
1389 // If you have nothing to say, don't say it here.
1390 if (0 == total_words) {
1391 return;
1392 }
1393 // The first word in the debug output buffer is the number of words that would have
1394 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1395 // The number of words actually written by the shaders is determined by the size of the buffer
1396 // we provide via the descriptor. So, we process only the number of words that can fit in the
1397 // buffer.
1398 // Each "report" written by the shader instrumentation is considered a "record". This function
1399 // is hard-coded to process only one record because it expects the buffer to be large enough to
1400 // hold only one record. If there is a desire to process more than one record, this function needs
1401 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001402 std::string validation_message;
1403 std::string stage_message;
1404 std::string common_message;
1405 std::string filename_message;
1406 std::string source_message;
1407 std::string vuid_msg;
1408 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1409 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1410 std::vector<unsigned int> pgm;
1411 // The first record starts at this offset after the total_words.
1412 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1413 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1414 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001415 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1416 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001417 shader_module_handle = it->second.shader_module;
1418 pipeline_handle = it->second.pipeline;
1419 pgm = it->second.pgm;
1420 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001421 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001422 if (gen_full_message) {
1423 UtilGenerateStageMessage(debug_record, stage_message);
1424 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1425 buffer_info.pipeline_bind_point, operation_index, common_message);
1426 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1427 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1428 filename_message.c_str(), source_message.c_str());
1429 }
1430 else {
1431 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1432 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001433 // The debug record at word kInstCommonOutSize is the number of words in the record
1434 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001435 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001436 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1437}
1438
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001439void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1440 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1441 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001442 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001443 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001444 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001445 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1446 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1447 }
1448 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1449 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001450 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001451 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001452 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001453 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1454 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1455 }
1456 } else {
1457 pData[index] = 1;
1458 }
1459}
1460
Tony-LunarG81efe392019-03-07 15:43:27 -07001461// 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 -06001462void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001463 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001464 uint32_t *data;
Tony-LunarG81efe392019-03-07 15:43:27 -07001465 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001466 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001467 VkResult result =
1468 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001469 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001470 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001471 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001472 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001473 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001474 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001475 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001476 }
1477 }
1478 }
1479}
1480
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001481void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
1482 auto cb_node = GetCBState(command_buffer);
1483 UpdateInstrumentationBuffer(cb_node);
John Zulauf79f06582021-02-27 18:38:39 -07001484 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001485 UpdateInstrumentationBuffer(secondary_cmd_buffer);
1486 }
1487}
1488
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001489void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001490 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1491 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1492 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001493 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001494 }
1495 }
1496}
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001497void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1498 VkFence fence) {
1499 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1500 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1501 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1502 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1503 }
1504 }
1505}
1506
1507bool GpuAssisted::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
1508 bool buffers_present = false;
1509 auto cb_node = GetCBState(command_buffer);
1510
1511 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) {
1512 buffers_present = true;
1513 }
John Zulauf79f06582021-02-27 18:38:39 -07001514 for (const auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001515 if (GetBufferInfo(secondary_cmd_buffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) {
1516 buffers_present = true;
1517 }
1518 }
1519 return buffers_present;
1520}
1521
1522void GpuAssisted::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
1523 auto cb_node = GetCBState(command_buffer);
1524
1525 UtilProcessInstrumentationBuffer(queue, cb_node, this);
1526 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
John Zulauf79f06582021-02-27 18:38:39 -07001527 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001528 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
1529 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
1530 }
1531}
Tony-LunarG81efe392019-03-07 15:43:27 -07001532
Karl Schultz58674242019-01-22 15:35:02 -07001533// Issue a memory barrier to make GPU-written data available to host.
1534// Wait for the queue to complete execution.
1535// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001536void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1537 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001538 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001539
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001540 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001541 bool buffers_present = false;
1542 // Don't QueueWaitIdle if there's nothing to process
1543 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1544 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1545 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001546 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001547 }
1548 }
1549 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001550
Tony-LunarGb5fae462020-03-05 12:43:25 -07001551 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001552
Tony-LunarG152a88b2019-03-20 15:42:24 -06001553 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001554
Karl Schultz7b024b42018-08-30 16:18:18 -06001555 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1556 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1557 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001558 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
1559 }
1560 }
1561}
1562
1563void GpuAssisted::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1564 VkFence fence, VkResult result) {
1565 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
1566
1567 if (aborted || (result != VK_SUCCESS)) return;
1568 bool buffers_present = false;
1569 // Don't QueueWaitIdle if there's nothing to process
1570 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1571 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1572 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1573 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
1574 }
1575 }
1576 if (!buffers_present) return;
1577
1578 UtilSubmitBarrier(queue, this);
1579
1580 DispatchQueueWaitIdle(queue);
1581
1582 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1583 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1584 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1585 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001586 }
1587 }
1588}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001589
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001590void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1591 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001592 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001593}
1594
1595void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1596 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001597 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001598}
1599
1600void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1601 uint32_t stride) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001602 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001603}
1604
1605void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1606 uint32_t count, uint32_t stride) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001607 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001608}
1609
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001610void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1611 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1612 uint32_t stride) {
1613 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1614 maxDrawCount, stride);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001615 GpuAssistedCmdDrawIndirectState cdic_state = { buffer, offset, stride, countBuffer, countBufferOffset };
1616 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdic_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001617}
1618
1619void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1620 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001621
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001622 uint32_t stride) {
1623 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1624 maxDrawCount, stride);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001625 GpuAssistedCmdDrawIndirectState cdic_state = { buffer, offset, stride, countBuffer, countBufferOffset };
1626 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdic_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001627}
1628
Tony-LunarG54176fb2020-12-02 10:47:22 -07001629void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1630 uint32_t firstInstance, VkBuffer counterBuffer,
1631 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1632 uint32_t vertexStride) {
1633 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1634 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001635 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001636}
1637
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001638void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1639 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1640 uint32_t maxDrawCount, uint32_t stride) {
1641 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1642 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001643 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001644}
1645
1646void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1647 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1648 uint32_t maxDrawCount, uint32_t stride) {
1649 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1650 maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001651 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001652}
1653
1654void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1655 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001656 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001657}
1658
1659void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1660 uint32_t drawCount, uint32_t stride) {
1661 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001662 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001663}
1664
1665void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1666 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1667 uint32_t maxDrawCount, uint32_t stride) {
1668 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1669 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001670 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001671}
1672
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001673void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001674 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001675}
1676
1677void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001678 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001679}
1680
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001681void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1682 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1683 uint32_t groupCountZ) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001684 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001685}
1686
Tony-LunarG52c8c602020-09-10 16:29:56 -06001687void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1688 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1689 uint32_t groupCountZ) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001690 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001691}
1692
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001693void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1694 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1695 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1696 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1697 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1698 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1699 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001700 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001701}
1702
1703void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1704 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1705 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1706 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1707 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1708 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1709 uint32_t width, uint32_t height, uint32_t depth) {
1710 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1711 cb_state->hasTraceRaysCmd = true;
1712}
1713
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001714void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001715 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1716 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1717 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1718 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001719 uint32_t height, uint32_t depth) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001720 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001721}
1722
1723void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001724 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1725 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1726 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1727 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001728 uint32_t height, uint32_t depth) {
1729 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1730 cb_state->hasTraceRaysCmd = true;
1731}
1732
1733void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001734 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1735 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1736 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1737 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001738 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001739 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001740}
1741
1742void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001743 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1744 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1745 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1746 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001747 VkDeviceAddress indirectDeviceAddress) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001748 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1749 cb_state->hasTraceRaysCmd = true;
1750}
1751
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001752void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1753 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
1754 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdic_state) {
1755 VkResult result;
1756 if (!pre_draw_validation_state.globals_created) {
1757 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
1758 shader_module_ci.codeSize = sizeof(kPreDrawValidaitonShaderSpirv);
1759 shader_module_ci.pCode = (uint32_t *)kPreDrawValidaitonShaderSpirv;
1760 result =
1761 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001762 if (result != VK_SUCCESS) {
1763 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1764 aborted = true;
1765 return;
1766 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001767
1768 std::vector<VkDescriptorSetLayoutBinding> bindings;
1769 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1770 // 0 - output buffer, 1 - count buffer
1771 bindings.push_back(binding);
1772 binding.binding = 1;
1773 bindings.push_back(binding);
1774
1775 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1776 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1777 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1778 ds_layout_ci.pBindings = bindings.data();
1779 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001780 if (result != VK_SUCCESS) {
1781 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1782 aborted = true;
1783 return;
1784 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001785
1786 const uint32_t push_constant_range_count = 1;
1787 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1788 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1789 push_constant_ranges[0].offset = 0;
1790 push_constant_ranges[0].size = 2 * sizeof(uint32_t);
1791 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
1792 pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1793 pipelineLayoutCreateInfo[0].pNext = NULL;
1794 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1795 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1796 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1797 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1798 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1799 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001800 if (result != VK_SUCCESS) {
1801 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1802 aborted = true;
1803 return;
1804 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001805
1806 pre_draw_validation_state.globals_created = true;
1807 }
1808 VkRenderPass render_pass = state.pipeline_state->rp_state->renderPass;
1809 assert(render_pass != VK_NULL_HANDLE);
1810 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1811 if (pipeline == pre_draw_validation_state.renderpass_to_pipeline.end()) {
1812 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1813 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1814 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1815 pipeline_stage_ci.pName = "main";
1816
1817 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1818 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1819 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1820 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1821 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1822 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1823 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1824
1825 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1826 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1827 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1828 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1829 graphicsPipelineCreateInfo.renderPass = render_pass;
1830 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1831 graphicsPipelineCreateInfo.stageCount = 1;
1832 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1833
1834 VkPipeline new_pipeline = VK_NULL_HANDLE;
1835 result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &new_pipeline);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001836 if (result != VK_SUCCESS) {
1837 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1838 aborted = true;
1839 return;
1840 }
1841
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001842 *pPipeline = new_pipeline;
1843 pre_draw_validation_state.renderpass_to_pipeline[render_pass] = new_pipeline;
1844 } else {
1845 *pPipeline = pipeline->second;
1846 }
1847
1848 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1849 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001850 if (result != VK_SUCCESS) {
1851 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1852 aborted = true;
1853 return;
1854 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001855
1856 VkDescriptorBufferInfo buffer_infos[3] = {};
1857 // Error output buffer
1858 buffer_infos[0].buffer = output_block.buffer;
1859 buffer_infos[0].offset = 0;
1860 buffer_infos[0].range = VK_WHOLE_SIZE;
1861 // Original count buffer
1862 buffer_infos[1].buffer = cdic_state->count_buffer;
1863 buffer_infos[1].offset = 0;
1864 buffer_infos[1].range = VK_WHOLE_SIZE;
1865
1866 VkWriteDescriptorSet desc_writes[2] = {};
1867 for (auto i = 0; i < 2; i++) {
1868 desc_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1869 desc_writes[i].dstBinding = i;
1870 desc_writes[i].descriptorCount = 1;
1871 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1872 desc_writes[i].pBufferInfo = &buffer_infos[i];
1873 desc_writes[i].dstSet = resources.desc_set;
1874 }
1875 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
1876}
1877
Tony-LunarG7de10e82020-11-24 11:31:55 -07001878void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001879 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdic_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07001880 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1881 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001882 return;
1883 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001884 VkResult result;
1885
Tony-LunarG99b880b2019-09-26 11:19:52 -06001886 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001887
1888 std::vector<VkDescriptorSet> desc_sets;
1889 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001890 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001891 assert(result == VK_SUCCESS);
1892 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001893 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001894 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001895 return;
1896 }
1897
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001898 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001899 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001900
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001901 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001902 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001903 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001904 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001905 return;
1906 }
1907
Tony-LunarG81efe392019-03-07 15:43:27 -07001908 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001909 GpuAssistedDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001910 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
1911 buffer_info.size = output_buffer_size;
1912 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1913 VmaAllocationCreateInfo alloc_info = {};
1914 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
1915 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001916 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001917 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001918 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001919 return;
1920 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001921
Tony-LunarG81efe392019-03-07 15:43:27 -07001922 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001923 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001924 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001925 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001926 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001927 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001928 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001929
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001930 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001931 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1932 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1933 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001934 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001935 uint32_t desc_count = 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06001936 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1937 auto const &state = cb_node->lastBound[lv_bind_point];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001938 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001939
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001940 if (cmd_type == CMD_DRAWINDIRECTCOUNT && validate_draw_indirect_count) {
1941 // Insert a draw that can examine some device memory right before the draw we're validating (Pre Draw Validation)
1942 // Currently the only Pre Draw Validation is checking the count value in the countBuffer of a Draw*IndirectCount call
1943 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
1944 assert(cdic_state != NULL);
1945 VkPipeline validation_pipeline;
1946 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdic_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001947 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001948
1949 // Save current graphics pipeline state
1950 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
1951 restorable_state.Create(cb_node, VK_PIPELINE_BIND_POINT_GRAPHICS);
1952
1953 if (cdic_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
1954 ReportSetupProblem(device, "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
1955 aborted = true;
1956 return;
1957 }
1958
1959 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
1960 BUFFER_STATE *buffer_state = GetBufferState(cdic_state->buffer);
1961 uint32_t max_count;
1962 uint64_t bufsize = buffer_state->createInfo.size;
1963 uint64_t first_command_bytes = sizeof(VkDrawIndirectCommand) + cdic_state->offset;
1964 if (first_command_bytes > bufsize) {
1965 max_count = 0;
1966 } else {
1967 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdic_state->stride)));
1968 }
1969
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001970 // Save parameters for error message
1971 pre_draw_resources.buffer = cdic_state->buffer;
1972 pre_draw_resources.offset = cdic_state->offset;
1973 pre_draw_resources.stride = cdic_state->stride;
1974 pre_draw_resources.buf_size = buffer_state->createInfo.size;
1975
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001976 // Insert diagnostic draw
1977 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
1978 uint32_t pushConstants[2] = {};
1979 pushConstants[0] = max_count;
1980 pushConstants[1] = static_cast<uint32_t>((cdic_state->count_buffer_offset / sizeof(uint32_t)));
1981 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
1982 sizeof(pushConstants), pushConstants);
1983 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1984 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
1985 nullptr);
1986 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
1987
1988 // Restore the previous graphics pipeline state.
1989 restorable_state.Restore(cmd_buffer);
1990 }
1991
Tony-LunarGe29097a2020-12-03 10:59:19 -07001992 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001993 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1994 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001995 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001996 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1997 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07001998 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001999 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06002000 if (desc && (desc->GetBindingCount() > 0)) {
2001 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07002002 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
2003 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002004 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
2005 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07002006 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
2007 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002008 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07002009 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
2010 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
2011 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06002012 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07002013 descriptor_count += desc->GetVariableDescriptorCount();
2014 } else {
2015 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
2016 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07002017 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2018 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
2019 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07002020 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2021 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2022 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002023 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002024 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002025 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002026 }
2027 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002028
Tony-LunarGe29097a2020-12-03 10:59:19 -07002029 if (descriptor_indexing || has_buffers) {
2030 // Note that the size of the input buffer is dependent on the maximum binding number, which
2031 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2032 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2033 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2034 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2035 uint32_t words_needed;
2036 if (descriptor_indexing) {
2037 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2038 } else {
2039 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2040 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002041 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2042 buffer_info.size = words_needed * 4;
2043 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2044 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002045 if (result != VK_SUCCESS) {
2046 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
2047 aborted = true;
2048 return;
2049 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002050
Tony-LunarGe29097a2020-12-03 10:59:19 -07002051 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2052 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2053 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002054 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2055 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002056
Tony-LunarGe29097a2020-12-03 10:59:19 -07002057 // Descriptor indexing needs the number of descriptors at each binding.
2058 if (descriptor_indexing) {
2059 // Pointer to a sets array that points into the sizes array
2060 uint32_t *sets_to_sizes = data_ptr + 1;
2061 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2062 uint32_t *sizes = sets_to_sizes + number_of_sets;
2063 // Pointer to another sets array that points into the bindings array that points into the written array
2064 uint32_t *sets_to_bindings = sizes + binding_count;
2065 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2066 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2067 // Index of the next entry in the written array to be updated
2068 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2069 uint32_t bind_counter = number_of_sets + 1;
2070 // Index of the start of the sets_to_bindings array
2071 data_ptr[0] = number_of_sets + binding_count + 1;
2072
John Zulauf79f06582021-02-27 18:38:39 -07002073 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002074 auto desc = s.bound_descriptor_set;
2075 if (desc && (desc->GetBindingCount() > 0)) {
2076 auto layout = desc->GetLayout();
2077 auto bindings = layout->GetSortedBindingSet();
2078 // For each set, fill in index of its bindings sizes in the sizes array
2079 *sets_to_sizes++ = bind_counter;
2080 // For each set, fill in the index of its bindings in the bindings_to_written array
2081 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
2082 for (auto binding : bindings) {
2083 // For each binding, fill in its size in the sizes array
2084 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2085 // uniform blocks
2086 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2087 sizes[binding] = 1;
2088 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
2089 sizes[binding] = desc->GetVariableDescriptorCount();
2090 } else {
2091 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
2092 }
2093 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2094 bindings_to_written[binding] = written_index;
2095
2096 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2097 // uniform blocks
2098 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2099 data_ptr[written_index++] = UINT_MAX;
2100 continue;
2101 }
2102
2103 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2104 // For each array element in the binding, update the written array with whether it has been written
2105 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2106 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2107 if (descriptor->updated) {
2108 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2109 } else if (desc->IsUpdateAfterBind(binding)) {
2110 // If it hasn't been written now and it's update after bind, put it in a list to check at
2111 // QueueSubmit
2112 di_input_block.update_at_submit[written_index] = descriptor;
2113 }
2114 written_index++;
2115 }
2116 }
2117 auto last = desc->GetLayout()->GetMaxBinding();
2118 bindings_to_written += last + 1;
2119 bind_counter += last + 1;
2120 sizes += last + 1;
2121 } else {
2122 *sets_to_sizes++ = 0;
2123 *sets_to_bindings++ = 0;
2124 }
2125 }
2126 } else {
2127 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2128 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2129
2130 // Pointer to sets array that points into the bindings array that points into the written array
2131 uint32_t *sets_to_bindings = data_ptr + 1;
2132 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2133 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2134 // Index of the next entry in the written array to be updated
2135 uint32_t written_index = 1 + number_of_sets + binding_count;
2136 uint32_t bind_counter = number_of_sets + 1;
2137 data_ptr[0] = 1;
2138
John Zulauf79f06582021-02-27 18:38:39 -07002139 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002140 auto desc = s.bound_descriptor_set;
2141 if (desc && (desc->GetBindingCount() > 0)) {
2142 auto layout = desc->GetLayout();
2143 auto bindings = layout->GetSortedBindingSet();
2144 *sets_to_bindings++ = bind_counter;
2145 for (auto binding : bindings) {
2146 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2147 bindings_to_written[binding] = written_index;
2148
2149 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2150 // uniform blocks
2151 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2152 data_ptr[written_index++] = UINT_MAX;
2153 continue;
2154 }
2155
2156 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2157
2158 // For each array element in the binding, update the written array with whether it has been written
2159 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2160 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2161 if (descriptor->updated) {
2162 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2163 } else if (desc->IsUpdateAfterBind(binding)) {
2164 // If it hasn't been written now and it's update after bind, put it in a list to check at
2165 // QueueSubmit
2166 di_input_block.update_at_submit[written_index] = descriptor;
2167 }
2168 written_index++;
2169 }
2170 }
2171 auto last = desc->GetLayout()->GetMaxBinding();
2172 bindings_to_written += last + 1;
2173 bind_counter += last + 1;
2174 } else {
2175 *sets_to_bindings++ = 0;
2176 }
2177 }
2178 }
2179 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2180
2181 di_input_desc_buffer_info.range = (words_needed * 4);
2182 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2183 di_input_desc_buffer_info.offset = 0;
2184
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002185 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002186 desc_writes[1].dstBinding = 1;
2187 desc_writes[1].descriptorCount = 1;
2188 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2189 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2190 desc_writes[1].dstSet = desc_sets[0];
2191
2192 desc_count = 2;
2193 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002194 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002195
Tony-LunarGc111b242020-06-30 14:43:45 -06002196 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 -06002197 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002198 // Example BDA input buffer assuming 2 buffers using BDA:
2199 // Word 0 | Index of start of buffer sizes (in this case 5)
2200 // Word 1 | 0x0000000000000000
2201 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2202 // Word 3 | Device Address of second buffer
2203 // Word 4 | 0xffffffffffffffff
2204 // Word 5 | 0 (size of pretend buffer at word 1)
2205 // Word 6 | Size in bytes of first buffer
2206 // Word 7 | Size in bytes of second buffer
2207 // Word 8 | 0 (size of pretend buffer in word 4)
2208
Tony-LunarG99b880b2019-09-26 11:19:52 -06002209 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002210 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002211 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2212 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06002213 result =
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002214 vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002215 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002216 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002217 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002218 return;
2219 }
2220 uint64_t *bda_data;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002221 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002222 uint32_t address_index = 1;
2223 uint32_t size_index = 3 + num_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002224 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002225 bda_data[0] = size_index; // Start of buffer sizes
2226 bda_data[address_index++] = 0; // NULL address
2227 bda_data[size_index++] = 0;
2228
John Zulauf79f06582021-02-27 18:38:39 -07002229 for (const auto &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002230 bda_data[address_index++] = value.first;
2231 bda_data[size_index++] = value.second;
2232 }
2233 bda_data[address_index] = UINTPTR_MAX;
2234 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06002235 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002236
2237 bda_input_desc_buffer_info.range = (words_needed * 8);
2238 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2239 bda_input_desc_buffer_info.offset = 0;
2240
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002241 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002242 desc_writes[desc_count].dstBinding = 2;
2243 desc_writes[desc_count].descriptorCount = 1;
2244 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2245 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2246 desc_writes[desc_count].dstSet = desc_sets[0];
2247 desc_count++;
2248 }
2249
Tony-LunarGb2501d22019-01-28 09:59:13 -07002250 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002251 output_desc_buffer_info.buffer = output_block.buffer;
2252 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002253
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002254 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002255 desc_writes[0].descriptorCount = 1;
2256 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2257 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2258 desc_writes[0].dstSet = desc_sets[0];
2259 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002260
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002261 const auto *pipeline_state = state.pipeline_state;
2262 if (pipeline_state) {
2263 if ((pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002264 !pipeline_state->pipeline_layout->destroyed) {
Jeff Bolze7fc67b2019-10-04 12:29:31 -05002265 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002266 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002267 }
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002268 if (pipeline_state->pipeline_layout->destroyed) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002269 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2270 aborted = true;
2271 } else {
2272 // Record buffer and memory info in CB state tracking
2273 GetBufferInfo(cmd_buffer)
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002274 .emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0], desc_pool,
2275 bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002276 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002277 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002278 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002279 aborted = true;
2280 }
2281 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002282 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2283 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2284 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002285 return;
2286 }
2287}