blob: 3b81109fc0d75408f732b0007cbdf4474bfc07f7 [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
James Rumble2f6e7bb2021-07-13 15:21:20 +0100235void GpuAssisted::PostCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
236 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, VkResult result) {
237 ValidationStateTracker::PostCallRecordCreateBuffer(device, pCreateInfo, pAllocator, pBuffer, result);
238 if (pCreateInfo) {
239 const auto *opaque_capture_address = LvlFindInChain<VkBufferOpaqueCaptureAddressCreateInfo>(pCreateInfo->pNext);
240 if (opaque_capture_address) {
241 // Validate against the size requested when the buffer was created
242 buffer_map[opaque_capture_address->opaqueCaptureAddress] = pCreateInfo->size;
243 }
244 }
245}
246
Karl Schultz7b024b42018-08-30 16:18:18 -0600247// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600248void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
249 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600250 void *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600251 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600252 VkPhysicalDeviceFeatures features = {};
253 features.vertexPipelineStoresAndAtomics = true;
254 features.fragmentStoresAndAtomics = true;
255 features.shaderInt64 = true;
Mark Lobodzinskib588cd42020-09-30 11:03:34 -0600256 UtilPreCallRecordCreateDevice(gpu, reinterpret_cast<safe_VkDeviceCreateInfo *>(modified_create_info), supported_features,
257 features);
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600258 ValidationStateTracker::PreCallRecordCreateDevice(gpu, create_info, pAllocator, pDevice, modified_create_info);
Karl Schultz7b024b42018-08-30 16:18:18 -0600259}
Karl Schultz7b024b42018-08-30 16:18:18 -0600260// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600261void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
262 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
263 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600264 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600265
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600266 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
267 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
268 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700269
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600270 if (device_gpu_assisted->enabled_features.core.robustBufferAccess ||
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700271 device_gpu_assisted->enabled_features.robustness2_features.robustBufferAccess2) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600272 device_gpu_assisted->buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700273 } else {
Tony-LunarGc99dbef2021-06-14 15:11:50 -0600274 std::string bufferoob_string = getLayerOption("khronos_validation.gpuav_buffer_oob");
275 transform(bufferoob_string.begin(), bufferoob_string.end(), bufferoob_string.begin(), ::tolower);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600276 device_gpu_assisted->buffer_oob_enabled = !bufferoob_string.empty() ? !bufferoob_string.compare("true") : true;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700277 }
Tony-LunarGaef435b2021-10-14 14:49:06 -0600278 std::string descriptor_indexing_string = getLayerOption("khronos_validation.gpuav_descriptor_indexing");
279 transform(descriptor_indexing_string.begin(), descriptor_indexing_string.end(), descriptor_indexing_string.begin(), ::tolower);
280 bool validate_descriptor_indexing = !descriptor_indexing_string.empty() ? !descriptor_indexing_string.compare("true") : true;
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600281
Tony-LunarGc99dbef2021-06-14 15:11:50 -0600282 std::string draw_indirect_string = getLayerOption("khronos_validation.validate_draw_indirect");
283 transform(draw_indirect_string.begin(), draw_indirect_string.end(), draw_indirect_string.begin(), ::tolower);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600284 device_gpu_assisted->validate_draw_indirect = !draw_indirect_string.empty() ? !draw_indirect_string.compare("true") : true;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600285
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600286 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700287 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600288 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600289 return;
290 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600291
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600292 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700293 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600294 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
295 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600296 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600297 return;
298 }
299
sfricke-samsung45996a42021-09-16 13:45:27 -0700300 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
301 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600302 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700303 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
304 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600305 }
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600306 device_gpu_assisted->shaderInt64 = supported_features.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600307 device_gpu_assisted->physicalDevice = physicalDevice;
308 device_gpu_assisted->device = *pDevice;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600309 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600310 if (validate_descriptor_indexing) {
311 device_gpu_assisted->descriptor_indexing = CheckForDescriptorIndexing(device_gpu_assisted->enabled_features);
312 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600313 std::vector<VkDescriptorSetLayoutBinding> bindings;
314 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
Tony-LunarGc7ed2082020-06-11 14:00:04 -0600315 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
316 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
317 kShaderStageAllRayTracing,
Tony-LunarG1dce2392019-10-23 16:49:29 -0600318 NULL};
319 bindings.push_back(binding);
320 for (auto i = 1; i < 3; i++) {
321 binding.binding = i;
322 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600323 }
Tony-LunarGb5fae462020-03-05 12:43:25 -0700324 UtilPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600325 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600326}
327
Mike Schuchardt2df08912020-12-15 16:28:09 -0800328void GpuAssisted::PostCallRecordGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600329 VkDeviceAddress address) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600330 auto buffer_state = Get<BUFFER_STATE>(pInfo->buffer);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600331 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600332 if (buffer_state) {
Rodney Huff0639b262021-11-10 09:24:24 -0800333 buffer_state->deviceAddress = address;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600334 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600335 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600336 ValidationStateTracker::PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600337}
338
Mike Schuchardt2df08912020-12-15 16:28:09 -0800339void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG588c7052020-04-23 10:47:21 -0600340 VkDeviceAddress address) {
341 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
342}
343
Mike Schuchardt2df08912020-12-15 16:28:09 -0800344void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfo *pInfo,
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700345 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600346 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700347}
348
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600349void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600350 auto buffer_state = Get<BUFFER_STATE>(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600351 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG2966c732020-05-21 10:33:53 -0600352 ValidationStateTracker::PreCallRecordDestroyBuffer(device, buffer, pAllocator);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600353}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600354
Karl Schultz7b024b42018-08-30 16:18:18 -0600355// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600356void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600357 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGb5fae462020-03-05 12:43:25 -0700358 UtilPreCallRecordDestroyDevice(this);
Tony-LunarG2966c732020-05-21 10:33:53 -0600359 ValidationStateTracker::PreCallRecordDestroyDevice(device, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600360 if (pre_draw_validation_state.globals_created) {
361 DispatchDestroyShaderModule(device, pre_draw_validation_state.validation_shader_module, nullptr);
362 DispatchDestroyDescriptorSetLayout(device, pre_draw_validation_state.validation_ds_layout, nullptr);
363 DispatchDestroyPipelineLayout(device, pre_draw_validation_state.validation_pipeline_layout, nullptr);
364 for (auto it = pre_draw_validation_state.renderpass_to_pipeline.begin();
365 it != pre_draw_validation_state.renderpass_to_pipeline.end(); ++it) {
366 DispatchDestroyPipeline(device, it->second, nullptr);
367 }
368 pre_draw_validation_state.renderpass_to_pipeline.clear();
369 pre_draw_validation_state.globals_created = false;
370 }
Tony-LunarG0a863bc2020-09-16 09:50:04 -0600371 // State Tracker can end up making vma calls through callbacks - don't destroy allocator until ST is done
372 if (vmaAllocator) {
373 vmaDestroyAllocator(vmaAllocator);
374 }
375 desc_set_manager.reset();
Karl Schultz7b024b42018-08-30 16:18:18 -0600376}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600377
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600378void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600379 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700380 return;
381 }
382
Tony-LunarG99b880b2019-09-26 11:19:52 -0600383 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700384 if (as_validation_state.initialized) {
385 return;
386 }
387
sfricke-samsung45996a42021-09-16 13:45:27 -0700388 if (!IsExtEnabled(device_extensions.vk_nv_ray_tracing)) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700389 return;
390 }
391
392 // Outline:
393 // - Create valid bottom level acceleration structure which acts as replacement
394 // - Create and load vertex buffer
395 // - Create and load index buffer
396 // - Create, allocate memory for, and bind memory for acceleration structure
397 // - Query acceleration structure handle
398 // - Create command pool and command buffer
399 // - Record build acceleration structure command
400 // - Submit command buffer and wait for completion
401 // - Cleanup
402 // - Create compute pipeline for validating instance buffers
403 // - Create descriptor set layout
404 // - Create pipeline layout
405 // - Create pipeline
406 // - Cleanup
407
408 VkResult result = VK_SUCCESS;
409
410 VkBuffer vbo = VK_NULL_HANDLE;
411 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
412 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600413 auto vbo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700414 vbo_ci.size = sizeof(float) * 9;
415 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
416
417 VmaAllocationCreateInfo vbo_ai = {};
418 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
419 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
420
Tony-LunarG99b880b2019-09-26 11:19:52 -0600421 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700422 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700423 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700424 }
425 }
426
427 if (result == VK_SUCCESS) {
428 uint8_t *mapped_vbo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700429 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700430 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700431 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700432 } else {
433 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
434 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600435 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700436 }
437 }
438
439 VkBuffer ibo = VK_NULL_HANDLE;
440 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
441 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600442 auto ibo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700443 ibo_ci.size = sizeof(uint32_t) * 3;
444 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
445
446 VmaAllocationCreateInfo ibo_ai = {};
447 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
448 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
449
Tony-LunarG99b880b2019-09-26 11:19:52 -0600450 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700451 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700452 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700453 }
454 }
455
456 if (result == VK_SUCCESS) {
457 uint8_t *mapped_ibo_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700458 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700459 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700460 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700461 } else {
462 const std::vector<uint32_t> indicies = {0, 1, 2};
463 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600464 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700465 }
466 }
467
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600468 auto geometry = LvlInitStruct<VkGeometryNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700469 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600470 geometry.geometry.triangles = LvlInitStruct<VkGeometryTrianglesNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700471 geometry.geometry.triangles.vertexData = vbo;
472 geometry.geometry.triangles.vertexOffset = 0;
473 geometry.geometry.triangles.vertexCount = 3;
474 geometry.geometry.triangles.vertexStride = 12;
475 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
476 geometry.geometry.triangles.indexData = ibo;
477 geometry.geometry.triangles.indexOffset = 0;
478 geometry.geometry.triangles.indexCount = 3;
479 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
480 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
481 geometry.geometry.triangles.transformOffset = 0;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600482 geometry.geometry.aabbs = LvlInitStruct<VkGeometryAABBNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700483
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600484 auto as_ci = LvlInitStruct<VkAccelerationStructureCreateInfoNV>();
485 as_ci.info = LvlInitStruct<VkAccelerationStructureInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700486 as_ci.info.instanceCount = 0;
487 as_ci.info.geometryCount = 1;
488 as_ci.info.pGeometries = &geometry;
489 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600490 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700491 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700492 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700493 "Failed to create acceleration structure for acceleration structure build validation.");
494 }
495 }
496
497 VkMemoryRequirements2 as_mem_requirements = {};
498 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600499 auto as_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700500 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
501 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
502
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600503 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700504 }
505
506 VmaAllocationInfo as_memory_ai = {};
507 if (result == VK_SUCCESS) {
508 VmaAllocationCreateInfo as_memory_aci = {};
509 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
510
Tony-LunarG99b880b2019-09-26 11:19:52 -0600511 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
512 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700513 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700514 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700515 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
516 }
517 }
518
519 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600520 auto as_bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700521 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
522 as_bind_info.memory = as_memory_ai.deviceMemory;
523 as_bind_info.memoryOffset = as_memory_ai.offset;
524
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600525 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700526 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700527 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700528 "Failed to bind acceleration structure memory for acceleration structure build validation.");
529 }
530 }
531
532 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600533 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
534 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700535 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700536 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700537 "Failed to get acceleration structure handle for acceleration structure build validation.");
538 }
539 }
540
541 VkMemoryRequirements2 scratch_mem_requirements = {};
542 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600543 auto scratch_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700544 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
545 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
546
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600547 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
548 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700549 }
550
551 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600552 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700553 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600554 auto scratch_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700555 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
556 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700557 VmaAllocationCreateInfo scratch_aci = {};
558 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
559
Tony-LunarG18900282020-05-20 12:34:33 -0600560 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700561 if (result != VK_SUCCESS) {
Tony-LunarG18900282020-05-20 12:34:33 -0600562 ReportSetupProblem(device_gpuav->device,
563 "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700564 }
565 }
566
567 VkCommandPool command_pool = VK_NULL_HANDLE;
568 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600569 auto command_pool_ci = LvlInitStruct<VkCommandPoolCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700570 command_pool_ci.queueFamilyIndex = 0;
571
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600572 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700573 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700574 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700575 }
576 }
577
578 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
579
580 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600581 auto command_buffer_ai = LvlInitStruct<VkCommandBufferAllocateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700582 command_buffer_ai.commandPool = command_pool;
583 command_buffer_ai.commandBufferCount = 1;
584 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
585
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600586 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700587 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700588 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700589 "Failed to create command buffer for acceleration structure build validation.");
590 }
591
592 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600593 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700594 }
595
596 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600597 auto command_buffer_bi = LvlInitStruct<VkCommandBufferBeginInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700598
599 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
600 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700601 ReportSetupProblem(device_gpuav->device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700602 }
603 }
604
605 if (result == VK_SUCCESS) {
606 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
607 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
608 DispatchEndCommandBuffer(command_buffer);
609 }
610
611 VkQueue queue = VK_NULL_HANDLE;
612 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600613 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700614
615 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600616 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700617
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600618 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700619 submit_info.commandBufferCount = 1;
620 submit_info.pCommandBuffers = &command_buffer;
621 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
622 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700623 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700624 "Failed to submit command buffer for acceleration structure build validation.");
625 }
626 }
627
628 if (result == VK_SUCCESS) {
629 result = DispatchQueueWaitIdle(queue);
630 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700631 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700632 }
633 }
634
635 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600636 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700637 }
638 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600639 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700640 }
641 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG18900282020-05-20 12:34:33 -0600642 vmaDestroyBuffer(device_gpuav->vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700643 }
644 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600645 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700646 }
647
Tony-LunarG99b880b2019-09-26 11:19:52 -0600648 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700649 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700650 "Failed to find descriptor set layout for acceleration structure build validation.");
651 result = VK_INCOMPLETE;
652 }
653
654 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600655 auto pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700656 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600657 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600658 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700659 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700660 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700661 "Failed to create pipeline layout for acceleration structure build validation.");
662 }
663 }
664
665 VkShaderModule shader_module = VK_NULL_HANDLE;
666 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600667 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700668 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
669 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
670
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600671 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700672 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700673 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700674 "Failed to create compute shader module for acceleration structure build validation.");
675 }
676 }
677
678 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600679 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700680 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
681 pipeline_stage_ci.module = shader_module;
682 pipeline_stage_ci.pName = "main";
683
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600684 auto pipeline_ci = LvlInitStruct<VkComputePipelineCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700685 pipeline_ci.stage = pipeline_stage_ci;
686 pipeline_ci.layout = as_validation_state.pipeline_layout;
687
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600688 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
689 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700690 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700691 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700692 "Failed to create compute pipeline for acceleration structure build validation.");
693 }
694 }
695
696 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600697 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700698 }
699
700 if (result == VK_SUCCESS) {
701 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700702 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600703 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700704 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600705 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700706 }
707}
708
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600709void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600710 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700711 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
712 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
713 }
714 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
715 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
716 }
717 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
718 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
719 }
720 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600721 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700722 }
723}
724
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600725struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700726 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
727 VkPipeline pipeline = VK_NULL_HANDLE;
728 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
729 std::vector<VkDescriptorSet> descriptor_sets;
730 std::vector<std::vector<uint32_t>> dynamic_offsets;
731 uint32_t push_descriptor_set_index = 0;
732 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
733 std::vector<uint8_t> push_constants_data;
734 PushConstantRangesId push_constants_ranges;
735
736 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
737 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600738 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700739
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600740 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700741 if (last_bound.pipeline_state) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600742 pipeline = last_bound.pipeline_state->pipeline();
Jason Macnak83cfd582019-07-31 10:14:24 -0700743 pipeline_layout = last_bound.pipeline_layout;
744 descriptor_sets.reserve(last_bound.per_set.size());
745 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700746 const auto &bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
ziga-lunarge0b552b2021-09-05 21:39:57 +0200747 if (bound_descriptor_set) {
748 descriptor_sets.push_back(bound_descriptor_set->GetSet());
749 if (bound_descriptor_set->IsPushDescriptor()) {
750 push_descriptor_set_index = static_cast<uint32_t>(i);
751 }
752 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
Jason Macnak83cfd582019-07-31 10:14:24 -0700753 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700754 }
755
756 if (last_bound.push_descriptor_set) {
757 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
758 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500759 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700760 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500761 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700762 }
763 }
764 }
765
766 void Restore(VkCommandBuffer command_buffer) const {
767 if (pipeline != VK_NULL_HANDLE) {
768 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
769 if (!descriptor_sets.empty()) {
770 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
771 VkDescriptorSet descriptor_set = descriptor_sets[i];
772 if (descriptor_set != VK_NULL_HANDLE) {
773 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
774 static_cast<uint32_t>(i), 1, &descriptor_set,
775 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
776 }
777 }
778 }
779 if (!push_descriptor_set_writes.empty()) {
780 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
781 static_cast<uint32_t>(push_descriptor_set_writes.size()),
782 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
783 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600784 if (!push_constants_data.empty()) {
785 for (const auto &push_constant_range : *push_constants_ranges) {
786 if (push_constant_range.size == 0) continue;
787 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
788 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
789 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700790 }
791 }
792 }
793};
794
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600795void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
796 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
797 VkDeviceSize instanceOffset, VkBool32 update,
798 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
799 VkBuffer scratch, VkDeviceSize scratchOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600800 ValidationStateTracker::PreCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update,
801 dst, src, scratch, scratchOffset);
Jason Macnak83cfd582019-07-31 10:14:24 -0700802 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
803 return;
804 }
805
Tony-LunarG99b880b2019-09-26 11:19:52 -0600806 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700807 if (!as_validation_state.initialized) {
808 return;
809 }
810
811 // Empty acceleration structure is valid according to the spec.
812 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
813 return;
814 }
815
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600816 auto cb_state = GetCBState(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700817 assert(cb_state != nullptr);
818
819 std::vector<uint64_t> current_valid_handles;
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600820 ForEach<ACCELERATION_STRUCTURE_STATE>([&current_valid_handles](const ACCELERATION_STRUCTURE_STATE &as_state) {
Jeff Bolz95176d02020-04-01 00:36:16 -0500821 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700822 current_valid_handles.push_back(as_state.opaque_handle);
823 }
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600824 });
Jason Macnak83cfd582019-07-31 10:14:24 -0700825
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600826 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700827 as_validation_buffer_info.acceleration_structure = dst;
828
829 const VkDeviceSize validation_buffer_size =
830 // One uint for number of instances to validate
831 4 +
832 // Two uint for the replacement acceleration structure handle
833 8 +
834 // One uint for number of invalid handles found
835 4 +
836 // Two uint for the first invalid handle found
837 8 +
838 // One uint for the number of current valid handles
839 4 +
840 // Two uint for each current valid handle
841 (8 * current_valid_handles.size());
842
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600843 auto validation_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700844 validation_buffer_create_info.size = validation_buffer_size;
845 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
846
847 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
848 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
849
Tony-LunarG99b880b2019-09-26 11:19:52 -0600850 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
851 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700852 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
853 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700854 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600855 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700856 return;
857 }
858
859 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700860 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
861 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700862 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700863 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600864 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700865 return;
866 }
867
868 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
869 mapped_validation_buffer->replacement_handle_bits_0 =
870 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
871 mapped_validation_buffer->replacement_handle_bits_1 =
872 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
873 mapped_validation_buffer->invalid_handle_found = 0;
874 mapped_validation_buffer->invalid_handle_bits_0 = 0;
875 mapped_validation_buffer->invalid_handle_bits_1 = 0;
876 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
877
878 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
879 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
880 const uint64_t current_valid_handle = current_valid_handles[i];
881
882 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
883 ++mapped_valid_handles;
884 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
885 ++mapped_valid_handles;
886 }
887
Tony-LunarG99b880b2019-09-26 11:19:52 -0600888 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700889
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700890 static constexpr const VkDeviceSize k_instance_size = 64;
891 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700892
Tony-LunarG1dce2392019-10-23 16:49:29 -0600893 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
894 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700895 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700896 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600897 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700898 return;
899 }
900
901 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
902 descriptor_buffer_infos[0].buffer = instanceData;
903 descriptor_buffer_infos[0].offset = instanceOffset;
904 descriptor_buffer_infos[0].range = instance_buffer_size;
905 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
906 descriptor_buffer_infos[1].offset = 0;
907 descriptor_buffer_infos[1].range = validation_buffer_size;
908
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600909 VkWriteDescriptorSet descriptor_set_writes[2] = {
910 LvlInitStruct<VkWriteDescriptorSet>(),
911 LvlInitStruct<VkWriteDescriptorSet>(),
912 };
Jason Macnak83cfd582019-07-31 10:14:24 -0700913 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
914 descriptor_set_writes[0].dstBinding = 0;
915 descriptor_set_writes[0].descriptorCount = 1;
916 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
917 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
Jason Macnak83cfd582019-07-31 10:14:24 -0700918 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
919 descriptor_set_writes[1].dstBinding = 1;
920 descriptor_set_writes[1].descriptorCount = 1;
921 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
922 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
923
924 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
925
926 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600927 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700928 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
929 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
930 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
931 &memory_barrier, 0, nullptr, 0, nullptr);
932
933 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600934 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -0600935 restorable_state.Create(cb_state.get(), VK_PIPELINE_BIND_POINT_COMPUTE);
Jason Macnak83cfd582019-07-31 10:14:24 -0700936
937 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
938 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
939 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
940 &as_validation_buffer_info.descriptor_set, 0, nullptr);
941 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
942
943 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
944 // have been replaced by the validation compute shader before any builds take place.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600945 auto instance_buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700946 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
947 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
948 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
949 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
950 instance_buffer_barrier.buffer = instanceData;
951 instance_buffer_barrier.offset = instanceOffset;
952 instance_buffer_barrier.size = instance_buffer_size;
953 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
954 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
955 nullptr);
956
957 // Restore the previous compute pipeline state.
958 restorable_state.Restore(commandBuffer);
959
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600960 cb_state->as_validation_buffers.emplace_back(std::move(as_validation_buffer_info));
Jason Macnak83cfd582019-07-31 10:14:24 -0700961}
962
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600963void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE_GPUAV *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700964 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
965 return;
966 }
967
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600968 for (const auto &as_validation_buffer_info : cb_node->as_validation_buffers) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700969 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
970
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700971 VkResult result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
972 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700973 if (result == VK_SUCCESS) {
974 if (mapped_validation_buffer->invalid_handle_found > 0) {
975 uint64_t invalid_handle = 0;
976 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
977 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
978
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700979 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
980 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
981 "handle (%" PRIu64 ")",
982 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700983 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600984 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700985 }
986 }
987}
988
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600989void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
990 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
991 VkResult result) {
992 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600993 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600994 for (uint32_t i = 0; i < bindInfoCount; i++) {
995 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600996 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600997 if (as_state) {
998 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
999 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001000 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001001}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -07001002
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001003// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
1004void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
1005 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
1006 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001007 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001008 return;
1009 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001010
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001011 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
1012
Tony-LunarG99b880b2019-09-26 11:19:52 -06001013 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001014 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001015 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -06001016 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
1017 << "Validation is not modifying the pipeline layout. "
1018 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001019 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001020 } else {
Tony-LunarGb5fae462020-03-05 12:43:25 -07001021 UtilPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -06001022 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001023 ValidationStateTracker::PreCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, cpl_state_data);
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -07001024}
1025
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001026void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
1027 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
1028 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001029 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
1030
Karl Schultz7b024b42018-08-30 16:18:18 -06001031 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001032 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001033 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -06001034 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001035}
1036
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001037// Free the device memory and descriptor set(s) associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001038void GpuAssisted::DestroyBuffer(GpuAssistedBufferInfo &buffer_info) {
1039 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
1040 if (buffer_info.di_input_mem_block.buffer) {
1041 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -06001042 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001043 if (buffer_info.bda_input_mem_block.buffer) {
1044 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -06001045 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001046 if (buffer_info.desc_set != VK_NULL_HANDLE) {
1047 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001048 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001049 if (buffer_info.pre_draw_resources.desc_set != VK_NULL_HANDLE) {
1050 desc_set_manager->PutBackDescriptorSet(buffer_info.pre_draw_resources.desc_pool, buffer_info.pre_draw_resources.desc_set);
1051 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001052}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001053
1054void GpuAssisted::DestroyBuffer(GpuAssistedAccelerationStructureBuildValidationBufferInfo &as_validation_buffer_info) {
1055 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
1056 as_validation_buffer_info.validation_buffer_allocation);
1057
1058 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
1059 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool, as_validation_buffer_info.descriptor_set);
1060 }
1061}
1062
Karl Schultz7b024b42018-08-30 16:18:18 -06001063// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001064bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1065 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1066 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1067 uint32_t bufferMemoryBarrierCount,
1068 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001069 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001070 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001071 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001072 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1073 "GPU_Assisted validation waits on queue completion. "
1074 "This wait could block the host's signaling of this event, resulting in deadlock.");
1075 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001076 ValidationStateTracker::PreCallValidateCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask,
1077 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
1078 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001079 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001080}
1081
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001082bool GpuAssisted::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1083 const VkDependencyInfoKHR *pDependencyInfos) const {
1084 VkPipelineStageFlags2KHR srcStageMask = 0;
1085
1086 for (uint32_t i = 0; i < eventCount; i++) {
1087 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
1088 srcStageMask = stage_masks.src;
1089 }
1090
1091 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
1092 ReportSetupProblem(commandBuffer,
1093 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1094 "GPU_Assisted validation waits on queue completion. "
1095 "This wait could block the host's signaling of this event, resulting in deadlock.");
1096 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001097 ValidationStateTracker::PreCallValidateCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001098 return false;
1099}
1100
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001101void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1102 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1103 // 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 -06001104 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001105 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1106 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1107 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001108 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1109 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001110 }
1111 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001112 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pPhysicalDeviceProperties);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001113}
1114
1115void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1116 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1117 // 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 -06001118 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001119 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1120 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1121 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001122 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1123 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001124 }
1125 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001126 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pPhysicalDeviceProperties2);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001127}
1128
1129void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1130 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1131 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1132 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001133 if (aborted) return;
Karl Schultz7b024b42018-08-30 16:18:18 -06001134 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001135 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001136 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1137 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001138 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1139 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001140 ValidationStateTracker::PreCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1141 cgpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001142}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001143
1144void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1145 const VkComputePipelineCreateInfo *pCreateInfos,
1146 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1147 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001148 if (aborted) return;
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001149 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001150 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001151 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1152 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001153 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1154 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001155 ValidationStateTracker::PreCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1156 ccpl_state_data);
Jason Macnak67407e72019-07-11 11:05:09 -07001157}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001158
1159void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1160 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1161 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1162 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001163 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001164 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001165 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001166 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1167 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001168 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1169 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001170 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1171 pPipelines, crtpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001172}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001173
sourav parmarcd5fb182020-07-17 12:58:44 -07001174void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1175 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001176 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1177 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1178 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001179 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001180 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1181 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001182 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1183 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001184 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1185 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001186 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesKHR(device, deferredOperation, pipelineCache, count, pCreateInfos,
1187 pAllocator, pPipelines, crtpl_state_data);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001188}
Karl Schultz7b024b42018-08-30 16:18:18 -06001189
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001190void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1191 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1192 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1193 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001194 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1195 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001196 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001197 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
1198 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001199 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001200}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001201
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001202void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1203 const VkComputePipelineCreateInfo *pCreateInfos,
1204 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1205 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001206 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1207 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001208 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001209 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
1210 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001211 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001212}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001213
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001214void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1215 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1216 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1217 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001218 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001219 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1220 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001221 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001222 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001223 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001224}
1225
sourav parmarcd5fb182020-07-17 12:58:44 -07001226void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1227 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001228 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1229 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1230 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001231 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
sourav parmarcd5fb182020-07-17 12:58:44 -07001232 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
1233 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001234 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001235 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001236 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001237}
1238
1239// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001240void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001241 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001242 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001243 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001244 } else {
1245 ++it;
1246 }
1247 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001248 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001249}
1250
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001251void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1252 const VkAllocationCallbacks *pAllocator) {
1253 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(renderPass);
1254 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1255 DispatchDestroyPipeline(device, pipeline->second, nullptr);
1256 pre_draw_validation_state.renderpass_to_pipeline.erase(pipeline);
1257 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001258 ValidationStateTracker::PreCallRecordDestroyRenderPass(device, renderPass, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001259}
1260
Karl Schultz7b024b42018-08-30 16:18:18 -06001261// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001262bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1263 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001264 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001265 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1266
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001267 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001268 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1269 switch (level) {
1270 case SPV_MSG_FATAL:
1271 case SPV_MSG_INTERNAL_ERROR:
1272 case SPV_MSG_ERROR:
1273 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1274 position.index, message);
1275 break;
1276 default:
1277 break;
1278 }
1279 };
1280
Karl Schultz7b024b42018-08-30 16:18:18 -06001281 // Load original shader SPIR-V
1282 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1283 new_pgm.clear();
1284 new_pgm.reserve(num_words);
1285 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1286
1287 // Call the optimizer to instrument the shader.
1288 // 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 -07001289 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001290 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -07001291 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001292 spvtools::ValidatorOptions val_options;
1293 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1294 spvtools::OptimizerOptions opt_options;
1295 opt_options.set_run_validator(true);
1296 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001297 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001298 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001299 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001300 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Tony-LunarG57400d42021-10-14 11:18:43 -06001301 // Call CreateAggressiveDCEPass with preserve_interface == true
1302 optimizer.RegisterPass(CreateAggressiveDCEPass(true));
sfricke-samsung45996a42021-09-16 13:45:27 -07001303 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
1304 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
1305 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001306 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001307 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001308 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001309 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001310 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001311 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001312 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001313 return pass;
1314}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001315// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001316void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1317 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1318 void *csm_state_data) {
1319 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1320 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001321 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001322 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1323 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001324 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001325 ValidationStateTracker::PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, csm_state_data);
Karl Schultz7b024b42018-08-30 16:18:18 -06001326}
Tony-LunarG20678ff2021-05-07 14:56:26 -06001327
Tony-LunarG7345a062021-06-24 13:16:38 -06001328static const int kInstErrorPreDrawValidate = spvtools::kInstErrorMax + 1;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001329static const int kPreDrawValidateSubError = spvtools::kInstValidationOutError + 1;
Karl Schultz7b024b42018-08-30 16:18:18 -06001330// Generate the part of the message describing the violation.
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001331bool 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 -06001332 using namespace spvtools;
1333 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001334 bool return_code = true;
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001335 assert(kInstErrorPreDrawValidate == _kInstErrorPreDrawValidate);
1336 assert(kInstValidationOutError == _kInstValidationOutError);
Tony-LunarGab47cac2019-12-20 15:28:01 -07001337 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001338 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001339 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1340 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001341 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001342 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001343 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001344 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001345 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001346 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001347 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001348 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001349 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1350 vuid_msg = "UNASSIGNED-Device address out of bounds";
1351 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001352 case kInstErrorBuffOOBUniform:
1353 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001354 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1355 if (size == 0) {
1356 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1357 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1358 } else {
1359 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1360 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001361 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001362 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001363 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1364 vuid_msg = vuid.uniform_access_oob;
1365 else
1366 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001367 }
1368 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001369 case kInstErrorBuffOOBUniformTexel:
1370 case kInstErrorBuffOOBStorageTexel: {
1371 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1372 if (size == 0) {
1373 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1374 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001375 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001376 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001377 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1378 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001379 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001380 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1381 vuid_msg = vuid.uniform_access_oob;
1382 else
1383 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001384 }
Tony-LunarG63f82e02021-04-12 16:13:48 -06001385 } break;
1386 case kInstErrorPreDrawValidate: {
Tim Van Patten38bdcdd2021-05-14 16:41:00 -06001387 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001388 if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_bufsize_error) {
Tony-LunarG63f82e02021-04-12 16:13:48 -06001389 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001390 uint32_t stride = buf_info.pre_draw_resources.stride;
1391 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
1392 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
1393 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1394 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
1395 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
1396 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001397 if (count == 1) {
1398 vuid_msg = vuid.count_exceeds_bufsize_1;
1399 } else {
1400 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001401 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001402 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_limit_error) {
1403 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
1404 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1405 strm << "Indirect draw count of " << count << " would exceed maxDrawIndirectCount limit of "
1406 << gpu_assisted->phys_dev_props.limits.maxDrawIndirectCount;
1407 vuid_msg = vuid.count_exceeds_device_limit;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001408 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_first_instance_error) {
1409 uint32_t index = debug_record[kPreDrawValidateSubError + 1];
1410 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1411 strm << "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the "
1412 "VkDrawIndirectCommand structure at index "
1413 << index << " is not zero";
1414 vuid_msg = vuid.first_instance_not_zero;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001415 }
1416 return_code = false;
1417 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001418 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001419 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001420 vuid_msg = "UNASSIGNED-Internal Error";
1421 assert(false);
1422 } break;
1423 }
1424 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001425 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001426}
1427
Karl Schultz7b024b42018-08-30 16:18:18 -06001428// Pull together all the information from the debug record to build the error message strings,
1429// and then assemble them into a single message string.
1430// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1431// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1432// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1433// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1434//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001435void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001436 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001437 using namespace spvtools;
1438 const uint32_t total_words = debug_output_buffer[0];
1439 // A zero here means that the shader instrumentation didn't write anything.
1440 // If you have nothing to say, don't say it here.
1441 if (0 == total_words) {
1442 return;
1443 }
1444 // The first word in the debug output buffer is the number of words that would have
1445 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1446 // The number of words actually written by the shaders is determined by the size of the buffer
1447 // we provide via the descriptor. So, we process only the number of words that can fit in the
1448 // buffer.
1449 // Each "report" written by the shader instrumentation is considered a "record". This function
1450 // is hard-coded to process only one record because it expects the buffer to be large enough to
1451 // hold only one record. If there is a desire to process more than one record, this function needs
1452 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001453 std::string validation_message;
1454 std::string stage_message;
1455 std::string common_message;
1456 std::string filename_message;
1457 std::string source_message;
1458 std::string vuid_msg;
1459 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1460 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1461 std::vector<unsigned int> pgm;
1462 // The first record starts at this offset after the total_words.
1463 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1464 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1465 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001466 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1467 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001468 shader_module_handle = it->second.shader_module;
1469 pipeline_handle = it->second.pipeline;
1470 pgm = it->second.pgm;
1471 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001472 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info, this);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001473 if (gen_full_message) {
1474 UtilGenerateStageMessage(debug_record, stage_message);
1475 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1476 buffer_info.pipeline_bind_point, operation_index, common_message);
1477 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1478 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1479 filename_message.c_str(), source_message.c_str());
1480 }
1481 else {
1482 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1483 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001484 // The debug record at word kInstCommonOutSize is the number of words in the record
1485 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001486 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001487 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1488}
1489
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001490void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1491 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1492 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001493 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001494 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001495 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001496 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1497 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1498 }
1499 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1500 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001501 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001502 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001503 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001504 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1505 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1506 }
1507 } else {
1508 pData[index] = 1;
1509 }
1510}
1511
Tony-LunarG81efe392019-03-07 15:43:27 -07001512// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001513void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE_GPUAV *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001514 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001515 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001516 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001517 VkResult result =
1518 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001519 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001520 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001521 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001522 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001523 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001524 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001525 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001526 }
1527 }
1528 }
1529}
1530
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001531void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
1532 auto cb_node = GetCBState(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001533 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001534 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001535 UpdateInstrumentationBuffer(static_cast<CMD_BUFFER_STATE_GPUAV *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001536 }
1537}
1538
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001539void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001540 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001541 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1542 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1543 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001544 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001545 }
1546 }
1547}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001548
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001549void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1550 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001551 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001552 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1553 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1554 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1555 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1556 }
1557 }
1558}
1559
Tony-LunarG26fe2842021-11-16 14:07:59 -07001560void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1561 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1562 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1563 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1564 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1565 }
1566 }
1567}
1568
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001569bool GpuAssisted::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
1570 bool buffers_present = false;
1571 auto cb_node = GetCBState(command_buffer);
1572
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001573 if (cb_node->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001574 buffers_present = true;
1575 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001576 for (const auto *secondary : cb_node->linkedCommandBuffers) {
1577 auto secondary_cmd_buffer = static_cast<const CMD_BUFFER_STATE_GPUAV *>(secondary);
1578 if (secondary_cmd_buffer->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001579 buffers_present = true;
1580 }
1581 }
1582 return buffers_present;
1583}
1584
1585void GpuAssisted::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
1586 auto cb_node = GetCBState(command_buffer);
1587
Jeremy Gebben9f537102021-10-05 16:37:12 -06001588 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
1589 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001590 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001591 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001592 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001593 }
1594}
Tony-LunarG81efe392019-03-07 15:43:27 -07001595
Karl Schultz58674242019-01-22 15:35:02 -07001596// Issue a memory barrier to make GPU-written data available to host.
1597// Wait for the queue to complete execution.
1598// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001599void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1600 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001601 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001602
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001603 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001604 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++) {
1607 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1608 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001609 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001610 }
1611 }
1612 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001613
Tony-LunarGb5fae462020-03-05 12:43:25 -07001614 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001615
Tony-LunarG152a88b2019-03-20 15:42:24 -06001616 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001617
Karl Schultz7b024b42018-08-30 16:18:18 -06001618 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1619 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1620 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001621 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
1622 }
1623 }
1624}
1625
Tony-LunarG26fe2842021-11-16 14:07:59 -07001626void GpuAssisted::RecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits,
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001627 VkFence fence, VkResult result) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001628 if (aborted || (result != VK_SUCCESS)) return;
1629 bool buffers_present = false;
1630 // Don't QueueWaitIdle if there's nothing to process
1631 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001632 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001633 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1634 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
1635 }
1636 }
1637 if (!buffers_present) return;
1638
1639 UtilSubmitBarrier(queue, this);
1640
1641 DispatchQueueWaitIdle(queue);
1642
1643 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001644 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001645 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1646 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001647 }
1648 }
1649}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001650
Tony-LunarG26fe2842021-11-16 14:07:59 -07001651void GpuAssisted::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits,
1652 VkFence fence, VkResult result) {
1653 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
1654 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1655}
1656
1657void GpuAssisted::PostCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits,
1658 VkFence fence, VkResult result) {
1659 ValidationStateTracker::PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1660 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1661}
1662
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001663void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1664 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001665 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001666 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001667}
1668
Tony-LunarG745150c2021-07-02 15:07:31 -06001669void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1670 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1671 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001672 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1673 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001674 for (uint32_t i = 0; i < drawCount; i++) {
1675 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1676 }
1677}
1678
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001679void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1680 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001681 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1682 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001683 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001684}
1685
Tony-LunarG745150c2021-07-02 15:07:31 -06001686void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1687 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1688 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001689 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1690 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001691 for (uint32_t i = 0; i < drawCount; i++) {
1692 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1693 }
1694}
1695
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001696void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1697 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001698 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001699 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1700 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001701}
1702
1703void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1704 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001705 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001706 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1707 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001708}
1709
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001710void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1711 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1712 uint32_t stride) {
1713 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1714 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001715 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001716 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001717}
1718
1719void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1720 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001721
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001722 uint32_t stride) {
1723 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1724 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001725 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1726 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001727}
1728
Tony-LunarG54176fb2020-12-02 10:47:22 -07001729void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1730 uint32_t firstInstance, VkBuffer counterBuffer,
1731 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1732 uint32_t vertexStride) {
1733 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1734 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001735 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001736}
1737
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001738void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1739 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1740 uint32_t maxDrawCount, uint32_t stride) {
1741 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1742 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001743 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001744 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001745}
1746
1747void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1748 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1749 uint32_t maxDrawCount, uint32_t stride) {
1750 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1751 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001752 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1753 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001754}
1755
1756void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1757 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001758 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001759}
1760
1761void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1762 uint32_t drawCount, uint32_t stride) {
1763 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001764 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001765}
1766
1767void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1768 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1769 uint32_t maxDrawCount, uint32_t stride) {
1770 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1771 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001772 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001773}
1774
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001775void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001776 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001777 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001778}
1779
1780void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001781 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001782 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001783}
1784
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001785void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1786 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1787 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001788 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1789 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001790 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001791}
1792
Tony-LunarG52c8c602020-09-10 16:29:56 -06001793void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1794 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1795 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001796 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1797 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001798 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001799}
1800
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001801void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1802 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1803 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1804 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1805 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1806 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1807 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001808 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1809 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1810 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1811 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1812 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001813 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001814}
1815
1816void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1817 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1818 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1819 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1820 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1821 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1822 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001823 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1824 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1825 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1826 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1827 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001828 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001829 cb_state->hasTraceRaysCmd = true;
1830}
1831
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001832void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001833 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1834 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1835 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1836 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001837 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001838 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1839 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001840 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001841}
1842
1843void GpuAssisted::PostCallRecordCmdTraceRaysKHR(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, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001848 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001849 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1850 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1851 depth);
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
1856void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001857 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1858 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1859 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1860 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001861 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001862 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1863 pHitShaderBindingTable, pCallableShaderBindingTable,
1864 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001865 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001866}
1867
1868void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001869 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1870 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1871 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1872 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001873 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001874 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1875 pHitShaderBindingTable, pCallableShaderBindingTable,
1876 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001877 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001878 cb_state->hasTraceRaysCmd = true;
1879}
1880
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001881// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001882// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1883// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001884#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001885void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1886 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001887 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001888 VkResult result;
1889 if (!pre_draw_validation_state.globals_created) {
1890 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001891 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1892 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001893 result =
1894 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001895 if (result != VK_SUCCESS) {
1896 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1897 aborted = true;
1898 return;
1899 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001900
1901 std::vector<VkDescriptorSetLayoutBinding> bindings;
1902 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1903 // 0 - output buffer, 1 - count buffer
1904 bindings.push_back(binding);
1905 binding.binding = 1;
1906 bindings.push_back(binding);
1907
1908 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1909 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1910 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1911 ds_layout_ci.pBindings = bindings.data();
1912 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001913 if (result != VK_SUCCESS) {
1914 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1915 aborted = true;
1916 return;
1917 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001918
1919 const uint32_t push_constant_range_count = 1;
1920 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1921 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1922 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001923 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001924 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
1925 pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1926 pipelineLayoutCreateInfo[0].pNext = NULL;
1927 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1928 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1929 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1930 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1931 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1932 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001933 if (result != VK_SUCCESS) {
1934 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1935 aborted = true;
1936 return;
1937 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001938
1939 pre_draw_validation_state.globals_created = true;
1940 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001941 VkRenderPass render_pass = state.pipeline_state->rp_state->renderPass();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001942 assert(render_pass != VK_NULL_HANDLE);
1943 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1944 if (pipeline == pre_draw_validation_state.renderpass_to_pipeline.end()) {
1945 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1946 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1947 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1948 pipeline_stage_ci.pName = "main";
1949
1950 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1951 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1952 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1953 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1954 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1955 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1956 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1957
1958 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1959 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1960 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1961 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1962 graphicsPipelineCreateInfo.renderPass = render_pass;
1963 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1964 graphicsPipelineCreateInfo.stageCount = 1;
1965 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1966
1967 VkPipeline new_pipeline = VK_NULL_HANDLE;
1968 result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &new_pipeline);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001969 if (result != VK_SUCCESS) {
1970 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1971 aborted = true;
1972 return;
1973 }
1974
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001975 *pPipeline = new_pipeline;
1976 pre_draw_validation_state.renderpass_to_pipeline[render_pass] = new_pipeline;
1977 } else {
1978 *pPipeline = pipeline->second;
1979 }
1980
1981 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1982 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001983 if (result != VK_SUCCESS) {
1984 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1985 aborted = true;
1986 return;
1987 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001988
1989 VkDescriptorBufferInfo buffer_infos[3] = {};
1990 // Error output buffer
1991 buffer_infos[0].buffer = output_block.buffer;
1992 buffer_infos[0].offset = 0;
1993 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001994 if (cdi_state->count_buffer) {
1995 // Count buffer
1996 buffer_infos[1].buffer = cdi_state->count_buffer;
1997 } else {
1998 // Draw Buffer
1999 buffer_infos[1].buffer = cdi_state->buffer;
2000 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002001 buffer_infos[1].offset = 0;
2002 buffer_infos[1].range = VK_WHOLE_SIZE;
2003
2004 VkWriteDescriptorSet desc_writes[2] = {};
2005 for (auto i = 0; i < 2; i++) {
2006 desc_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2007 desc_writes[i].dstBinding = i;
2008 desc_writes[i].descriptorCount = 1;
2009 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2010 desc_writes[i].pBufferInfo = &buffer_infos[i];
2011 desc_writes[i].dstSet = resources.desc_set;
2012 }
2013 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
2014}
2015
Tony-LunarG7de10e82020-11-24 11:31:55 -07002016void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002017 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07002018 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
2019 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03002020 return;
2021 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002022 VkResult result;
2023
Tony-LunarG99b880b2019-09-26 11:19:52 -06002024 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002025
2026 std::vector<VkDescriptorSet> desc_sets;
2027 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06002028 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002029 assert(result == VK_SUCCESS);
2030 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002031 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002032 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002033 return;
2034 }
2035
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002036 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06002037 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002038
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06002039 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002040 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002041 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002042 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002043 return;
2044 }
2045
Tony-LunarG81efe392019-03-07 15:43:27 -07002046 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002047 GpuAssistedDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002048 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
2049 buffer_info.size = output_buffer_size;
2050 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2051 VmaAllocationCreateInfo alloc_info = {};
2052 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
2053 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002054 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002055 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002056 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002057 return;
2058 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002059
Tony-LunarG81efe392019-03-07 15:43:27 -07002060 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002061 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002062 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06002063 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002064 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06002065 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002066 }
Tony-LunarG81efe392019-03-07 15:43:27 -07002067
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002068 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002069 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
2070 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
2071 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002072 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002073 uint32_t desc_count = 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002074 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
2075 auto const &state = cb_node->lastBound[lv_bind_point];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002076 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002077
sfricke-samsung85584a72021-09-30 21:43:38 -07002078 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
2079 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002080 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
2081 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002082 // 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 -06002083 //
2084 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
2085 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
2086
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002087 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002088 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002089 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002090 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06002091 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002092
2093 // Save current graphics pipeline state
2094 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06002095 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002096
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002097 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002098 pre_draw_resources.buffer = cdi_state->buffer;
2099 pre_draw_resources.offset = cdi_state->offset;
2100 pre_draw_resources.stride = cdi_state->stride;
2101
2102 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07002103 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
2104 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002105 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
2106 ReportSetupProblem(device,
2107 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
2108 aborted = true;
2109 return;
2110 }
2111
2112 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
2113 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07002114 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002115 struct_size = sizeof(VkDrawIndirectCommand);
2116 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07002117 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002118 struct_size = sizeof(VkDrawIndexedIndirectCommand);
2119 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06002120 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002121 uint32_t max_count;
2122 uint64_t bufsize = buffer_state->createInfo.size;
2123 uint64_t first_command_bytes = struct_size + cdi_state->offset;
2124 if (first_command_bytes > bufsize) {
2125 max_count = 0;
2126 } else {
2127 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
2128 }
2129 pre_draw_resources.buf_size = buffer_state->createInfo.size;
2130
2131 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
2132 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
2133 pushConstants[1] = max_count;
2134 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
2135 } else {
2136 pushConstants[0] = 0; // firstInstance check instead of count buffer check
2137 pushConstants[1] = cdi_state->drawCount;
2138 if (cmd_type == CMD_DRAWINDIRECT) {
2139 pushConstants[2] = static_cast<uint32_t>(
2140 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2141 } else {
2142 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
2143 pushConstants[2] = static_cast<uint32_t>(
2144 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2145 }
2146 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
2147 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002148
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002149 // Insert diagnostic draw
2150 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002151 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
2152 sizeof(pushConstants), pushConstants);
2153 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
2154 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
2155 nullptr);
2156 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
2157
2158 // Restore the previous graphics pipeline state.
2159 restorable_state.Restore(cmd_buffer);
2160 }
2161
Tony-LunarGe29097a2020-12-03 10:59:19 -07002162 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07002163 // Figure out how much memory we need for the input block based on how many sets and bindings there are
2164 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002165 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07002166 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
2167 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07002168 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05002169 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06002170 if (desc && (desc->GetBindingCount() > 0)) {
2171 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07002172 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
2173 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002174 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
2175 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07002176 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
2177 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002178 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07002179 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
2180 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
2181 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06002182 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07002183 descriptor_count += desc->GetVariableDescriptorCount();
2184 } else {
2185 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
2186 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07002187 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2188 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
2189 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07002190 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2191 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2192 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002193 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002194 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002195 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002196 }
2197 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002198
Tony-LunarGe29097a2020-12-03 10:59:19 -07002199 if (descriptor_indexing || has_buffers) {
2200 // Note that the size of the input buffer is dependent on the maximum binding number, which
2201 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2202 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2203 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2204 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2205 uint32_t words_needed;
2206 if (descriptor_indexing) {
2207 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2208 } else {
2209 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2210 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002211 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2212 buffer_info.size = words_needed * 4;
2213 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2214 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002215 if (result != VK_SUCCESS) {
2216 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
2217 aborted = true;
2218 return;
2219 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002220
Tony-LunarGe29097a2020-12-03 10:59:19 -07002221 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2222 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2223 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002224 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2225 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002226
Tony-LunarGe29097a2020-12-03 10:59:19 -07002227 // Descriptor indexing needs the number of descriptors at each binding.
2228 if (descriptor_indexing) {
2229 // Pointer to a sets array that points into the sizes array
2230 uint32_t *sets_to_sizes = data_ptr + 1;
2231 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2232 uint32_t *sizes = sets_to_sizes + number_of_sets;
2233 // Pointer to another sets array that points into the bindings array that points into the written array
2234 uint32_t *sets_to_bindings = sizes + binding_count;
2235 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2236 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2237 // Index of the next entry in the written array to be updated
2238 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2239 uint32_t bind_counter = number_of_sets + 1;
2240 // Index of the start of the sets_to_bindings array
2241 data_ptr[0] = number_of_sets + binding_count + 1;
2242
John Zulauf79f06582021-02-27 18:38:39 -07002243 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002244 auto desc = s.bound_descriptor_set;
2245 if (desc && (desc->GetBindingCount() > 0)) {
2246 auto layout = desc->GetLayout();
2247 auto bindings = layout->GetSortedBindingSet();
2248 // For each set, fill in index of its bindings sizes in the sizes array
2249 *sets_to_sizes++ = bind_counter;
2250 // For each set, fill in the index of its bindings in the bindings_to_written array
2251 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
2252 for (auto binding : bindings) {
2253 // For each binding, fill in its size in the sizes array
2254 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2255 // uniform blocks
2256 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2257 sizes[binding] = 1;
2258 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
2259 sizes[binding] = desc->GetVariableDescriptorCount();
2260 } else {
2261 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
2262 }
2263 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2264 bindings_to_written[binding] = written_index;
2265
2266 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2267 // uniform blocks
2268 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2269 data_ptr[written_index++] = UINT_MAX;
2270 continue;
2271 }
2272
2273 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2274 // For each array element in the binding, update the written array with whether it has been written
2275 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2276 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2277 if (descriptor->updated) {
2278 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2279 } else if (desc->IsUpdateAfterBind(binding)) {
2280 // If it hasn't been written now and it's update after bind, put it in a list to check at
2281 // QueueSubmit
2282 di_input_block.update_at_submit[written_index] = descriptor;
2283 }
2284 written_index++;
2285 }
2286 }
2287 auto last = desc->GetLayout()->GetMaxBinding();
2288 bindings_to_written += last + 1;
2289 bind_counter += last + 1;
2290 sizes += last + 1;
2291 } else {
2292 *sets_to_sizes++ = 0;
2293 *sets_to_bindings++ = 0;
2294 }
2295 }
2296 } else {
2297 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2298 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2299
2300 // Pointer to sets array that points into the bindings array that points into the written array
2301 uint32_t *sets_to_bindings = data_ptr + 1;
2302 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2303 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2304 // Index of the next entry in the written array to be updated
2305 uint32_t written_index = 1 + number_of_sets + binding_count;
2306 uint32_t bind_counter = number_of_sets + 1;
2307 data_ptr[0] = 1;
2308
John Zulauf79f06582021-02-27 18:38:39 -07002309 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002310 auto desc = s.bound_descriptor_set;
2311 if (desc && (desc->GetBindingCount() > 0)) {
2312 auto layout = desc->GetLayout();
2313 auto bindings = layout->GetSortedBindingSet();
2314 *sets_to_bindings++ = bind_counter;
2315 for (auto binding : bindings) {
2316 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2317 bindings_to_written[binding] = written_index;
2318
2319 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2320 // uniform blocks
2321 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2322 data_ptr[written_index++] = UINT_MAX;
2323 continue;
2324 }
2325
2326 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2327
2328 // For each array element in the binding, update the written array with whether it has been written
2329 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2330 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2331 if (descriptor->updated) {
2332 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2333 } else if (desc->IsUpdateAfterBind(binding)) {
2334 // If it hasn't been written now and it's update after bind, put it in a list to check at
2335 // QueueSubmit
2336 di_input_block.update_at_submit[written_index] = descriptor;
2337 }
2338 written_index++;
2339 }
2340 }
2341 auto last = desc->GetLayout()->GetMaxBinding();
2342 bindings_to_written += last + 1;
2343 bind_counter += last + 1;
2344 } else {
2345 *sets_to_bindings++ = 0;
2346 }
2347 }
2348 }
2349 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2350
2351 di_input_desc_buffer_info.range = (words_needed * 4);
2352 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2353 di_input_desc_buffer_info.offset = 0;
2354
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002355 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002356 desc_writes[1].dstBinding = 1;
2357 desc_writes[1].descriptorCount = 1;
2358 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2359 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2360 desc_writes[1].dstSet = desc_sets[0];
2361
2362 desc_count = 2;
2363 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002364 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002365
sfricke-samsung45996a42021-09-16 13:45:27 -07002366 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2367 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
2368 buffer_map.size() && shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002369 // Example BDA input buffer assuming 2 buffers using BDA:
2370 // Word 0 | Index of start of buffer sizes (in this case 5)
2371 // Word 1 | 0x0000000000000000
2372 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2373 // Word 3 | Device Address of second buffer
2374 // Word 4 | 0xffffffffffffffff
2375 // Word 5 | 0 (size of pretend buffer at word 1)
2376 // Word 6 | Size in bytes of first buffer
2377 // Word 7 | Size in bytes of second buffer
2378 // Word 8 | 0 (size of pretend buffer in word 4)
2379
Tony-LunarG99b880b2019-09-26 11:19:52 -06002380 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002381 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002382 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2383 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06002384 result =
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002385 vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002386 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002387 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002388 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002389 return;
2390 }
2391 uint64_t *bda_data;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002392 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002393 uint32_t address_index = 1;
2394 uint32_t size_index = 3 + num_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002395 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002396 bda_data[0] = size_index; // Start of buffer sizes
2397 bda_data[address_index++] = 0; // NULL address
2398 bda_data[size_index++] = 0;
2399
John Zulauf79f06582021-02-27 18:38:39 -07002400 for (const auto &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002401 bda_data[address_index++] = value.first;
2402 bda_data[size_index++] = value.second;
2403 }
2404 bda_data[address_index] = UINTPTR_MAX;
2405 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06002406 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002407
2408 bda_input_desc_buffer_info.range = (words_needed * 8);
2409 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2410 bda_input_desc_buffer_info.offset = 0;
2411
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002412 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002413 desc_writes[desc_count].dstBinding = 2;
2414 desc_writes[desc_count].descriptorCount = 1;
2415 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2416 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2417 desc_writes[desc_count].dstSet = desc_sets[0];
2418 desc_count++;
2419 }
2420
Tony-LunarGb2501d22019-01-28 09:59:13 -07002421 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002422 output_desc_buffer_info.buffer = output_block.buffer;
2423 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002424
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002425 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002426 desc_writes[0].descriptorCount = 1;
2427 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2428 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2429 desc_writes[0].dstSet = desc_sets[0];
2430 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002431
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002432 const auto *pipeline_state = state.pipeline_state;
2433 if (pipeline_state) {
2434 if ((pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002435 !pipeline_state->pipeline_layout->Destroyed()) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002436 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002437 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002438 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002439 if (pipeline_state->pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002440 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2441 aborted = true;
2442 } else {
2443 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002444 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2445 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002446 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002447 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002448 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002449 aborted = true;
2450 }
2451 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002452 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2453 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2454 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002455 return;
2456 }
2457}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002458
2459std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2460 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002461 const COMMAND_POOL_STATE *pool) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002462 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<CMD_BUFFER_STATE_GPUAV>(this, cb, pCreateInfo, pool));
2463}
2464
2465CMD_BUFFER_STATE_GPUAV::CMD_BUFFER_STATE_GPUAV(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002466 const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002467 : CMD_BUFFER_STATE(ga, cb, pCreateInfo, pool) {}
2468
2469void CMD_BUFFER_STATE_GPUAV::Reset() {
2470 CMD_BUFFER_STATE::Reset();
2471 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2472 // Free the device memory and descriptor set(s) associated with a command buffer.
2473 if (gpuav->aborted) {
2474 return;
2475 }
2476 for (auto &buffer_info : gpuav_buffer_list) {
2477 gpuav->DestroyBuffer(buffer_info);
2478 }
2479 gpuav_buffer_list.clear();
2480
2481 for (auto &as_validation_buffer_info : as_validation_buffers) {
2482 gpuav->DestroyBuffer(as_validation_buffer_info);
2483 }
2484 as_validation_buffers.clear();
2485}