blob: f597f0f7cf6352113a3eb1e2039c3bd389fc2195 [file] [log] [blame]
Jeremy Gebben4d51c552022-01-06 21:27:15 -07001/* Copyright (c) 2018-2022 The Khronos Group Inc.
2 * Copyright (c) 2018-2022 Valve Corporation
3 * Copyright (c) 2018-2022 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"
Tony-LunarG20678ff2021-05-07 14:56:26 -060028#include "gpu_pre_draw_constants.h"
Jeremy Gebbena3705f42021-01-19 16:47:43 -070029#include "sync_utils.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060030#include "buffer_state.h"
31#include "cmd_buffer_state.h"
32#include "render_pass_state.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060033
Jason Macnak67407e72019-07-11 11:05:09 -070034static const VkShaderStageFlags kShaderStageAllRayTracing =
35 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
36 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
37
Jason Macnak83cfd582019-07-31 10:14:24 -070038// Keep in sync with the GLSL shader below.
39struct GpuAccelerationStructureBuildValidationBuffer {
40 uint32_t instances_to_validate;
41 uint32_t replacement_handle_bits_0;
42 uint32_t replacement_handle_bits_1;
43 uint32_t invalid_handle_found;
44 uint32_t invalid_handle_bits_0;
45 uint32_t invalid_handle_bits_1;
46 uint32_t valid_handles_count;
47};
48
49// This is the GLSL source for the compute shader that is used during ray tracing acceleration structure
50// building validation which inspects instance buffers for top level acceleration structure builds and
51// reports and replaces invalid bottom level acceleration structure handles with good bottom level
52// acceleration structure handle so that applications can continue without undefined behavior long enough
53// to report errors.
54//
55// #version 450
56// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
57// struct VkGeometryInstanceNV {
58// uint unused[14];
59// uint handle_bits_0;
60// uint handle_bits_1;
61// };
62// layout(set=0, binding=0, std430) buffer InstanceBuffer {
63// VkGeometryInstanceNV instances[];
64// };
65// layout(set=0, binding=1, std430) buffer ValidationBuffer {
66// uint instances_to_validate;
67// uint replacement_handle_bits_0;
68// uint replacement_handle_bits_1;
69// uint invalid_handle_found;
70// uint invalid_handle_bits_0;
71// uint invalid_handle_bits_1;
72// uint valid_handles_count;
73// uint valid_handles[];
74// };
75// void main() {
76// for (uint instance_index = 0; instance_index < instances_to_validate; instance_index++) {
77// uint instance_handle_bits_0 = instances[instance_index].handle_bits_0;
78// uint instance_handle_bits_1 = instances[instance_index].handle_bits_1;
79// bool valid = false;
80// for (uint valid_handle_index = 0; valid_handle_index < valid_handles_count; valid_handle_index++) {
81// if (instance_handle_bits_0 == valid_handles[2*valid_handle_index+0] &&
82// instance_handle_bits_1 == valid_handles[2*valid_handle_index+1]) {
83// valid = true;
84// break;
85// }
86// }
87// if (!valid) {
88// invalid_handle_found += 1;
89// invalid_handle_bits_0 = instance_handle_bits_0;
90// invalid_handle_bits_1 = instance_handle_bits_1;
91// instances[instance_index].handle_bits_0 = replacement_handle_bits_0;
92// instances[instance_index].handle_bits_1 = replacement_handle_bits_1;
93// }
94// }
95// }
96//
97// To regenerate the spirv below:
98// 1. Save the above GLSL source to a file called validation_shader.comp.
99// 2. Run in terminal
100//
101// glslangValidator.exe -x -V validation_shader.comp -o validation_shader.comp.spv
102//
103// 4. Copy-paste the contents of validation_shader.comp.spv here (clang-format will fix up the alignment).
104static const uint32_t kComputeShaderSpirv[] = {
105 0x07230203, 0x00010000, 0x00080007, 0x0000006d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
106 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005, 0x00000004, 0x6e69616d,
107 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2,
108 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x00000008, 0x74736e69, 0x65636e61, 0x646e695f, 0x00007865,
109 0x00070005, 0x00000011, 0x696c6156, 0x69746164, 0x75426e6f, 0x72656666, 0x00000000, 0x00090006, 0x00000011, 0x00000000,
110 0x74736e69, 0x65636e61, 0x6f745f73, 0x6c61765f, 0x74616469, 0x00000065, 0x000a0006, 0x00000011, 0x00000001, 0x6c706572,
111 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x000a0006, 0x00000011, 0x00000002, 0x6c706572,
112 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00090006, 0x00000011, 0x00000003, 0x61766e69,
113 0x5f64696c, 0x646e6168, 0x665f656c, 0x646e756f, 0x00000000, 0x00090006, 0x00000011, 0x00000004, 0x61766e69, 0x5f64696c,
114 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00090006, 0x00000011, 0x00000005, 0x61766e69, 0x5f64696c, 0x646e6168,
115 0x625f656c, 0x5f737469, 0x00000031, 0x00080006, 0x00000011, 0x00000006, 0x696c6176, 0x61685f64, 0x656c646e, 0x6f635f73,
116 0x00746e75, 0x00070006, 0x00000011, 0x00000007, 0x696c6176, 0x61685f64, 0x656c646e, 0x00000073, 0x00030005, 0x00000013,
117 0x00000000, 0x00080005, 0x0000001b, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000305f, 0x00080005,
118 0x0000001e, 0x65476b56, 0x74656d6f, 0x6e497972, 0x6e617473, 0x564e6563, 0x00000000, 0x00050006, 0x0000001e, 0x00000000,
119 0x73756e75, 0x00006465, 0x00070006, 0x0000001e, 0x00000001, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00070006,
120 0x0000001e, 0x00000002, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00060005, 0x00000020, 0x74736e49, 0x65636e61,
121 0x66667542, 0x00007265, 0x00060006, 0x00000020, 0x00000000, 0x74736e69, 0x65636e61, 0x00000073, 0x00030005, 0x00000022,
122 0x00000000, 0x00080005, 0x00000027, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000315f, 0x00040005,
123 0x0000002d, 0x696c6176, 0x00000064, 0x00070005, 0x0000002f, 0x696c6176, 0x61685f64, 0x656c646e, 0x646e695f, 0x00007865,
124 0x00040047, 0x00000010, 0x00000006, 0x00000004, 0x00050048, 0x00000011, 0x00000000, 0x00000023, 0x00000000, 0x00050048,
125 0x00000011, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000011, 0x00000002, 0x00000023, 0x00000008, 0x00050048,
126 0x00000011, 0x00000003, 0x00000023, 0x0000000c, 0x00050048, 0x00000011, 0x00000004, 0x00000023, 0x00000010, 0x00050048,
127 0x00000011, 0x00000005, 0x00000023, 0x00000014, 0x00050048, 0x00000011, 0x00000006, 0x00000023, 0x00000018, 0x00050048,
128 0x00000011, 0x00000007, 0x00000023, 0x0000001c, 0x00030047, 0x00000011, 0x00000003, 0x00040047, 0x00000013, 0x00000022,
129 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000001, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00050048,
130 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000038, 0x00050048,
131 0x0000001e, 0x00000002, 0x00000023, 0x0000003c, 0x00040047, 0x0000001f, 0x00000006, 0x00000040, 0x00050048, 0x00000020,
132 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000003, 0x00040047, 0x00000022, 0x00000022, 0x00000000,
133 0x00040047, 0x00000022, 0x00000021, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015,
134 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x0004002b, 0x00000006, 0x00000009,
135 0x00000000, 0x0003001d, 0x00000010, 0x00000006, 0x000a001e, 0x00000011, 0x00000006, 0x00000006, 0x00000006, 0x00000006,
136 0x00000006, 0x00000006, 0x00000006, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012,
137 0x00000013, 0x00000002, 0x00040015, 0x00000014, 0x00000020, 0x00000001, 0x0004002b, 0x00000014, 0x00000015, 0x00000000,
138 0x00040020, 0x00000016, 0x00000002, 0x00000006, 0x00020014, 0x00000019, 0x0004002b, 0x00000006, 0x0000001c, 0x0000000e,
139 0x0004001c, 0x0000001d, 0x00000006, 0x0000001c, 0x0005001e, 0x0000001e, 0x0000001d, 0x00000006, 0x00000006, 0x0003001d,
140 0x0000001f, 0x0000001e, 0x0003001e, 0x00000020, 0x0000001f, 0x00040020, 0x00000021, 0x00000002, 0x00000020, 0x0004003b,
141 0x00000021, 0x00000022, 0x00000002, 0x0004002b, 0x00000014, 0x00000024, 0x00000001, 0x0004002b, 0x00000014, 0x00000029,
142 0x00000002, 0x00040020, 0x0000002c, 0x00000007, 0x00000019, 0x0003002a, 0x00000019, 0x0000002e, 0x0004002b, 0x00000014,
143 0x00000036, 0x00000006, 0x0004002b, 0x00000014, 0x0000003b, 0x00000007, 0x0004002b, 0x00000006, 0x0000003c, 0x00000002,
144 0x0004002b, 0x00000006, 0x00000048, 0x00000001, 0x00030029, 0x00000019, 0x00000050, 0x0004002b, 0x00000014, 0x00000058,
145 0x00000003, 0x0004002b, 0x00000014, 0x0000005d, 0x00000004, 0x0004002b, 0x00000014, 0x00000060, 0x00000005, 0x00050036,
146 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007,
147 0x0004003b, 0x00000007, 0x0000001b, 0x00000007, 0x0004003b, 0x00000007, 0x00000027, 0x00000007, 0x0004003b, 0x0000002c,
148 0x0000002d, 0x00000007, 0x0004003b, 0x00000007, 0x0000002f, 0x00000007, 0x0003003e, 0x00000008, 0x00000009, 0x000200f9,
149 0x0000000a, 0x000200f8, 0x0000000a, 0x000400f6, 0x0000000c, 0x0000000d, 0x00000000, 0x000200f9, 0x0000000e, 0x000200f8,
150 0x0000000e, 0x0004003d, 0x00000006, 0x0000000f, 0x00000008, 0x00050041, 0x00000016, 0x00000017, 0x00000013, 0x00000015,
151 0x0004003d, 0x00000006, 0x00000018, 0x00000017, 0x000500b0, 0x00000019, 0x0000001a, 0x0000000f, 0x00000018, 0x000400fa,
152 0x0000001a, 0x0000000b, 0x0000000c, 0x000200f8, 0x0000000b, 0x0004003d, 0x00000006, 0x00000023, 0x00000008, 0x00070041,
153 0x00000016, 0x00000025, 0x00000022, 0x00000015, 0x00000023, 0x00000024, 0x0004003d, 0x00000006, 0x00000026, 0x00000025,
154 0x0003003e, 0x0000001b, 0x00000026, 0x0004003d, 0x00000006, 0x00000028, 0x00000008, 0x00070041, 0x00000016, 0x0000002a,
155 0x00000022, 0x00000015, 0x00000028, 0x00000029, 0x0004003d, 0x00000006, 0x0000002b, 0x0000002a, 0x0003003e, 0x00000027,
156 0x0000002b, 0x0003003e, 0x0000002d, 0x0000002e, 0x0003003e, 0x0000002f, 0x00000009, 0x000200f9, 0x00000030, 0x000200f8,
157 0x00000030, 0x000400f6, 0x00000032, 0x00000033, 0x00000000, 0x000200f9, 0x00000034, 0x000200f8, 0x00000034, 0x0004003d,
158 0x00000006, 0x00000035, 0x0000002f, 0x00050041, 0x00000016, 0x00000037, 0x00000013, 0x00000036, 0x0004003d, 0x00000006,
159 0x00000038, 0x00000037, 0x000500b0, 0x00000019, 0x00000039, 0x00000035, 0x00000038, 0x000400fa, 0x00000039, 0x00000031,
160 0x00000032, 0x000200f8, 0x00000031, 0x0004003d, 0x00000006, 0x0000003a, 0x0000001b, 0x0004003d, 0x00000006, 0x0000003d,
161 0x0000002f, 0x00050084, 0x00000006, 0x0000003e, 0x0000003c, 0x0000003d, 0x00050080, 0x00000006, 0x0000003f, 0x0000003e,
162 0x00000009, 0x00060041, 0x00000016, 0x00000040, 0x00000013, 0x0000003b, 0x0000003f, 0x0004003d, 0x00000006, 0x00000041,
163 0x00000040, 0x000500aa, 0x00000019, 0x00000042, 0x0000003a, 0x00000041, 0x000300f7, 0x00000044, 0x00000000, 0x000400fa,
164 0x00000042, 0x00000043, 0x00000044, 0x000200f8, 0x00000043, 0x0004003d, 0x00000006, 0x00000045, 0x00000027, 0x0004003d,
165 0x00000006, 0x00000046, 0x0000002f, 0x00050084, 0x00000006, 0x00000047, 0x0000003c, 0x00000046, 0x00050080, 0x00000006,
166 0x00000049, 0x00000047, 0x00000048, 0x00060041, 0x00000016, 0x0000004a, 0x00000013, 0x0000003b, 0x00000049, 0x0004003d,
167 0x00000006, 0x0000004b, 0x0000004a, 0x000500aa, 0x00000019, 0x0000004c, 0x00000045, 0x0000004b, 0x000200f9, 0x00000044,
168 0x000200f8, 0x00000044, 0x000700f5, 0x00000019, 0x0000004d, 0x00000042, 0x00000031, 0x0000004c, 0x00000043, 0x000300f7,
169 0x0000004f, 0x00000000, 0x000400fa, 0x0000004d, 0x0000004e, 0x0000004f, 0x000200f8, 0x0000004e, 0x0003003e, 0x0000002d,
170 0x00000050, 0x000200f9, 0x00000032, 0x000200f8, 0x0000004f, 0x000200f9, 0x00000033, 0x000200f8, 0x00000033, 0x0004003d,
171 0x00000006, 0x00000052, 0x0000002f, 0x00050080, 0x00000006, 0x00000053, 0x00000052, 0x00000024, 0x0003003e, 0x0000002f,
172 0x00000053, 0x000200f9, 0x00000030, 0x000200f8, 0x00000032, 0x0004003d, 0x00000019, 0x00000054, 0x0000002d, 0x000400a8,
173 0x00000019, 0x00000055, 0x00000054, 0x000300f7, 0x00000057, 0x00000000, 0x000400fa, 0x00000055, 0x00000056, 0x00000057,
174 0x000200f8, 0x00000056, 0x00050041, 0x00000016, 0x00000059, 0x00000013, 0x00000058, 0x0004003d, 0x00000006, 0x0000005a,
175 0x00000059, 0x00050080, 0x00000006, 0x0000005b, 0x0000005a, 0x00000048, 0x00050041, 0x00000016, 0x0000005c, 0x00000013,
176 0x00000058, 0x0003003e, 0x0000005c, 0x0000005b, 0x0004003d, 0x00000006, 0x0000005e, 0x0000001b, 0x00050041, 0x00000016,
177 0x0000005f, 0x00000013, 0x0000005d, 0x0003003e, 0x0000005f, 0x0000005e, 0x0004003d, 0x00000006, 0x00000061, 0x00000027,
178 0x00050041, 0x00000016, 0x00000062, 0x00000013, 0x00000060, 0x0003003e, 0x00000062, 0x00000061, 0x0004003d, 0x00000006,
179 0x00000063, 0x00000008, 0x00050041, 0x00000016, 0x00000064, 0x00000013, 0x00000024, 0x0004003d, 0x00000006, 0x00000065,
180 0x00000064, 0x00070041, 0x00000016, 0x00000066, 0x00000022, 0x00000015, 0x00000063, 0x00000024, 0x0003003e, 0x00000066,
181 0x00000065, 0x0004003d, 0x00000006, 0x00000067, 0x00000008, 0x00050041, 0x00000016, 0x00000068, 0x00000013, 0x00000029,
182 0x0004003d, 0x00000006, 0x00000069, 0x00000068, 0x00070041, 0x00000016, 0x0000006a, 0x00000022, 0x00000015, 0x00000067,
183 0x00000029, 0x0003003e, 0x0000006a, 0x00000069, 0x000200f9, 0x00000057, 0x000200f8, 0x00000057, 0x000200f9, 0x0000000d,
184 0x000200f8, 0x0000000d, 0x0004003d, 0x00000006, 0x0000006b, 0x00000008, 0x00050080, 0x00000006, 0x0000006c, 0x0000006b,
185 0x00000024, 0x0003003e, 0x00000008, 0x0000006c, 0x000200f9, 0x0000000a, 0x000200f8, 0x0000000c, 0x000100fd, 0x00010038};
186
Karl Schultz7b024b42018-08-30 16:18:18 -0600187// Convenience function for reporting problems with setting up GPU Validation.
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700188template <typename T>
189void GpuAssisted::ReportSetupProblem(T object, const char *const specific_message) const {
190 LogError(object, "UNASSIGNED-GPU-Assisted Validation Error. ", "Detail: (%s)", specific_message);
Karl Schultz7b024b42018-08-30 16:18:18 -0600191}
192
Tony-LunarG5c38b182020-06-10 16:15:32 -0600193bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
194 bool result =
195 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
196 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
197 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
198 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
199 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
200 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
201 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
202 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
203 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
204 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
205 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
206 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
207 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
208 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
209 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
210 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
211 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
212 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
213 enabled_features.core12.descriptorBindingPartiallyBound ||
214 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
215 return result;
216}
217
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600218void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
219 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700220 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
221 // acceleration structure build validation will find and replace invalid acceleration structure
222 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600223 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
224 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
225 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700226 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600227
228 // Validating DrawIndirectCount countBuffer will require validation shader to bind the count buffer as a storage buffer
Tony-LunarG3723a3a2021-05-04 14:52:39 -0600229 if (validate_draw_indirect && cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600230 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
231 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600232 ValidationStateTracker::PreCallRecordCreateBuffer(device, pCreateInfo, pAllocator, pBuffer, cb_state_data);
Jason Macnak83cfd582019-07-31 10:14:24 -0700233}
234
Karl Schultz7b024b42018-08-30 16:18:18 -0600235// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600236void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
237 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600238 void *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600239 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600240 VkPhysicalDeviceFeatures features = {};
241 features.vertexPipelineStoresAndAtomics = true;
242 features.fragmentStoresAndAtomics = true;
243 features.shaderInt64 = true;
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600244 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), supported_features,
245 features);
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600246 ValidationStateTracker::PreCallRecordCreateDevice(gpu, create_info, pAllocator, pDevice, modified_create_info);
Karl Schultz7b024b42018-08-30 16:18:18 -0600247}
Karl Schultz7b024b42018-08-30 16:18:18 -0600248// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600249void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
250 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
251 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600252 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600253
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600254 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
255 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
256 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700257
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600258 if (device_gpu_assisted->enabled_features.core.robustBufferAccess ||
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700259 device_gpu_assisted->enabled_features.robustness2_features.robustBufferAccess2) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600260 device_gpu_assisted->buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700261 } else {
Tony-LunarGc99dbef2021-06-14 15:11:50 -0600262 std::string bufferoob_string = getLayerOption("khronos_validation.gpuav_buffer_oob");
263 transform(bufferoob_string.begin(), bufferoob_string.end(), bufferoob_string.begin(), ::tolower);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600264 device_gpu_assisted->buffer_oob_enabled = !bufferoob_string.empty() ? !bufferoob_string.compare("true") : true;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700265 }
Tony-LunarGaef435b2021-10-14 14:49:06 -0600266 std::string descriptor_indexing_string = getLayerOption("khronos_validation.gpuav_descriptor_indexing");
267 transform(descriptor_indexing_string.begin(), descriptor_indexing_string.end(), descriptor_indexing_string.begin(), ::tolower);
268 bool validate_descriptor_indexing = !descriptor_indexing_string.empty() ? !descriptor_indexing_string.compare("true") : true;
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600269
Tony-LunarGc99dbef2021-06-14 15:11:50 -0600270 std::string draw_indirect_string = getLayerOption("khronos_validation.validate_draw_indirect");
271 transform(draw_indirect_string.begin(), draw_indirect_string.end(), draw_indirect_string.begin(), ::tolower);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600272 device_gpu_assisted->validate_draw_indirect = !draw_indirect_string.empty() ? !draw_indirect_string.compare("true") : true;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600273
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600274 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700275 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600276 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600277 return;
278 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600279
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600280 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700281 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600282 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
283 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600284 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600285 return;
286 }
287
sfricke-samsung45996a42021-09-16 13:45:27 -0700288 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
289 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600290 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700291 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
292 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600293 }
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600294 device_gpu_assisted->shaderInt64 = supported_features.shaderInt64;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600295 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600296 if (validate_descriptor_indexing) {
297 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
298 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600299 std::vector<VkDescriptorSetLayoutBinding> bindings;
300 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -0600301 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
302 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
303 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600304 NULL};
305 bindings.push_back(binding);
306 for (auto i = 1; i < 3; i++) {
307 binding.binding = i;
308 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600309 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700310 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Jeremy Gebben21782012022-03-15 16:23:27 -0600311 device_gpu_assisted->CreateAccelerationStructureBuildValidationState();
Karl Schultz7b024b42018-08-30 16:18:18 -0600312}
313
314// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600315void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600316 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700317 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600318 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600319 if (pre_draw_validation_state.globals_created) {
320 DispatchDestroyShaderModule(device, pre_draw_validation_state.validation_shader_module, nullptr);
321 DispatchDestroyDescriptorSetLayout(device, pre_draw_validation_state.validation_ds_layout, nullptr);
322 DispatchDestroyPipelineLayout(device, pre_draw_validation_state.validation_pipeline_layout, nullptr);
323 for (auto it = pre_draw_validation_state.renderpass_to_pipeline.begin();
324 it != pre_draw_validation_state.renderpass_to_pipeline.end(); ++it) {
325 DispatchDestroyPipeline(device, it->second, nullptr);
326 }
327 pre_draw_validation_state.renderpass_to_pipeline.clear();
328 pre_draw_validation_state.globals_created = false;
329 }
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600330 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
331 if (vmaAllocator) {
332 vmaDestroyAllocator(vmaAllocator);
333 }
334 desc_set_manager.reset();
Karl Schultz7b024b42018-08-30 16:18:18 -0600335}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600336
Jeremy Gebben21782012022-03-15 16:23:27 -0600337void GpuAssisted::CreateAccelerationStructureBuildValidationState() {
338 if (aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700339 return;
340 }
341
Jeremy Gebben21782012022-03-15 16:23:27 -0600342 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700343 if (as_validation_state.initialized) {
344 return;
345 }
346
sfricke-samsung45996a42021-09-16 13:45:27 -0700347 if (!IsExtEnabled(device_extensions.vk_nv_ray_tracing)) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700348 return;
349 }
350
351 // Outline:
352 // - Create valid bottom level acceleration structure which acts as replacement
353 // - Create and load vertex buffer
354 // - Create and load index buffer
355 // - Create, allocate memory for, and bind memory for acceleration structure
356 // - Query acceleration structure handle
357 // - Create command pool and command buffer
358 // - Record build acceleration structure command
359 // - Submit command buffer and wait for completion
360 // - Cleanup
361 // - Create compute pipeline for validating instance buffers
362 // - Create descriptor set layout
363 // - Create pipeline layout
364 // - Create pipeline
365 // - Cleanup
366
367 VkResult result = VK_SUCCESS;
368
369 VkBuffer vbo = VK_NULL_HANDLE;
370 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
371 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600372 auto vbo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700373 vbo_ci.size = sizeof(float) * 9;
374 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
375
376 VmaAllocationCreateInfo vbo_ai = {};
377 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
378 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
379
Jeremy Gebben21782012022-03-15 16:23:27 -0600380 result = vmaCreateBuffer(vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700381 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700382 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700383 }
384 }
385
386 if (result == VK_SUCCESS) {
387 uint8_t *mapped_vbo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600388 result = vmaMapMemory(vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700389 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700390 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700391 } else {
392 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
393 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600394 vmaUnmapMemory(vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700395 }
396 }
397
398 VkBuffer ibo = VK_NULL_HANDLE;
399 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
400 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600401 auto ibo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700402 ibo_ci.size = sizeof(uint32_t) * 3;
403 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
404
405 VmaAllocationCreateInfo ibo_ai = {};
406 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
407 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
408
Jeremy Gebben21782012022-03-15 16:23:27 -0600409 result = vmaCreateBuffer(vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700410 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700411 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700412 }
413 }
414
415 if (result == VK_SUCCESS) {
416 uint8_t *mapped_ibo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600417 result = vmaMapMemory(vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700418 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700419 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700420 } else {
421 const std::vector<uint32_t> indicies = {0, 1, 2};
422 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600423 vmaUnmapMemory(vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700424 }
425 }
426
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600427 auto geometry = LvlInitStruct<VkGeometryNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700428 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600429 geometry.geometry.triangles = LvlInitStruct<VkGeometryTrianglesNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700430 geometry.geometry.triangles.vertexData = vbo;
431 geometry.geometry.triangles.vertexOffset = 0;
432 geometry.geometry.triangles.vertexCount = 3;
433 geometry.geometry.triangles.vertexStride = 12;
434 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
435 geometry.geometry.triangles.indexData = ibo;
436 geometry.geometry.triangles.indexOffset = 0;
437 geometry.geometry.triangles.indexCount = 3;
438 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
439 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
440 geometry.geometry.triangles.transformOffset = 0;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600441 geometry.geometry.aabbs = LvlInitStruct<VkGeometryAABBNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700442
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600443 auto as_ci = LvlInitStruct<VkAccelerationStructureCreateInfoNV>();
444 as_ci.info = LvlInitStruct<VkAccelerationStructureInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700445 as_ci.info.instanceCount = 0;
446 as_ci.info.geometryCount = 1;
447 as_ci.info.pGeometries = &geometry;
448 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600449 result = DispatchCreateAccelerationStructureNV(device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700450 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600451 ReportSetupProblem(device, "Failed to create acceleration structure for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700452 }
453 }
454
455 VkMemoryRequirements2 as_mem_requirements = {};
456 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600457 auto as_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700458 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
459 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
460
Jeremy Gebben21782012022-03-15 16:23:27 -0600461 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700462 }
463
464 VmaAllocationInfo as_memory_ai = {};
465 if (result == VK_SUCCESS) {
466 VmaAllocationCreateInfo as_memory_aci = {};
467 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
468
Jeremy Gebben21782012022-03-15 16:23:27 -0600469 result = vmaAllocateMemory(vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
Tony-LunarG99b880b2019-09-26 11:19:52 -0600470 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700471 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600472 ReportSetupProblem(device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700473 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
474 }
475 }
476
477 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600478 auto as_bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700479 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
480 as_bind_info.memory = as_memory_ai.deviceMemory;
481 as_bind_info.memoryOffset = as_memory_ai.offset;
482
Jeremy Gebben21782012022-03-15 16:23:27 -0600483 result = DispatchBindAccelerationStructureMemoryNV(device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700484 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600485 ReportSetupProblem(device, "Failed to bind acceleration structure memory for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700486 }
487 }
488
489 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600490 result = DispatchGetAccelerationStructureHandleNV(device, as_validation_state.replacement_as, sizeof(uint64_t),
491 &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700492 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600493 ReportSetupProblem(device, "Failed to get acceleration structure handle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700494 }
495 }
496
497 VkMemoryRequirements2 scratch_mem_requirements = {};
498 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600499 auto scratch_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700500 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
501 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
502
Jeremy Gebben21782012022-03-15 16:23:27 -0600503 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_mem_requirements_info, &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700504 }
505
506 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600507 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700508 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600509 auto scratch_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700510 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
511 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700512 VmaAllocationCreateInfo scratch_aci = {};
513 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
514
Jeremy Gebben21782012022-03-15 16:23:27 -0600515 result = vmaCreateBuffer(vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700516 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600517 ReportSetupProblem(device, "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700518 }
519 }
520
521 VkCommandPool command_pool = VK_NULL_HANDLE;
522 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600523 auto command_pool_ci = LvlInitStruct<VkCommandPoolCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700524 command_pool_ci.queueFamilyIndex = 0;
525
Jeremy Gebben21782012022-03-15 16:23:27 -0600526 result = DispatchCreateCommandPool(device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700527 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600528 ReportSetupProblem(device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700529 }
530 }
531
532 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
533
534 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600535 auto command_buffer_ai = LvlInitStruct<VkCommandBufferAllocateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700536 command_buffer_ai.commandPool = command_pool;
537 command_buffer_ai.commandBufferCount = 1;
538 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
539
Jeremy Gebben21782012022-03-15 16:23:27 -0600540 result = DispatchAllocateCommandBuffers(device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700541 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600542 ReportSetupProblem(device, "Failed to create command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700543 }
544
545 // Hook up command buffer dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600546 vkSetDeviceLoaderData(device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700547 }
548
549 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600550 auto command_buffer_bi = LvlInitStruct<VkCommandBufferBeginInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700551
552 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
553 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600554 ReportSetupProblem(device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700555 }
556 }
557
558 if (result == VK_SUCCESS) {
559 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
560 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
561 DispatchEndCommandBuffer(command_buffer);
562 }
563
564 VkQueue queue = VK_NULL_HANDLE;
565 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600566 DispatchGetDeviceQueue(device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700567
568 // Hook up queue dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600569 vkSetDeviceLoaderData(device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700570
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600571 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700572 submit_info.commandBufferCount = 1;
573 submit_info.pCommandBuffers = &command_buffer;
574 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
575 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600576 ReportSetupProblem(device, "Failed to submit command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700577 }
578 }
579
580 if (result == VK_SUCCESS) {
581 result = DispatchQueueWaitIdle(queue);
582 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600583 ReportSetupProblem(device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700584 }
585 }
586
587 if (vbo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600588 vmaDestroyBuffer(vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700589 }
590 if (ibo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600591 vmaDestroyBuffer(vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700592 }
593 if (scratch != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600594 vmaDestroyBuffer(vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700595 }
596 if (command_pool != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600597 DispatchDestroyCommandPool(device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700598 }
599
Jeremy Gebben21782012022-03-15 16:23:27 -0600600 if (debug_desc_layout == VK_NULL_HANDLE) {
601 ReportSetupProblem(device, "Failed to find descriptor set layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700602 result = VK_INCOMPLETE;
603 }
604
605 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600606 auto pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700607 pipeline_layout_ci.setLayoutCount = 1;
Jeremy Gebben21782012022-03-15 16:23:27 -0600608 pipeline_layout_ci.pSetLayouts = &debug_desc_layout;
609 result = DispatchCreatePipelineLayout(device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700610 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600611 ReportSetupProblem(device, "Failed to create pipeline layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700612 }
613 }
614
615 VkShaderModule shader_module = VK_NULL_HANDLE;
616 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600617 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700618 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
619 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
620
Jeremy Gebben21782012022-03-15 16:23:27 -0600621 result = DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700622 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600623 ReportSetupProblem(device, "Failed to create compute shader module for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700624 }
625 }
626
627 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600628 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700629 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
630 pipeline_stage_ci.module = shader_module;
631 pipeline_stage_ci.pName = "main";
632
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600633 auto pipeline_ci = LvlInitStruct<VkComputePipelineCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700634 pipeline_ci.stage = pipeline_stage_ci;
635 pipeline_ci.layout = as_validation_state.pipeline_layout;
636
Jeremy Gebben21782012022-03-15 16:23:27 -0600637 result = DispatchCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr, &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700638 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600639 ReportSetupProblem(device, "Failed to create compute pipeline for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700640 }
641 }
642
643 if (shader_module != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600644 DispatchDestroyShaderModule(device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700645 }
646
647 if (result == VK_SUCCESS) {
648 as_validation_state.initialized = true;
Jeremy Gebben21782012022-03-15 16:23:27 -0600649 LogInfo(device, "UNASSIGNED-GPU-Assisted Validation.", "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700650 } else {
Jeremy Gebben21782012022-03-15 16:23:27 -0600651 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700652 }
653}
654
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600655void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600656 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700657 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
658 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
659 }
660 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
661 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
662 }
663 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
664 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
665 }
666 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600667 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700668 }
669}
670
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600671struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700672 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
673 VkPipeline pipeline = VK_NULL_HANDLE;
674 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
675 std::vector<VkDescriptorSet> descriptor_sets;
676 std::vector<std::vector<uint32_t>> dynamic_offsets;
677 uint32_t push_descriptor_set_index = 0;
678 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
679 std::vector<uint8_t> push_constants_data;
680 PushConstantRangesId push_constants_ranges;
681
682 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
683 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600684 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700685
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600686 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700687 if (last_bound.pipeline_state) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600688 pipeline = last_bound.pipeline_state->pipeline();
Jason Macnak83cfd582019-07-31 10:14:24 -0700689 pipeline_layout = last_bound.pipeline_layout;
690 descriptor_sets.reserve(last_bound.per_set.size());
691 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700692 const auto &bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
ziga-lunarge0b552b2021-09-05 21:39:57 +0200693 if (bound_descriptor_set) {
694 descriptor_sets.push_back(bound_descriptor_set->GetSet());
695 if (bound_descriptor_set->IsPushDescriptor()) {
696 push_descriptor_set_index = static_cast<uint32_t>(i);
697 }
698 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
Jason Macnak83cfd582019-07-31 10:14:24 -0700699 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700700 }
701
702 if (last_bound.push_descriptor_set) {
703 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
704 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500705 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700706 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500707 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700708 }
709 }
710 }
711
712 void Restore(VkCommandBuffer command_buffer) const {
713 if (pipeline != VK_NULL_HANDLE) {
714 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
715 if (!descriptor_sets.empty()) {
716 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
717 VkDescriptorSet descriptor_set = descriptor_sets[i];
718 if (descriptor_set != VK_NULL_HANDLE) {
719 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
720 static_cast<uint32_t>(i), 1, &descriptor_set,
721 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
722 }
723 }
724 }
725 if (!push_descriptor_set_writes.empty()) {
726 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
727 static_cast<uint32_t>(push_descriptor_set_writes.size()),
728 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
729 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600730 if (!push_constants_data.empty()) {
731 for (const auto &push_constant_range : *push_constants_ranges) {
732 if (push_constant_range.size == 0) continue;
733 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
734 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
735 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700736 }
737 }
738 }
739};
740
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600741void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
742 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
743 VkDeviceSize instanceOffset, VkBool32 update,
744 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
745 VkBuffer scratch, VkDeviceSize scratchOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600746 ValidationStateTracker::PreCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update,
747 dst, src, scratch, scratchOffset);
Jason Macnak83cfd582019-07-31 10:14:24 -0700748 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
749 return;
750 }
751
Tony-LunarG99b880b2019-09-26 11:19:52 -0600752 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700753 if (!as_validation_state.initialized) {
754 return;
755 }
756
757 // Empty acceleration structure is valid according to the spec.
758 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
759 return;
760 }
761
Jeremy Gebben135550d2022-03-21 07:15:07 -0600762 auto cb_state = Get<gpuav_state::CommandBuffer>(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700763 assert(cb_state != nullptr);
764
765 std::vector<uint64_t> current_valid_handles;
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600766 ForEach<ACCELERATION_STRUCTURE_STATE>([&current_valid_handles](const ACCELERATION_STRUCTURE_STATE &as_state) {
Jeff Bolz95176d02020-04-01 00:36:16 -0500767 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700768 current_valid_handles.push_back(as_state.opaque_handle);
769 }
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600770 });
Jason Macnak83cfd582019-07-31 10:14:24 -0700771
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600772 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700773 as_validation_buffer_info.acceleration_structure = dst;
774
775 const VkDeviceSize validation_buffer_size =
776 // One uint for number of instances to validate
777 4 +
778 // Two uint for the replacement acceleration structure handle
779 8 +
780 // One uint for number of invalid handles found
781 4 +
782 // Two uint for the first invalid handle found
783 8 +
784 // One uint for the number of current valid handles
785 4 +
786 // Two uint for each current valid handle
787 (8 * current_valid_handles.size());
788
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600789 auto validation_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700790 validation_buffer_create_info.size = validation_buffer_size;
791 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
792
793 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
794 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
795
Tony-LunarG99b880b2019-09-26 11:19:52 -0600796 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
797 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700798 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
799 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700800 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600801 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700802 return;
803 }
804
805 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700806 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
807 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700808 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700809 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600810 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700811 return;
812 }
813
814 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
815 mapped_validation_buffer->replacement_handle_bits_0 =
816 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
817 mapped_validation_buffer->replacement_handle_bits_1 =
818 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
819 mapped_validation_buffer->invalid_handle_found = 0;
820 mapped_validation_buffer->invalid_handle_bits_0 = 0;
821 mapped_validation_buffer->invalid_handle_bits_1 = 0;
822 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
823
824 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
825 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
826 const uint64_t current_valid_handle = current_valid_handles[i];
827
828 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
829 ++mapped_valid_handles;
830 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
831 ++mapped_valid_handles;
832 }
833
Tony-LunarG99b880b2019-09-26 11:19:52 -0600834 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700835
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700836 static constexpr const VkDeviceSize k_instance_size = 64;
837 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700838
Tony-LunarG1dce2392019-10-23 16:49:29 -0600839 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
840 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700841 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700842 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600843 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700844 return;
845 }
846
847 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
848 descriptor_buffer_infos[0].buffer = instanceData;
849 descriptor_buffer_infos[0].offset = instanceOffset;
850 descriptor_buffer_infos[0].range = instance_buffer_size;
851 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
852 descriptor_buffer_infos[1].offset = 0;
853 descriptor_buffer_infos[1].range = validation_buffer_size;
854
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600855 VkWriteDescriptorSet descriptor_set_writes[2] = {
856 LvlInitStruct<VkWriteDescriptorSet>(),
857 LvlInitStruct<VkWriteDescriptorSet>(),
858 };
Jason Macnak83cfd582019-07-31 10:14:24 -0700859 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
860 descriptor_set_writes[0].dstBinding = 0;
861 descriptor_set_writes[0].descriptorCount = 1;
862 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
863 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
Jason Macnak83cfd582019-07-31 10:14:24 -0700864 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
865 descriptor_set_writes[1].dstBinding = 1;
866 descriptor_set_writes[1].descriptorCount = 1;
867 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
868 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
869
870 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
871
872 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600873 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700874 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
875 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
876 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
877 &memory_barrier, 0, nullptr, 0, nullptr);
878
879 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600880 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -0600881 restorable_state.Create(cb_state.get(), VK_PIPELINE_BIND_POINT_COMPUTE);
Jason Macnak83cfd582019-07-31 10:14:24 -0700882
883 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
884 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
885 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
886 &as_validation_buffer_info.descriptor_set, 0, nullptr);
887 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
888
889 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
890 // have been replaced by the validation compute shader before any builds take place.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600891 auto instance_buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700892 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
893 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
894 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
895 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
896 instance_buffer_barrier.buffer = instanceData;
897 instance_buffer_barrier.offset = instanceOffset;
898 instance_buffer_barrier.size = instance_buffer_size;
899 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
900 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
901 nullptr);
902
903 // Restore the previous compute pipeline state.
904 restorable_state.Restore(commandBuffer);
905
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600906 cb_state->as_validation_buffers.emplace_back(std::move(as_validation_buffer_info));
Jason Macnak83cfd582019-07-31 10:14:24 -0700907}
908
Jeremy Gebben135550d2022-03-21 07:15:07 -0600909void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, gpuav_state::CommandBuffer *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700910 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
911 return;
912 }
913
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600914 for (const auto &as_validation_buffer_info : cb_node->as_validation_buffers) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700915 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
916
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700917 VkResult result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
918 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700919 if (result == VK_SUCCESS) {
920 if (mapped_validation_buffer->invalid_handle_found > 0) {
921 uint64_t invalid_handle = 0;
922 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
923 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
924
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700925 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
926 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
927 "handle (%" PRIu64 ")",
928 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700929 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600930 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700931 }
932 }
933}
934
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600935void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
936 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
937 VkResult result) {
938 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600939 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600940 for (uint32_t i = 0; i < bindInfoCount; i++) {
941 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600942 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600943 if (as_state) {
944 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
945 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600946 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600947}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700948
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600949// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
950void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
951 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
952 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600953 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600954 return;
955 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600956
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600957 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
958
Tony-LunarG99b880b2019-09-26 11:19:52 -0600959 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600960 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600961 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600962 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
963 << "Validation is not modifying the pipeline layout. "
964 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700965 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600966 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -0700967 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -0600968 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600969 ValidationStateTracker::PreCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, cpl_state_data);
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700970}
971
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600972void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
973 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
974 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600975 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
976
Karl Schultz7b024b42018-08-30 16:18:18 -0600977 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700978 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600979 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600980 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600981}
982
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600983// Free the device memory and descriptor set(s) associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600984void GpuAssisted::DestroyBuffer(GpuAssistedBufferInfo &buffer_info) {
985 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
986 if (buffer_info.di_input_mem_block.buffer) {
987 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600988 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600989 if (buffer_info.bda_input_mem_block.buffer) {
990 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600991 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600992 if (buffer_info.desc_set != VK_NULL_HANDLE) {
993 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700994 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600995 if (buffer_info.pre_draw_resources.desc_set != VK_NULL_HANDLE) {
996 desc_set_manager->PutBackDescriptorSet(buffer_info.pre_draw_resources.desc_pool, buffer_info.pre_draw_resources.desc_set);
997 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600998}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600999
1000void GpuAssisted::DestroyBuffer(GpuAssistedAccelerationStructureBuildValidationBufferInfo &as_validation_buffer_info) {
1001 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
1002 as_validation_buffer_info.validation_buffer_allocation);
1003
1004 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
1005 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool, as_validation_buffer_info.descriptor_set);
1006 }
1007}
1008
Karl Schultz7b024b42018-08-30 16:18:18 -06001009// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001010bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1011 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1012 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1013 uint32_t bufferMemoryBarrierCount,
1014 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001015 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001016 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001017 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001018 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001019 "GPU-Assisted validation waits on queue completion. "
Karl Schultz7b024b42018-08-30 16:18:18 -06001020 "This wait could block the host's signaling of this event, resulting in deadlock.");
1021 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001022 ValidationStateTracker::PreCallValidateCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask,
1023 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1024 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001025 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001026}
1027
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001028bool GpuAssisted::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1029 const VkDependencyInfoKHR *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001030 VkPipelineStageFlags2KHR src_stage_mask = 0;
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001031
1032 for (uint32_t i = 0; i < eventCount; i++) {
1033 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001034 src_stage_mask |= stage_masks.src;
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001035 }
1036
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001037 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001038 ReportSetupProblem(commandBuffer,
1039 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001040 "GPU-Assisted validation waits on queue completion. "
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001041 "This wait could block the host's signaling of this event, resulting in deadlock.");
1042 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001043 ValidationStateTracker::PreCallValidateCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001044 return false;
1045}
1046
Tony-LunarG1364cf52021-11-17 16:10:11 -07001047bool GpuAssisted::PreCallValidateCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1048 const VkDependencyInfo *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001049 VkPipelineStageFlags2 src_stage_mask = 0;
Tony-LunarG1364cf52021-11-17 16:10:11 -07001050
1051 for (uint32_t i = 0; i < eventCount; i++) {
1052 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001053 src_stage_mask |= stage_masks.src;
Tony-LunarG1364cf52021-11-17 16:10:11 -07001054 }
1055
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001056 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1364cf52021-11-17 16:10:11 -07001057 ReportSetupProblem(commandBuffer,
1058 "CmdWaitEvents2 recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001059 "GPU-Assisted validation waits on queue completion. "
Tony-LunarG1364cf52021-11-17 16:10:11 -07001060 "This wait could block the host's signaling of this event, resulting in deadlock.");
1061 }
1062 ValidationStateTracker::PreCallValidateCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
1063 return false;
1064}
1065
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001066void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1067 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1068 // 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 -06001069 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001070 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1071 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1072 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001073 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1074 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001075 }
1076 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001077 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pPhysicalDeviceProperties);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001078}
1079
1080void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1081 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1082 // 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 -06001083 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001084 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1085 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1086 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001087 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1088 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001089 }
1090 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001091 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pPhysicalDeviceProperties2);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001092}
1093
1094void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1095 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1096 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1097 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001098 if (aborted) return;
Karl Schultz7b024b42018-08-30 16:18:18 -06001099 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001100 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001101 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1102 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001103 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1104 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001105 ValidationStateTracker::PreCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1106 cgpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001107}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001108
1109void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1110 const VkComputePipelineCreateInfo *pCreateInfos,
1111 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1112 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001113 if (aborted) return;
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001114 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001115 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001116 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1117 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001118 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1119 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001120 ValidationStateTracker::PreCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1121 ccpl_state_data);
Jason Macnak67407e72019-07-11 11:05:09 -07001122}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001123
1124void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1125 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1126 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1127 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001128 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001129 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001130 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001131 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1132 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001133 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1134 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001135 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1136 pPipelines, crtpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001137}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001138
sourav parmarcd5fb182020-07-17 12:58:44 -07001139void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1140 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001141 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1142 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1143 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001144 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001145 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1146 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001147 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1148 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001149 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1150 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001151 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesKHR(device, deferredOperation, pipelineCache, count, pCreateInfos,
1152 pAllocator, pPipelines, crtpl_state_data);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001153}
Karl Schultz7b024b42018-08-30 16:18:18 -06001154
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001155void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1156 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1157 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1158 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001159 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1160 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001161 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001162 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
1163 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001164 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001165}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001166
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001167void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1168 const VkComputePipelineCreateInfo *pCreateInfos,
1169 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1170 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001171 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1172 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001173 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001174 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
1175 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001176 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001177}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001178
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001179void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1180 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1181 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1182 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001183 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001184 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1185 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001186 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001187 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001188 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001189}
1190
sourav parmarcd5fb182020-07-17 12:58:44 -07001191void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1192 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001193 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1194 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1195 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001196 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
sourav parmarcd5fb182020-07-17 12:58:44 -07001197 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
1198 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001199 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001200 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001201 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001202}
1203
1204// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001205void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001206 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001207 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001208 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001209 } else {
1210 ++it;
1211 }
1212 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001213 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001214}
1215
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001216void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1217 const VkAllocationCallbacks *pAllocator) {
1218 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(renderPass);
1219 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1220 DispatchDestroyPipeline(device, pipeline->second, nullptr);
1221 pre_draw_validation_state.renderpass_to_pipeline.erase(pipeline);
1222 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001223 ValidationStateTracker::PreCallRecordDestroyRenderPass(device, renderPass, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001224}
1225
Karl Schultz7b024b42018-08-30 16:18:18 -06001226// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001227bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001228 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001229 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001230 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1231
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001232 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001233 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1234 switch (level) {
1235 case SPV_MSG_FATAL:
1236 case SPV_MSG_INTERNAL_ERROR:
1237 case SPV_MSG_ERROR:
1238 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1239 position.index, message);
1240 break;
1241 default:
1242 break;
1243 }
1244 };
1245
Karl Schultz7b024b42018-08-30 16:18:18 -06001246 // Load original shader SPIR-V
1247 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1248 new_pgm.clear();
1249 new_pgm.reserve(num_words);
1250 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1251
1252 // Call the optimizer to instrument the shader.
1253 // 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 -07001254 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001255 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -07001256 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001257 spvtools::ValidatorOptions val_options;
1258 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1259 spvtools::OptimizerOptions opt_options;
1260 opt_options.set_run_validator(true);
1261 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001262 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001263 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001264 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001265 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Tony-LunarG57400d42021-10-14 11:18:43 -06001266 // Call CreateAggressiveDCEPass with preserve_interface == true
1267 optimizer.RegisterPass(CreateAggressiveDCEPass(true));
sfricke-samsung45996a42021-09-16 13:45:27 -07001268 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
1269 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
1270 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001271 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001272 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001273 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001274 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001275 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001276 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001277 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001278 return pass;
1279}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001280// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001281void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1282 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1283 void *csm_state_data) {
1284 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1285 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001286 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001287 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001288 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Karl Schultz7b024b42018-08-30 16:18:18 -06001289 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001290 ValidationStateTracker::PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, csm_state_data);
Karl Schultz7b024b42018-08-30 16:18:18 -06001291}
Tony-LunarG20678ff2021-05-07 14:56:26 -06001292
Tony-LunarG7345a062021-06-24 13:16:38 -06001293static const int kInstErrorPreDrawValidate = spvtools::kInstErrorMax + 1;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001294static const int kPreDrawValidateSubError = spvtools::kInstValidationOutError + 1;
Karl Schultz7b024b42018-08-30 16:18:18 -06001295// Generate the part of the message describing the violation.
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001296bool GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg, GpuAssistedBufferInfo buf_info, GpuAssisted *gpu_assisted) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001297 using namespace spvtools;
1298 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001299 bool return_code = true;
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001300 assert(kInstErrorPreDrawValidate == _kInstErrorPreDrawValidate);
1301 assert(kInstValidationOutError == _kInstValidationOutError);
Tony-LunarGab47cac2019-12-20 15:28:01 -07001302 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001303 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001304 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1305 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001306 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001307 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001308 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001309 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001310 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001311 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001312 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001313 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001314 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1315 vuid_msg = "UNASSIGNED-Device address out of bounds";
1316 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001317 case kInstErrorBuffOOBUniform:
1318 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001319 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1320 if (size == 0) {
1321 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1322 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1323 } else {
1324 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1325 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001326 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001327 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001328 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1329 vuid_msg = vuid.uniform_access_oob;
1330 else
1331 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001332 }
1333 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001334 case kInstErrorBuffOOBUniformTexel:
1335 case kInstErrorBuffOOBStorageTexel: {
1336 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1337 if (size == 0) {
1338 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1339 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001340 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001341 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001342 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1343 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001344 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001345 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1346 vuid_msg = vuid.uniform_access_oob;
1347 else
1348 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001349 }
Tony-LunarG63f82e02021-04-12 16:13:48 -06001350 } break;
1351 case kInstErrorPreDrawValidate: {
Tim Van Patten38bdcdd2021-05-14 16:41:00 -06001352 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001353 if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_bufsize_error) {
Tony-LunarG63f82e02021-04-12 16:13:48 -06001354 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001355 uint32_t stride = buf_info.pre_draw_resources.stride;
1356 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
1357 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
1358 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1359 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
1360 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
1361 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001362 if (count == 1) {
1363 vuid_msg = vuid.count_exceeds_bufsize_1;
1364 } else {
1365 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001366 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001367 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_limit_error) {
1368 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
1369 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1370 strm << "Indirect draw count of " << count << " would exceed maxDrawIndirectCount limit of "
1371 << gpu_assisted->phys_dev_props.limits.maxDrawIndirectCount;
1372 vuid_msg = vuid.count_exceeds_device_limit;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001373 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_first_instance_error) {
1374 uint32_t index = debug_record[kPreDrawValidateSubError + 1];
1375 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1376 strm << "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the "
1377 "VkDrawIndirectCommand structure at index "
1378 << index << " is not zero";
1379 vuid_msg = vuid.first_instance_not_zero;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001380 }
1381 return_code = false;
1382 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001383 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001384 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001385 vuid_msg = "UNASSIGNED-Internal Error";
1386 assert(false);
1387 } break;
1388 }
1389 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001390 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001391}
1392
Karl Schultz7b024b42018-08-30 16:18:18 -06001393// Pull together all the information from the debug record to build the error message strings,
1394// and then assemble them into a single message string.
1395// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1396// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1397// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1398// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1399//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001400void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001401 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001402 using namespace spvtools;
1403 const uint32_t total_words = debug_output_buffer[0];
1404 // A zero here means that the shader instrumentation didn't write anything.
1405 // If you have nothing to say, don't say it here.
1406 if (0 == total_words) {
1407 return;
1408 }
1409 // The first word in the debug output buffer is the number of words that would have
1410 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1411 // The number of words actually written by the shaders is determined by the size of the buffer
1412 // we provide via the descriptor. So, we process only the number of words that can fit in the
1413 // buffer.
1414 // Each "report" written by the shader instrumentation is considered a "record". This function
1415 // is hard-coded to process only one record because it expects the buffer to be large enough to
1416 // hold only one record. If there is a desire to process more than one record, this function needs
1417 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001418 std::string validation_message;
1419 std::string stage_message;
1420 std::string common_message;
1421 std::string filename_message;
1422 std::string source_message;
1423 std::string vuid_msg;
1424 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1425 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001426 std::vector<uint32_t> pgm;
Karl Schultz7b024b42018-08-30 16:18:18 -06001427 // The first record starts at this offset after the total_words.
1428 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1429 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1430 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001431 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1432 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001433 shader_module_handle = it->second.shader_module;
1434 pipeline_handle = it->second.pipeline;
1435 pgm = it->second.pgm;
1436 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001437 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info, this);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001438 if (gen_full_message) {
1439 UtilGenerateStageMessage(debug_record, stage_message);
1440 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1441 buffer_info.pipeline_bind_point, operation_index, common_message);
1442 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1443 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1444 filename_message.c_str(), source_message.c_str());
1445 }
1446 else {
1447 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1448 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001449 // The debug record at word kInstCommonOutSize is the number of words in the record
1450 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001451 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001452 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1453}
1454
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001455void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1456 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1457 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001458 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001459 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001460 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001461 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1462 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1463 }
1464 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1465 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001466 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001467 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001468 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001469 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1470 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1471 }
ziga7a255fb2021-11-20 21:17:07 +01001472 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::Mutable) {
1473 if (descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1474 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1475 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1476 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
1477 const auto size = static_cast<const cvdescriptorset::MutableDescriptor *>(descriptor)->GetBufferSize();
1478 pData[index] = static_cast<uint32_t>(size);
1479 } else {
1480 pData[index] = 1;
1481 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001482 } else {
1483 pData[index] = 1;
1484 }
1485}
1486
Tony-LunarG81efe392019-03-07 15:43:27 -07001487// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Jeremy Gebben135550d2022-03-21 07:15:07 -06001488void GpuAssisted::UpdateInstrumentationBuffer(gpuav_state::CommandBuffer *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001489 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001490 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001491 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001492 VkResult result =
1493 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001494 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001495 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001496 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001497 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001498 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001499 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001500 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001501 }
1502 }
1503 }
1504}
1505
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001506void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06001507 auto cb_node = Get<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001508 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001509 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06001510 UpdateInstrumentationBuffer(static_cast<gpuav_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001511 }
1512}
1513
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001514void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001515 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001516 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1517 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1518 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001519 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001520 }
1521 }
1522}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001523
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001524void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1525 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001526 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001527 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1528 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1529 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1530 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1531 }
1532 }
1533}
1534
Tony-LunarG26fe2842021-11-16 14:07:59 -07001535void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1536 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1537 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1538 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1539 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1540 }
1541 }
1542}
1543
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001544bool GpuAssisted::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
1545 bool buffers_present = false;
Jeremy Gebben135550d2022-03-21 07:15:07 -06001546 auto cb_node = Get<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001547
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001548 if (cb_node->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001549 buffers_present = true;
1550 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001551 for (const auto *secondary : cb_node->linkedCommandBuffers) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06001552 auto secondary_cmd_buffer = static_cast<const gpuav_state::CommandBuffer *>(secondary);
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001553 if (secondary_cmd_buffer->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001554 buffers_present = true;
1555 }
1556 }
1557 return buffers_present;
1558}
1559
1560void GpuAssisted::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06001561 auto cb_node = Get<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001562
Jeremy Gebben9f537102021-10-05 16:37:12 -06001563 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
1564 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001565 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001566 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001567 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001568 }
1569}
Tony-LunarG81efe392019-03-07 15:43:27 -07001570
Karl Schultz58674242019-01-22 15:35:02 -07001571// Issue a memory barrier to make GPU-written data available to host.
1572// Wait for the queue to complete execution.
1573// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001574void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1575 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001576 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001577
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001578 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001579 bool buffers_present = false;
1580 // Don't QueueWaitIdle if there's nothing to process
1581 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1582 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1583 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001584 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001585 }
1586 }
1587 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001588
Tony-LunarGb5fae462020-03-05 12:43:25 -07001589 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001590
Tony-LunarG152a88b2019-03-20 15:42:24 -06001591 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001592
Karl Schultz7b024b42018-08-30 16:18:18 -06001593 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1594 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1595 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001596 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
1597 }
1598 }
1599}
1600
Tony-LunarG26fe2842021-11-16 14:07:59 -07001601void GpuAssisted::RecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits,
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001602 VkFence fence, VkResult result) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001603 if (aborted || (result != VK_SUCCESS)) return;
1604 bool buffers_present = false;
1605 // Don't QueueWaitIdle if there's nothing to process
1606 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001607 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001608 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1609 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
1610 }
1611 }
1612 if (!buffers_present) return;
1613
1614 UtilSubmitBarrier(queue, this);
1615
1616 DispatchQueueWaitIdle(queue);
1617
1618 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001619 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001620 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1621 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001622 }
1623 }
1624}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001625
Tony-LunarG26fe2842021-11-16 14:07:59 -07001626void GpuAssisted::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits,
1627 VkFence fence, VkResult result) {
1628 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
1629 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1630}
1631
1632void GpuAssisted::PostCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits,
1633 VkFence fence, VkResult result) {
1634 ValidationStateTracker::PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1635 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1636}
1637
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001638void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1639 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001640 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001641 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001642}
1643
Tony-LunarG745150c2021-07-02 15:07:31 -06001644void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1645 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1646 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001647 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1648 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001649 for (uint32_t i = 0; i < drawCount; i++) {
1650 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1651 }
1652}
1653
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001654void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1655 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001656 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1657 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001658 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001659}
1660
Tony-LunarG745150c2021-07-02 15:07:31 -06001661void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1662 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1663 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001664 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1665 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001666 for (uint32_t i = 0; i < drawCount; i++) {
1667 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1668 }
1669}
1670
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001671void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1672 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001673 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001674 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1675 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001676}
1677
1678void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1679 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001680 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001681 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1682 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001683}
1684
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001685void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1686 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1687 uint32_t stride) {
1688 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1689 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001690 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001691 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001692}
1693
1694void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1695 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001696
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001697 uint32_t stride) {
1698 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1699 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001700 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1701 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001702}
1703
Tony-LunarG54176fb2020-12-02 10:47:22 -07001704void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1705 uint32_t firstInstance, VkBuffer counterBuffer,
1706 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1707 uint32_t vertexStride) {
1708 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1709 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001710 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001711}
1712
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001713void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1714 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1715 uint32_t maxDrawCount, uint32_t stride) {
1716 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1717 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001718 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001719 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001720}
1721
1722void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1723 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1724 uint32_t maxDrawCount, uint32_t stride) {
1725 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1726 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001727 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1728 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001729}
1730
1731void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1732 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001733 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001734}
1735
1736void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1737 uint32_t drawCount, uint32_t stride) {
1738 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001739 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001740}
1741
1742void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1743 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1744 uint32_t maxDrawCount, uint32_t stride) {
1745 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1746 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001747 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001748}
1749
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001750void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001751 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001752 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001753}
1754
1755void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001756 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001757 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001758}
1759
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001760void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1761 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1762 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001763 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1764 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001765 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001766}
1767
Tony-LunarG52c8c602020-09-10 16:29:56 -06001768void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1769 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1770 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001771 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1772 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001773 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001774}
1775
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001776void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1777 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1778 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1779 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1780 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1781 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1782 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001783 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1784 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1785 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1786 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1787 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001788 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001789}
1790
1791void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1792 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1793 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1794 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1795 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1796 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1797 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001798 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1799 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1800 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1801 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1802 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001803 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001804 cb_state->hasTraceRaysCmd = true;
1805}
1806
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001807void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001808 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1809 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1810 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1811 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001812 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001813 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1814 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001815 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001816}
1817
1818void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001819 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1820 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1821 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1822 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001823 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001824 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1825 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1826 depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001827 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001828 cb_state->hasTraceRaysCmd = true;
1829}
1830
1831void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001832 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1833 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1834 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1835 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001836 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001837 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1838 pHitShaderBindingTable, pCallableShaderBindingTable,
1839 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001840 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001841}
1842
1843void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001844 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1845 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1846 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1847 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001848 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001849 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1850 pHitShaderBindingTable, pCallableShaderBindingTable,
1851 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001852 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001853 cb_state->hasTraceRaysCmd = true;
1854}
1855
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001856// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001857// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1858// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001859#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001860void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1861 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001862 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001863 VkResult result;
1864 if (!pre_draw_validation_state.globals_created) {
1865 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001866 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1867 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001868 result =
1869 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001870 if (result != VK_SUCCESS) {
1871 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1872 aborted = true;
1873 return;
1874 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001875
1876 std::vector<VkDescriptorSetLayoutBinding> bindings;
1877 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1878 // 0 - output buffer, 1 - count buffer
1879 bindings.push_back(binding);
1880 binding.binding = 1;
1881 bindings.push_back(binding);
1882
1883 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1884 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1885 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1886 ds_layout_ci.pBindings = bindings.data();
1887 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001888 if (result != VK_SUCCESS) {
1889 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1890 aborted = true;
1891 return;
1892 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001893
1894 const uint32_t push_constant_range_count = 1;
1895 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1896 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1897 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001898 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001899 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
1900 pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1901 pipelineLayoutCreateInfo[0].pNext = NULL;
1902 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1903 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1904 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1905 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1906 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1907 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001908 if (result != VK_SUCCESS) {
1909 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1910 aborted = true;
1911 return;
1912 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001913
1914 pre_draw_validation_state.globals_created = true;
1915 }
Tony-LunarG463bae32022-02-25 09:31:17 -07001916
1917 VkPipeline pipeline = VK_NULL_HANDLE;
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001918 VkRenderPass render_pass = state.pipeline_state->rp_state->renderPass();
Tony-LunarG463bae32022-02-25 09:31:17 -07001919 if (render_pass != VK_NULL_HANDLE) {
1920 auto pipeentry = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1921 if (pipeentry != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1922 pipeline = pipeentry->second;
1923 }
1924 } else {
1925 // Dynamic Rendering
1926 pipeline = pre_draw_validation_state.dyn_rendering_pipeline;
1927 }
1928 if (pipeline == VK_NULL_HANDLE) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001929 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1930 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1931 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1932 pipeline_stage_ci.pName = "main";
1933
1934 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1935 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1936 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1937 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1938 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1939 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1940 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1941
1942 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1943 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1944 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1945 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1946 graphicsPipelineCreateInfo.renderPass = render_pass;
1947 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1948 graphicsPipelineCreateInfo.stageCount = 1;
1949 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1950
1951 VkPipeline new_pipeline = VK_NULL_HANDLE;
1952 result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &new_pipeline);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001953 if (result != VK_SUCCESS) {
1954 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1955 aborted = true;
1956 return;
1957 }
1958
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001959 *pPipeline = new_pipeline;
Tony-LunarG463bae32022-02-25 09:31:17 -07001960 if (render_pass != VK_NULL_HANDLE)
1961 pre_draw_validation_state.renderpass_to_pipeline[render_pass] = new_pipeline;
1962 else
1963 pre_draw_validation_state.dyn_rendering_pipeline = new_pipeline;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001964 } else {
Tony-LunarG463bae32022-02-25 09:31:17 -07001965 *pPipeline = pipeline;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001966 }
1967
1968 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1969 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001970 if (result != VK_SUCCESS) {
1971 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1972 aborted = true;
1973 return;
1974 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001975
1976 VkDescriptorBufferInfo buffer_infos[3] = {};
1977 // Error output buffer
1978 buffer_infos[0].buffer = output_block.buffer;
1979 buffer_infos[0].offset = 0;
1980 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001981 if (cdi_state->count_buffer) {
1982 // Count buffer
1983 buffer_infos[1].buffer = cdi_state->count_buffer;
1984 } else {
1985 // Draw Buffer
1986 buffer_infos[1].buffer = cdi_state->buffer;
1987 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001988 buffer_infos[1].offset = 0;
1989 buffer_infos[1].range = VK_WHOLE_SIZE;
1990
1991 VkWriteDescriptorSet desc_writes[2] = {};
1992 for (auto i = 0; i < 2; i++) {
1993 desc_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1994 desc_writes[i].dstBinding = i;
1995 desc_writes[i].descriptorCount = 1;
1996 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1997 desc_writes[i].pBufferInfo = &buffer_infos[i];
1998 desc_writes[i].dstSet = resources.desc_set;
1999 }
2000 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
2001}
2002
Tony-LunarG7de10e82020-11-24 11:31:55 -07002003void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002004 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07002005 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
2006 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03002007 return;
2008 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002009 VkResult result;
2010
Tony-LunarG99b880b2019-09-26 11:19:52 -06002011 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002012
2013 std::vector<VkDescriptorSet> desc_sets;
2014 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06002015 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002016 assert(result == VK_SUCCESS);
2017 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002018 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002019 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002020 return;
2021 }
2022
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002023 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06002024 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002025
Jeremy Gebben135550d2022-03-21 07:15:07 -06002026 auto cb_node = Get<gpuav_state::CommandBuffer>(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002027 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002028 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002029 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002030 return;
2031 }
2032
Tony-LunarG81efe392019-03-07 15:43:27 -07002033 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002034 GpuAssistedDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002035 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
2036 buffer_info.size = output_buffer_size;
2037 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2038 VmaAllocationCreateInfo alloc_info = {};
2039 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
2040 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002041 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002042 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002043 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002044 return;
2045 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002046
Tony-LunarG81efe392019-03-07 15:43:27 -07002047 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002048 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002049 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06002050 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002051 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06002052 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002053 }
Tony-LunarG81efe392019-03-07 15:43:27 -07002054
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002055 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002056 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
2057 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
2058 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002059 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002060 uint32_t desc_count = 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002061 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
2062 auto const &state = cb_node->lastBound[lv_bind_point];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002063 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002064
sfricke-samsung85584a72021-09-30 21:43:38 -07002065 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
2066 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002067 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
2068 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002069 // Insert a draw that can examine some device memory right before the draw we're validating (Pre Draw Validation)
Tony-LunarG20678ff2021-05-07 14:56:26 -06002070 //
2071 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
2072 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
2073
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002074 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002075 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002076 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002077 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06002078 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002079
2080 // Save current graphics pipeline state
2081 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06002082 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002083
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002084 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002085 pre_draw_resources.buffer = cdi_state->buffer;
2086 pre_draw_resources.offset = cdi_state->offset;
2087 pre_draw_resources.stride = cdi_state->stride;
2088
2089 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07002090 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
2091 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002092 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
2093 ReportSetupProblem(device,
2094 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
2095 aborted = true;
2096 return;
2097 }
2098
2099 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
2100 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07002101 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002102 struct_size = sizeof(VkDrawIndirectCommand);
2103 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07002104 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002105 struct_size = sizeof(VkDrawIndexedIndirectCommand);
2106 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06002107 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002108 uint32_t max_count;
2109 uint64_t bufsize = buffer_state->createInfo.size;
2110 uint64_t first_command_bytes = struct_size + cdi_state->offset;
2111 if (first_command_bytes > bufsize) {
2112 max_count = 0;
2113 } else {
2114 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
2115 }
2116 pre_draw_resources.buf_size = buffer_state->createInfo.size;
2117
2118 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
2119 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
2120 pushConstants[1] = max_count;
2121 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
2122 } else {
2123 pushConstants[0] = 0; // firstInstance check instead of count buffer check
2124 pushConstants[1] = cdi_state->drawCount;
2125 if (cmd_type == CMD_DRAWINDIRECT) {
2126 pushConstants[2] = static_cast<uint32_t>(
2127 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2128 } else {
2129 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
2130 pushConstants[2] = static_cast<uint32_t>(
2131 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2132 }
2133 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
2134 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002135
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002136 // Insert diagnostic draw
2137 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002138 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
2139 sizeof(pushConstants), pushConstants);
2140 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
2141 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
2142 nullptr);
2143 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
2144
2145 // Restore the previous graphics pipeline state.
2146 restorable_state.Restore(cmd_buffer);
2147 }
2148
Tony-LunarGe29097a2020-12-03 10:59:19 -07002149 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07002150 // Figure out how much memory we need for the input block based on how many sets and bindings there are
2151 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002152 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07002153 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
2154 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07002155 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05002156 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06002157 if (desc && (desc->GetBindingCount() > 0)) {
2158 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07002159 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
2160 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002161 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
2162 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07002163 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
2164 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002165 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07002166 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
2167 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
2168 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06002169 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07002170 descriptor_count += desc->GetVariableDescriptorCount();
2171 } else {
2172 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
2173 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07002174 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2175 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
2176 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07002177 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2178 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2179 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002180 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002181 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002182 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002183 }
2184 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002185
Tony-LunarGe29097a2020-12-03 10:59:19 -07002186 if (descriptor_indexing || has_buffers) {
2187 // Note that the size of the input buffer is dependent on the maximum binding number, which
2188 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2189 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2190 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2191 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2192 uint32_t words_needed;
2193 if (descriptor_indexing) {
2194 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2195 } else {
2196 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2197 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002198 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2199 buffer_info.size = words_needed * 4;
2200 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2201 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002202 if (result != VK_SUCCESS) {
2203 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
2204 aborted = true;
2205 return;
2206 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002207
Tony-LunarGe29097a2020-12-03 10:59:19 -07002208 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2209 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2210 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002211 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2212 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002213
Tony-LunarGe29097a2020-12-03 10:59:19 -07002214 // Descriptor indexing needs the number of descriptors at each binding.
2215 if (descriptor_indexing) {
2216 // Pointer to a sets array that points into the sizes array
2217 uint32_t *sets_to_sizes = data_ptr + 1;
2218 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2219 uint32_t *sizes = sets_to_sizes + number_of_sets;
2220 // Pointer to another sets array that points into the bindings array that points into the written array
2221 uint32_t *sets_to_bindings = sizes + binding_count;
2222 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2223 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2224 // Index of the next entry in the written array to be updated
2225 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2226 uint32_t bind_counter = number_of_sets + 1;
2227 // Index of the start of the sets_to_bindings array
2228 data_ptr[0] = number_of_sets + binding_count + 1;
2229
John Zulauf79f06582021-02-27 18:38:39 -07002230 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002231 auto desc = s.bound_descriptor_set;
2232 if (desc && (desc->GetBindingCount() > 0)) {
2233 auto layout = desc->GetLayout();
2234 auto bindings = layout->GetSortedBindingSet();
2235 // For each set, fill in index of its bindings sizes in the sizes array
2236 *sets_to_sizes++ = bind_counter;
2237 // For each set, fill in the index of its bindings in the bindings_to_written array
2238 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
2239 for (auto binding : bindings) {
2240 // For each binding, fill in its size in the sizes array
2241 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2242 // uniform blocks
2243 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2244 sizes[binding] = 1;
2245 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
2246 sizes[binding] = desc->GetVariableDescriptorCount();
2247 } else {
2248 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
2249 }
2250 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2251 bindings_to_written[binding] = written_index;
2252
2253 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2254 // uniform blocks
2255 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2256 data_ptr[written_index++] = UINT_MAX;
2257 continue;
2258 }
2259
2260 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2261 // For each array element in the binding, update the written array with whether it has been written
2262 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2263 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2264 if (descriptor->updated) {
2265 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2266 } else if (desc->IsUpdateAfterBind(binding)) {
2267 // If it hasn't been written now and it's update after bind, put it in a list to check at
2268 // QueueSubmit
2269 di_input_block.update_at_submit[written_index] = descriptor;
2270 }
2271 written_index++;
2272 }
2273 }
2274 auto last = desc->GetLayout()->GetMaxBinding();
2275 bindings_to_written += last + 1;
2276 bind_counter += last + 1;
2277 sizes += last + 1;
2278 } else {
2279 *sets_to_sizes++ = 0;
2280 *sets_to_bindings++ = 0;
2281 }
2282 }
2283 } else {
2284 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2285 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2286
2287 // Pointer to sets array that points into the bindings array that points into the written array
2288 uint32_t *sets_to_bindings = data_ptr + 1;
2289 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2290 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2291 // Index of the next entry in the written array to be updated
2292 uint32_t written_index = 1 + number_of_sets + binding_count;
2293 uint32_t bind_counter = number_of_sets + 1;
2294 data_ptr[0] = 1;
2295
John Zulauf79f06582021-02-27 18:38:39 -07002296 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002297 auto desc = s.bound_descriptor_set;
2298 if (desc && (desc->GetBindingCount() > 0)) {
2299 auto layout = desc->GetLayout();
2300 auto bindings = layout->GetSortedBindingSet();
2301 *sets_to_bindings++ = bind_counter;
2302 for (auto binding : bindings) {
2303 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2304 bindings_to_written[binding] = written_index;
2305
2306 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2307 // uniform blocks
2308 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2309 data_ptr[written_index++] = UINT_MAX;
2310 continue;
2311 }
2312
2313 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2314
2315 // For each array element in the binding, update the written array with whether it has been written
2316 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2317 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2318 if (descriptor->updated) {
2319 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2320 } else if (desc->IsUpdateAfterBind(binding)) {
2321 // If it hasn't been written now and it's update after bind, put it in a list to check at
2322 // QueueSubmit
2323 di_input_block.update_at_submit[written_index] = descriptor;
2324 }
2325 written_index++;
2326 }
2327 }
2328 auto last = desc->GetLayout()->GetMaxBinding();
2329 bindings_to_written += last + 1;
2330 bind_counter += last + 1;
2331 } else {
2332 *sets_to_bindings++ = 0;
2333 }
2334 }
2335 }
2336 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2337
2338 di_input_desc_buffer_info.range = (words_needed * 4);
2339 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2340 di_input_desc_buffer_info.offset = 0;
2341
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002342 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002343 desc_writes[1].dstBinding = 1;
2344 desc_writes[1].descriptorCount = 1;
2345 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2346 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2347 desc_writes[1].dstSet = desc_sets[0];
2348
2349 desc_count = 2;
2350 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002351 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002352
sfricke-samsung45996a42021-09-16 13:45:27 -07002353 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2354 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002355 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
2356 auto address_ranges = GetBufferAddressRanges();
2357 if (address_ranges.size() > 0) {
2358 // Example BDA input buffer assuming 2 buffers using BDA:
2359 // Word 0 | Index of start of buffer sizes (in this case 5)
2360 // Word 1 | 0x0000000000000000
2361 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2362 // Word 3 | Device Address of second buffer
2363 // Word 4 | 0xffffffffffffffff
2364 // Word 5 | 0 (size of pretend buffer at word 1)
2365 // Word 6 | Size in bytes of first buffer
2366 // Word 7 | Size in bytes of second buffer
2367 // Word 8 | 0 (size of pretend buffer in word 4)
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002368
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002369 uint32_t num_buffers = static_cast<uint32_t>(address_ranges.size());
2370 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
2371 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2372 buffer_info.size = words_needed * 8; // 64 bit words
2373 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation,
2374 nullptr);
2375 if (result != VK_SUCCESS) {
2376 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
2377 aborted = true;
2378 return;
2379 }
2380 uint64_t *bda_data;
2381 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
2382 uint32_t address_index = 1;
2383 uint32_t size_index = 3 + num_buffers;
2384 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
2385 bda_data[0] = size_index; // Start of buffer sizes
2386 bda_data[address_index++] = 0; // NULL address
2387 bda_data[size_index++] = 0;
2388
2389 for (const auto &range : address_ranges) {
2390 bda_data[address_index++] = range.begin;
2391 bda_data[size_index++] = range.end - range.begin;
2392 }
2393 bda_data[address_index] = UINTPTR_MAX;
2394 bda_data[size_index] = 0;
2395 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
2396
2397 bda_input_desc_buffer_info.range = (words_needed * 8);
2398 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2399 bda_input_desc_buffer_info.offset = 0;
2400
2401 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
2402 desc_writes[desc_count].dstBinding = 2;
2403 desc_writes[desc_count].descriptorCount = 1;
2404 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2405 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2406 desc_writes[desc_count].dstSet = desc_sets[0];
2407 desc_count++;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002408 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002409 }
2410
Tony-LunarGb2501d22019-01-28 09:59:13 -07002411 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002412 output_desc_buffer_info.buffer = output_block.buffer;
2413 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002414
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002415 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002416 desc_writes[0].descriptorCount = 1;
2417 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2418 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2419 desc_writes[0].dstSet = desc_sets[0];
2420 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002421
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002422 const auto *pipeline_state = state.pipeline_state;
2423 if (pipeline_state) {
2424 if ((pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002425 !pipeline_state->pipeline_layout->Destroyed()) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002426 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002427 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002428 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002429 if (pipeline_state->pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002430 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2431 aborted = true;
2432 } else {
2433 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002434 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2435 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002436 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002437 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002438 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002439 aborted = true;
2440 }
2441 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002442 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2443 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2444 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002445 return;
2446 }
2447}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002448
2449std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2450 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002451 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06002452 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<gpuav_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002453}
2454
Jeremy Gebben135550d2022-03-21 07:15:07 -06002455gpuav_state::CommandBuffer::CommandBuffer(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
2456 const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002457 : CMD_BUFFER_STATE(ga, cb, pCreateInfo, pool) {}
2458
Jeremy Gebben135550d2022-03-21 07:15:07 -06002459void gpuav_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002460 CMD_BUFFER_STATE::Reset();
2461 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2462 // Free the device memory and descriptor set(s) associated with a command buffer.
2463 if (gpuav->aborted) {
2464 return;
2465 }
2466 for (auto &buffer_info : gpuav_buffer_list) {
2467 gpuav->DestroyBuffer(buffer_info);
2468 }
2469 gpuav_buffer_list.clear();
2470
2471 for (auto &as_validation_buffer_info : as_validation_buffers) {
2472 gpuav->DestroyBuffer(as_validation_buffer_info);
2473 }
2474 as_validation_buffers.clear();
2475}