blob: 35369e98db7c4851ffd3c39f09911c6d5c80803d [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-LunarG1364cf52021-11-17 16:10:11 -07001101bool GpuAssisted::PreCallValidateCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1102 const VkDependencyInfo *pDependencyInfos) const {
1103 VkPipelineStageFlags2 srcStageMask = 0;
1104
1105 for (uint32_t i = 0; i < eventCount; i++) {
1106 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
1107 srcStageMask = stage_masks.src;
1108 }
1109
1110 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
1111 ReportSetupProblem(commandBuffer,
1112 "CmdWaitEvents2 recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1113 "GPU_Assisted validation waits on queue completion. "
1114 "This wait could block the host's signaling of this event, resulting in deadlock.");
1115 }
1116 ValidationStateTracker::PreCallValidateCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
1117 return false;
1118}
1119
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001120void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1121 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1122 // 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 -06001123 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001124 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1125 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1126 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001127 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1128 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001129 }
1130 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001131 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pPhysicalDeviceProperties);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001132}
1133
1134void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1135 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1136 // 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 -06001137 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001138 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1139 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1140 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001141 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1142 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001143 }
1144 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001145 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pPhysicalDeviceProperties2);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001146}
1147
1148void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1149 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1150 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1151 void *cgpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001152 if (aborted) return;
Karl Schultz7b024b42018-08-30 16:18:18 -06001153 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001154 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001155 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1156 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001157 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1158 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001159 ValidationStateTracker::PreCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1160 cgpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001161}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001162
1163void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1164 const VkComputePipelineCreateInfo *pCreateInfos,
1165 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1166 void *ccpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001167 if (aborted) return;
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001168 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001169 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001170 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1171 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001172 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1173 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001174 ValidationStateTracker::PreCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1175 ccpl_state_data);
Jason Macnak67407e72019-07-11 11:05:09 -07001176}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001177
1178void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1179 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1180 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1181 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001182 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001183 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001184 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001185 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1186 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001187 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1188 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001189 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1190 pPipelines, crtpl_state_data);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001191}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001192
sourav parmarcd5fb182020-07-17 12:58:44 -07001193void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1194 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001195 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1196 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1197 void *crtpl_state_data) {
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001198 if (aborted) return;
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001199 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1200 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001201 UtilPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1202 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001203 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1204 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001205 ValidationStateTracker::PreCallRecordCreateRayTracingPipelinesKHR(device, deferredOperation, pipelineCache, count, pCreateInfos,
1206 pAllocator, pPipelines, crtpl_state_data);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001207}
Karl Schultz7b024b42018-08-30 16:18:18 -06001208
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001209void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1210 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1211 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1212 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001213 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1214 pPipelines, result, cgpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001215 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001216 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
1217 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, cgpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001218 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001219}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001220
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001221void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1222 const VkComputePipelineCreateInfo *pCreateInfos,
1223 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1224 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001225 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1226 result, ccpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001227 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001228 create_compute_pipeline_api_state *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
1229 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, ccpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001230 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001231}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001232
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001233void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1234 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1235 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1236 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001237 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001238 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1239 pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001240 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001241 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001242 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001243}
1244
sourav parmarcd5fb182020-07-17 12:58:44 -07001245void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkDeferredOperationKHR deferredOperation,
1246 VkPipelineCache pipelineCache, uint32_t count,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001247 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1248 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1249 VkResult result, void *crtpl_state_data) {
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001250 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
sourav parmarcd5fb182020-07-17 12:58:44 -07001251 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(
1252 device, deferredOperation, pipelineCache, count, pCreateInfos, pAllocator, pPipelines, result, crtpl_state_data);
Tony-LunarG00e7b7d2021-06-30 12:59:43 -06001253 if (aborted) return;
Tony-LunarGc876c6e2020-09-09 15:19:43 -06001254 UtilCopyCreatePipelineFeedbackData(count, pCreateInfos, crtpl_state->gpu_create_infos.data());
Tony-LunarGb5fae462020-03-05 12:43:25 -07001255 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001256}
1257
1258// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001259void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001260 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001261 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001262 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001263 } else {
1264 ++it;
1265 }
1266 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001267 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001268}
1269
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001270void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1271 const VkAllocationCallbacks *pAllocator) {
1272 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(renderPass);
1273 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1274 DispatchDestroyPipeline(device, pipeline->second, nullptr);
1275 pre_draw_validation_state.renderpass_to_pipeline.erase(pipeline);
1276 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001277 ValidationStateTracker::PreCallRecordDestroyRenderPass(device, renderPass, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001278}
1279
Karl Schultz7b024b42018-08-30 16:18:18 -06001280// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001281bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001282 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001283 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001284 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1285
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001286 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001287 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1288 switch (level) {
1289 case SPV_MSG_FATAL:
1290 case SPV_MSG_INTERNAL_ERROR:
1291 case SPV_MSG_ERROR:
1292 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1293 position.index, message);
1294 break;
1295 default:
1296 break;
1297 }
1298 };
1299
Karl Schultz7b024b42018-08-30 16:18:18 -06001300 // Load original shader SPIR-V
1301 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1302 new_pgm.clear();
1303 new_pgm.reserve(num_words);
1304 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1305
1306 // Call the optimizer to instrument the shader.
1307 // 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 -07001308 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001309 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -07001310 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001311 spvtools::ValidatorOptions val_options;
1312 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1313 spvtools::OptimizerOptions opt_options;
1314 opt_options.set_run_validator(true);
1315 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001316 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001317 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001318 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001319 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Tony-LunarG57400d42021-10-14 11:18:43 -06001320 // Call CreateAggressiveDCEPass with preserve_interface == true
1321 optimizer.RegisterPass(CreateAggressiveDCEPass(true));
sfricke-samsung45996a42021-09-16 13:45:27 -07001322 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
1323 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
1324 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001325 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001326 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001327 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001328 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001329 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001330 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001331 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001332 return pass;
1333}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001334// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001335void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1336 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1337 void *csm_state_data) {
1338 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1339 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001340 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001341 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001342 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Karl Schultz7b024b42018-08-30 16:18:18 -06001343 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001344 ValidationStateTracker::PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, csm_state_data);
Karl Schultz7b024b42018-08-30 16:18:18 -06001345}
Tony-LunarG20678ff2021-05-07 14:56:26 -06001346
Tony-LunarG7345a062021-06-24 13:16:38 -06001347static const int kInstErrorPreDrawValidate = spvtools::kInstErrorMax + 1;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001348static const int kPreDrawValidateSubError = spvtools::kInstValidationOutError + 1;
Karl Schultz7b024b42018-08-30 16:18:18 -06001349// Generate the part of the message describing the violation.
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001350bool 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 -06001351 using namespace spvtools;
1352 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001353 bool return_code = true;
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001354 assert(kInstErrorPreDrawValidate == _kInstErrorPreDrawValidate);
1355 assert(kInstValidationOutError == _kInstValidationOutError);
Tony-LunarGab47cac2019-12-20 15:28:01 -07001356 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001357 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001358 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1359 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001360 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001361 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001362 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001363 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001364 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001365 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001366 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001367 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001368 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1369 vuid_msg = "UNASSIGNED-Device address out of bounds";
1370 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001371 case kInstErrorBuffOOBUniform:
1372 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001373 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1374 if (size == 0) {
1375 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1376 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1377 } else {
1378 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1379 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001380 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001381 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001382 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1383 vuid_msg = vuid.uniform_access_oob;
1384 else
1385 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001386 }
1387 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001388 case kInstErrorBuffOOBUniformTexel:
1389 case kInstErrorBuffOOBStorageTexel: {
1390 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1391 if (size == 0) {
1392 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1393 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001394 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001395 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001396 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1397 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001398 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001399 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1400 vuid_msg = vuid.uniform_access_oob;
1401 else
1402 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001403 }
Tony-LunarG63f82e02021-04-12 16:13:48 -06001404 } break;
1405 case kInstErrorPreDrawValidate: {
Tim Van Patten38bdcdd2021-05-14 16:41:00 -06001406 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001407 if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_bufsize_error) {
Tony-LunarG63f82e02021-04-12 16:13:48 -06001408 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001409 uint32_t stride = buf_info.pre_draw_resources.stride;
1410 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
1411 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
1412 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1413 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
1414 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
1415 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001416 if (count == 1) {
1417 vuid_msg = vuid.count_exceeds_bufsize_1;
1418 } else {
1419 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001420 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001421 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_limit_error) {
1422 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
1423 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1424 strm << "Indirect draw count of " << count << " would exceed maxDrawIndirectCount limit of "
1425 << gpu_assisted->phys_dev_props.limits.maxDrawIndirectCount;
1426 vuid_msg = vuid.count_exceeds_device_limit;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001427 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_first_instance_error) {
1428 uint32_t index = debug_record[kPreDrawValidateSubError + 1];
1429 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1430 strm << "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the "
1431 "VkDrawIndirectCommand structure at index "
1432 << index << " is not zero";
1433 vuid_msg = vuid.first_instance_not_zero;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001434 }
1435 return_code = false;
1436 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001437 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001438 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001439 vuid_msg = "UNASSIGNED-Internal Error";
1440 assert(false);
1441 } break;
1442 }
1443 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001444 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001445}
1446
Karl Schultz7b024b42018-08-30 16:18:18 -06001447// Pull together all the information from the debug record to build the error message strings,
1448// and then assemble them into a single message string.
1449// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1450// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1451// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1452// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1453//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001454void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001455 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001456 using namespace spvtools;
1457 const uint32_t total_words = debug_output_buffer[0];
1458 // A zero here means that the shader instrumentation didn't write anything.
1459 // If you have nothing to say, don't say it here.
1460 if (0 == total_words) {
1461 return;
1462 }
1463 // The first word in the debug output buffer is the number of words that would have
1464 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1465 // The number of words actually written by the shaders is determined by the size of the buffer
1466 // we provide via the descriptor. So, we process only the number of words that can fit in the
1467 // buffer.
1468 // Each "report" written by the shader instrumentation is considered a "record". This function
1469 // is hard-coded to process only one record because it expects the buffer to be large enough to
1470 // hold only one record. If there is a desire to process more than one record, this function needs
1471 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001472 std::string validation_message;
1473 std::string stage_message;
1474 std::string common_message;
1475 std::string filename_message;
1476 std::string source_message;
1477 std::string vuid_msg;
1478 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1479 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001480 std::vector<uint32_t> pgm;
Karl Schultz7b024b42018-08-30 16:18:18 -06001481 // The first record starts at this offset after the total_words.
1482 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1483 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1484 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001485 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1486 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001487 shader_module_handle = it->second.shader_module;
1488 pipeline_handle = it->second.pipeline;
1489 pgm = it->second.pgm;
1490 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001491 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info, this);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001492 if (gen_full_message) {
1493 UtilGenerateStageMessage(debug_record, stage_message);
1494 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1495 buffer_info.pipeline_bind_point, operation_index, common_message);
1496 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1497 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1498 filename_message.c_str(), source_message.c_str());
1499 }
1500 else {
1501 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1502 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001503 // The debug record at word kInstCommonOutSize is the number of words in the record
1504 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001505 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001506 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1507}
1508
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001509void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1510 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1511 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001512 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001513 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001514 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001515 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1516 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1517 }
1518 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1519 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001520 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001521 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001522 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001523 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1524 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1525 }
1526 } else {
1527 pData[index] = 1;
1528 }
1529}
1530
Tony-LunarG81efe392019-03-07 15:43:27 -07001531// 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 -06001532void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE_GPUAV *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001533 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001534 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001535 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001536 VkResult result =
1537 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001538 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001539 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001540 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001541 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001542 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001543 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001544 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001545 }
1546 }
1547 }
1548}
1549
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001550void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
1551 auto cb_node = GetCBState(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001552 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001553 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001554 UpdateInstrumentationBuffer(static_cast<CMD_BUFFER_STATE_GPUAV *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001555 }
1556}
1557
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001558void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001559 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001560 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1561 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1562 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001563 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001564 }
1565 }
1566}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001567
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001568void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1569 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001570 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001571 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1572 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1573 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1574 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1575 }
1576 }
1577}
1578
Tony-LunarG26fe2842021-11-16 14:07:59 -07001579void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1580 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1581 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1582 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1583 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1584 }
1585 }
1586}
1587
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001588bool GpuAssisted::CommandBufferNeedsProcessing(VkCommandBuffer command_buffer) {
1589 bool buffers_present = false;
1590 auto cb_node = GetCBState(command_buffer);
1591
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001592 if (cb_node->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001593 buffers_present = true;
1594 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001595 for (const auto *secondary : cb_node->linkedCommandBuffers) {
1596 auto secondary_cmd_buffer = static_cast<const CMD_BUFFER_STATE_GPUAV *>(secondary);
1597 if (secondary_cmd_buffer->gpuav_buffer_list.size() || cb_node->hasBuildAccelerationStructureCmd) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001598 buffers_present = true;
1599 }
1600 }
1601 return buffers_present;
1602}
1603
1604void GpuAssisted::ProcessCommandBuffer(VkQueue queue, VkCommandBuffer command_buffer) {
1605 auto cb_node = GetCBState(command_buffer);
1606
Jeremy Gebben9f537102021-10-05 16:37:12 -06001607 UtilProcessInstrumentationBuffer(queue, cb_node.get(), this);
1608 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001609 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001610 UtilProcessInstrumentationBuffer(queue, secondary_cmd_buffer, this);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001611 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node.get());
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001612 }
1613}
Tony-LunarG81efe392019-03-07 15:43:27 -07001614
Karl Schultz58674242019-01-22 15:35:02 -07001615// Issue a memory barrier to make GPU-written data available to host.
1616// Wait for the queue to complete execution.
1617// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001618void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1619 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001620 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001621
Mark Lobodzinski09379db2020-05-07 08:22:01 -06001622 if (aborted || (result != VK_SUCCESS)) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001623 bool buffers_present = false;
1624 // Don't QueueWaitIdle if there's nothing to process
1625 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1626 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1627 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001628 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBuffers[i]);
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001629 }
1630 }
1631 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001632
Tony-LunarGb5fae462020-03-05 12:43:25 -07001633 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001634
Tony-LunarG152a88b2019-03-20 15:42:24 -06001635 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001636
Karl Schultz7b024b42018-08-30 16:18:18 -06001637 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1638 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1639 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001640 ProcessCommandBuffer(queue, submit->pCommandBuffers[i]);
1641 }
1642 }
1643}
1644
Tony-LunarG26fe2842021-11-16 14:07:59 -07001645void GpuAssisted::RecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits,
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001646 VkFence fence, VkResult result) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001647 if (aborted || (result != VK_SUCCESS)) return;
1648 bool buffers_present = false;
1649 // Don't QueueWaitIdle if there's nothing to process
1650 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001651 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001652 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1653 buffers_present |= CommandBufferNeedsProcessing(submit->pCommandBufferInfos[i].commandBuffer);
1654 }
1655 }
1656 if (!buffers_present) return;
1657
1658 UtilSubmitBarrier(queue, this);
1659
1660 DispatchQueueWaitIdle(queue);
1661
1662 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
Tony-LunarG26fe2842021-11-16 14:07:59 -07001663 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001664 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1665 ProcessCommandBuffer(queue, submit->pCommandBufferInfos[i].commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001666 }
1667 }
1668}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001669
Tony-LunarG26fe2842021-11-16 14:07:59 -07001670void GpuAssisted::PostCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR* pSubmits,
1671 VkFence fence, VkResult result) {
1672 ValidationStateTracker::PostCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence, result);
1673 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1674}
1675
1676void GpuAssisted::PostCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits,
1677 VkFence fence, VkResult result) {
1678 ValidationStateTracker::PostCallRecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1679 RecordQueueSubmit2(queue, submitCount, pSubmits, fence, result);
1680}
1681
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001682void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1683 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001684 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001685 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001686}
1687
Tony-LunarG745150c2021-07-02 15:07:31 -06001688void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1689 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1690 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001691 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1692 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001693 for (uint32_t i = 0; i < drawCount; i++) {
1694 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1695 }
1696}
1697
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001698void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1699 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001700 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1701 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001702 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001703}
1704
Tony-LunarG745150c2021-07-02 15:07:31 -06001705void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1706 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1707 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001708 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1709 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001710 for (uint32_t i = 0; i < drawCount; i++) {
1711 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1712 }
1713}
1714
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001715void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1716 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001717 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001718 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1719 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001720}
1721
1722void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1723 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001724 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001725 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1726 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001727}
1728
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001729void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1730 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1731 uint32_t stride) {
1732 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1733 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001734 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001735 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001736}
1737
1738void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1739 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001740
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001741 uint32_t stride) {
1742 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1743 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001744 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1745 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001746}
1747
Tony-LunarG54176fb2020-12-02 10:47:22 -07001748void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1749 uint32_t firstInstance, VkBuffer counterBuffer,
1750 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1751 uint32_t vertexStride) {
1752 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1753 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001754 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001755}
1756
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001757void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1758 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1759 uint32_t maxDrawCount, uint32_t stride) {
1760 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1761 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001762 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001763 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001764}
1765
1766void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1767 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1768 uint32_t maxDrawCount, uint32_t stride) {
1769 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1770 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001771 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1772 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001773}
1774
1775void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1776 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001777 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001778}
1779
1780void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1781 uint32_t drawCount, uint32_t stride) {
1782 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001783 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001784}
1785
1786void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1787 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1788 uint32_t maxDrawCount, uint32_t stride) {
1789 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1790 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001791 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001792}
1793
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001794void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001795 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001796 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001797}
1798
1799void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001800 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001801 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001802}
1803
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001804void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1805 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1806 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001807 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1808 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001809 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001810}
1811
Tony-LunarG52c8c602020-09-10 16:29:56 -06001812void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1813 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1814 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001815 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1816 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001817 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001818}
1819
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001820void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1821 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1822 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1823 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1824 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1825 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1826 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001827 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1828 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1829 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1830 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1831 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001832 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001833}
1834
1835void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1836 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1837 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1838 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1839 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1840 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1841 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001842 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1843 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1844 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1845 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1846 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001847 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001848 cb_state->hasTraceRaysCmd = true;
1849}
1850
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001851void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001852 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1853 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1854 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1855 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001856 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001857 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1858 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001859 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001860}
1861
1862void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001863 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1864 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1865 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1866 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001867 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001868 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1869 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1870 depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001871 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001872 cb_state->hasTraceRaysCmd = true;
1873}
1874
1875void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001876 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1877 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1878 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1879 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001880 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001881 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1882 pHitShaderBindingTable, pCallableShaderBindingTable,
1883 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001884 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001885}
1886
1887void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001888 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1889 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1890 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1891 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001892 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001893 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1894 pHitShaderBindingTable, pCallableShaderBindingTable,
1895 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001896 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001897 cb_state->hasTraceRaysCmd = true;
1898}
1899
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001900// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001901// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1902// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001903#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001904void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1905 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001906 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001907 VkResult result;
1908 if (!pre_draw_validation_state.globals_created) {
1909 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001910 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1911 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001912 result =
1913 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001914 if (result != VK_SUCCESS) {
1915 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1916 aborted = true;
1917 return;
1918 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001919
1920 std::vector<VkDescriptorSetLayoutBinding> bindings;
1921 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1922 // 0 - output buffer, 1 - count buffer
1923 bindings.push_back(binding);
1924 binding.binding = 1;
1925 bindings.push_back(binding);
1926
1927 VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
1928 ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1929 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1930 ds_layout_ci.pBindings = bindings.data();
1931 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001932 if (result != VK_SUCCESS) {
1933 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1934 aborted = true;
1935 return;
1936 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001937
1938 const uint32_t push_constant_range_count = 1;
1939 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1940 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1941 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001942 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001943 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
1944 pipelineLayoutCreateInfo[0].sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
1945 pipelineLayoutCreateInfo[0].pNext = NULL;
1946 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1947 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1948 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1949 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1950 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1951 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001952 if (result != VK_SUCCESS) {
1953 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1954 aborted = true;
1955 return;
1956 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001957
1958 pre_draw_validation_state.globals_created = true;
1959 }
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06001960 VkRenderPass render_pass = state.pipeline_state->rp_state->renderPass();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001961 assert(render_pass != VK_NULL_HANDLE);
1962 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1963 if (pipeline == pre_draw_validation_state.renderpass_to_pipeline.end()) {
1964 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1965 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1966 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1967 pipeline_stage_ci.pName = "main";
1968
1969 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1970 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1971 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1972 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1973 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1974 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1975 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1976
1977 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1978 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1979 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1980 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1981 graphicsPipelineCreateInfo.renderPass = render_pass;
1982 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1983 graphicsPipelineCreateInfo.stageCount = 1;
1984 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1985
1986 VkPipeline new_pipeline = VK_NULL_HANDLE;
1987 result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &new_pipeline);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001988 if (result != VK_SUCCESS) {
1989 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1990 aborted = true;
1991 return;
1992 }
1993
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001994 *pPipeline = new_pipeline;
1995 pre_draw_validation_state.renderpass_to_pipeline[render_pass] = new_pipeline;
1996 } else {
1997 *pPipeline = pipeline->second;
1998 }
1999
2000 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
2001 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06002002 if (result != VK_SUCCESS) {
2003 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
2004 aborted = true;
2005 return;
2006 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002007
2008 VkDescriptorBufferInfo buffer_infos[3] = {};
2009 // Error output buffer
2010 buffer_infos[0].buffer = output_block.buffer;
2011 buffer_infos[0].offset = 0;
2012 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002013 if (cdi_state->count_buffer) {
2014 // Count buffer
2015 buffer_infos[1].buffer = cdi_state->count_buffer;
2016 } else {
2017 // Draw Buffer
2018 buffer_infos[1].buffer = cdi_state->buffer;
2019 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002020 buffer_infos[1].offset = 0;
2021 buffer_infos[1].range = VK_WHOLE_SIZE;
2022
2023 VkWriteDescriptorSet desc_writes[2] = {};
2024 for (auto i = 0; i < 2; i++) {
2025 desc_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2026 desc_writes[i].dstBinding = i;
2027 desc_writes[i].descriptorCount = 1;
2028 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2029 desc_writes[i].pBufferInfo = &buffer_infos[i];
2030 desc_writes[i].dstSet = resources.desc_set;
2031 }
2032 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
2033}
2034
Tony-LunarG7de10e82020-11-24 11:31:55 -07002035void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002036 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07002037 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
2038 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03002039 return;
2040 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002041 VkResult result;
2042
Tony-LunarG99b880b2019-09-26 11:19:52 -06002043 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002044
2045 std::vector<VkDescriptorSet> desc_sets;
2046 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06002047 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002048 assert(result == VK_SUCCESS);
2049 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002050 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002051 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002052 return;
2053 }
2054
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002055 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06002056 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002057
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06002058 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002059 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002060 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002061 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002062 return;
2063 }
2064
Tony-LunarG81efe392019-03-07 15:43:27 -07002065 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002066 GpuAssistedDeviceMemoryBlock output_block = {};
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002067 VkBufferCreateInfo buffer_info = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
2068 buffer_info.size = output_buffer_size;
2069 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
2070 VmaAllocationCreateInfo alloc_info = {};
2071 alloc_info.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
2072 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002073 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002074 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002075 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002076 return;
2077 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002078
Tony-LunarG81efe392019-03-07 15:43:27 -07002079 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002080 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002081 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06002082 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002083 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06002084 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002085 }
Tony-LunarG81efe392019-03-07 15:43:27 -07002086
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06002087 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002088 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
2089 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
2090 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002091 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002092 uint32_t desc_count = 1;
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002093 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
2094 auto const &state = cb_node->lastBound[lv_bind_point];
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002095 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002096
sfricke-samsung85584a72021-09-30 21:43:38 -07002097 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
2098 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002099 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
2100 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002101 // 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 -06002102 //
2103 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
2104 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
2105
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002106 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002107 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002108 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002109 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06002110 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002111
2112 // Save current graphics pipeline state
2113 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06002114 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002115
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002116 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002117 pre_draw_resources.buffer = cdi_state->buffer;
2118 pre_draw_resources.offset = cdi_state->offset;
2119 pre_draw_resources.stride = cdi_state->stride;
2120
2121 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07002122 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
2123 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002124 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
2125 ReportSetupProblem(device,
2126 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
2127 aborted = true;
2128 return;
2129 }
2130
2131 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
2132 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07002133 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002134 struct_size = sizeof(VkDrawIndirectCommand);
2135 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07002136 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002137 struct_size = sizeof(VkDrawIndexedIndirectCommand);
2138 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06002139 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06002140 uint32_t max_count;
2141 uint64_t bufsize = buffer_state->createInfo.size;
2142 uint64_t first_command_bytes = struct_size + cdi_state->offset;
2143 if (first_command_bytes > bufsize) {
2144 max_count = 0;
2145 } else {
2146 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
2147 }
2148 pre_draw_resources.buf_size = buffer_state->createInfo.size;
2149
2150 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
2151 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
2152 pushConstants[1] = max_count;
2153 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
2154 } else {
2155 pushConstants[0] = 0; // firstInstance check instead of count buffer check
2156 pushConstants[1] = cdi_state->drawCount;
2157 if (cmd_type == CMD_DRAWINDIRECT) {
2158 pushConstants[2] = static_cast<uint32_t>(
2159 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2160 } else {
2161 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
2162 pushConstants[2] = static_cast<uint32_t>(
2163 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
2164 }
2165 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
2166 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06002167
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002168 // Insert diagnostic draw
2169 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06002170 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
2171 sizeof(pushConstants), pushConstants);
2172 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
2173 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
2174 nullptr);
2175 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
2176
2177 // Restore the previous graphics pipeline state.
2178 restorable_state.Restore(cmd_buffer);
2179 }
2180
Tony-LunarGe29097a2020-12-03 10:59:19 -07002181 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07002182 // Figure out how much memory we need for the input block based on how many sets and bindings there are
2183 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002184 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07002185 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
2186 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07002187 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05002188 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06002189 if (desc && (desc->GetBindingCount() > 0)) {
2190 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07002191 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
2192 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002193 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
2194 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07002195 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
2196 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06002197 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07002198 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
2199 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
2200 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06002201 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07002202 descriptor_count += desc->GetVariableDescriptorCount();
2203 } else {
2204 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
2205 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07002206 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
2207 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
2208 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07002209 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2210 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2211 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002212 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002213 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002214 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002215 }
2216 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002217
Tony-LunarGe29097a2020-12-03 10:59:19 -07002218 if (descriptor_indexing || has_buffers) {
2219 // Note that the size of the input buffer is dependent on the maximum binding number, which
2220 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2221 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2222 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2223 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2224 uint32_t words_needed;
2225 if (descriptor_indexing) {
2226 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2227 } else {
2228 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2229 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002230 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2231 buffer_info.size = words_needed * 4;
2232 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2233 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002234 if (result != VK_SUCCESS) {
2235 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
2236 aborted = true;
2237 return;
2238 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002239
Tony-LunarGe29097a2020-12-03 10:59:19 -07002240 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2241 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2242 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002243 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2244 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002245
Tony-LunarGe29097a2020-12-03 10:59:19 -07002246 // Descriptor indexing needs the number of descriptors at each binding.
2247 if (descriptor_indexing) {
2248 // Pointer to a sets array that points into the sizes array
2249 uint32_t *sets_to_sizes = data_ptr + 1;
2250 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2251 uint32_t *sizes = sets_to_sizes + number_of_sets;
2252 // Pointer to another sets array that points into the bindings array that points into the written array
2253 uint32_t *sets_to_bindings = sizes + binding_count;
2254 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2255 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2256 // Index of the next entry in the written array to be updated
2257 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2258 uint32_t bind_counter = number_of_sets + 1;
2259 // Index of the start of the sets_to_bindings array
2260 data_ptr[0] = number_of_sets + binding_count + 1;
2261
John Zulauf79f06582021-02-27 18:38:39 -07002262 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002263 auto desc = s.bound_descriptor_set;
2264 if (desc && (desc->GetBindingCount() > 0)) {
2265 auto layout = desc->GetLayout();
2266 auto bindings = layout->GetSortedBindingSet();
2267 // For each set, fill in index of its bindings sizes in the sizes array
2268 *sets_to_sizes++ = bind_counter;
2269 // For each set, fill in the index of its bindings in the bindings_to_written array
2270 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
2271 for (auto binding : bindings) {
2272 // For each binding, fill in its size in the sizes array
2273 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2274 // uniform blocks
2275 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2276 sizes[binding] = 1;
2277 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
2278 sizes[binding] = desc->GetVariableDescriptorCount();
2279 } else {
2280 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
2281 }
2282 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2283 bindings_to_written[binding] = written_index;
2284
2285 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2286 // uniform blocks
2287 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2288 data_ptr[written_index++] = UINT_MAX;
2289 continue;
2290 }
2291
2292 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2293 // For each array element in the binding, update the written array with whether it has been written
2294 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2295 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2296 if (descriptor->updated) {
2297 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2298 } else if (desc->IsUpdateAfterBind(binding)) {
2299 // If it hasn't been written now and it's update after bind, put it in a list to check at
2300 // QueueSubmit
2301 di_input_block.update_at_submit[written_index] = descriptor;
2302 }
2303 written_index++;
2304 }
2305 }
2306 auto last = desc->GetLayout()->GetMaxBinding();
2307 bindings_to_written += last + 1;
2308 bind_counter += last + 1;
2309 sizes += last + 1;
2310 } else {
2311 *sets_to_sizes++ = 0;
2312 *sets_to_bindings++ = 0;
2313 }
2314 }
2315 } else {
2316 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2317 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2318
2319 // Pointer to sets array that points into the bindings array that points into the written array
2320 uint32_t *sets_to_bindings = data_ptr + 1;
2321 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2322 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2323 // Index of the next entry in the written array to be updated
2324 uint32_t written_index = 1 + number_of_sets + binding_count;
2325 uint32_t bind_counter = number_of_sets + 1;
2326 data_ptr[0] = 1;
2327
John Zulauf79f06582021-02-27 18:38:39 -07002328 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002329 auto desc = s.bound_descriptor_set;
2330 if (desc && (desc->GetBindingCount() > 0)) {
2331 auto layout = desc->GetLayout();
2332 auto bindings = layout->GetSortedBindingSet();
2333 *sets_to_bindings++ = bind_counter;
2334 for (auto binding : bindings) {
2335 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2336 bindings_to_written[binding] = written_index;
2337
2338 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2339 // uniform blocks
2340 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2341 data_ptr[written_index++] = UINT_MAX;
2342 continue;
2343 }
2344
2345 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2346
2347 // For each array element in the binding, update the written array with whether it has been written
2348 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2349 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2350 if (descriptor->updated) {
2351 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2352 } else if (desc->IsUpdateAfterBind(binding)) {
2353 // If it hasn't been written now and it's update after bind, put it in a list to check at
2354 // QueueSubmit
2355 di_input_block.update_at_submit[written_index] = descriptor;
2356 }
2357 written_index++;
2358 }
2359 }
2360 auto last = desc->GetLayout()->GetMaxBinding();
2361 bindings_to_written += last + 1;
2362 bind_counter += last + 1;
2363 } else {
2364 *sets_to_bindings++ = 0;
2365 }
2366 }
2367 }
2368 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2369
2370 di_input_desc_buffer_info.range = (words_needed * 4);
2371 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2372 di_input_desc_buffer_info.offset = 0;
2373
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002374 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002375 desc_writes[1].dstBinding = 1;
2376 desc_writes[1].descriptorCount = 1;
2377 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2378 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2379 desc_writes[1].dstSet = desc_sets[0];
2380
2381 desc_count = 2;
2382 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002383 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002384
sfricke-samsung45996a42021-09-16 13:45:27 -07002385 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2386 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
2387 buffer_map.size() && shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002388 // Example BDA input buffer assuming 2 buffers using BDA:
2389 // Word 0 | Index of start of buffer sizes (in this case 5)
2390 // Word 1 | 0x0000000000000000
2391 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2392 // Word 3 | Device Address of second buffer
2393 // Word 4 | 0xffffffffffffffff
2394 // Word 5 | 0 (size of pretend buffer at word 1)
2395 // Word 6 | Size in bytes of first buffer
2396 // Word 7 | Size in bytes of second buffer
2397 // Word 8 | 0 (size of pretend buffer in word 4)
2398
Tony-LunarG99b880b2019-09-26 11:19:52 -06002399 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002400 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002401 alloc_info.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
2402 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06002403 result =
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002404 vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002405 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002406 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06002407 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002408 return;
2409 }
2410 uint64_t *bda_data;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002411 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002412 uint32_t address_index = 1;
2413 uint32_t size_index = 3 + num_buffers;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002414 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002415 bda_data[0] = size_index; // Start of buffer sizes
2416 bda_data[address_index++] = 0; // NULL address
2417 bda_data[size_index++] = 0;
2418
John Zulauf79f06582021-02-27 18:38:39 -07002419 for (const auto &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002420 bda_data[address_index++] = value.first;
2421 bda_data[size_index++] = value.second;
2422 }
2423 bda_data[address_index] = UINTPTR_MAX;
2424 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06002425 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002426
2427 bda_input_desc_buffer_info.range = (words_needed * 8);
2428 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2429 bda_input_desc_buffer_info.offset = 0;
2430
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002431 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002432 desc_writes[desc_count].dstBinding = 2;
2433 desc_writes[desc_count].descriptorCount = 1;
2434 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2435 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2436 desc_writes[desc_count].dstSet = desc_sets[0];
2437 desc_count++;
2438 }
2439
Tony-LunarGb2501d22019-01-28 09:59:13 -07002440 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002441 output_desc_buffer_info.buffer = output_block.buffer;
2442 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002443
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002444 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002445 desc_writes[0].descriptorCount = 1;
2446 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2447 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2448 desc_writes[0].dstSet = desc_sets[0];
2449 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002450
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002451 const auto *pipeline_state = state.pipeline_state;
2452 if (pipeline_state) {
2453 if ((pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index) &&
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002454 !pipeline_state->pipeline_layout->Destroyed()) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -06002455 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002456 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002457 }
Jeremy Gebben9efe1cf2021-05-15 20:05:09 -06002458 if (pipeline_state->pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002459 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2460 aborted = true;
2461 } else {
2462 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002463 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2464 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002465 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002466 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002467 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002468 aborted = true;
2469 }
2470 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002471 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2472 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2473 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002474 return;
2475 }
2476}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002477
2478std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2479 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002480 const COMMAND_POOL_STATE *pool) {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002481 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<CMD_BUFFER_STATE_GPUAV>(this, cb, pCreateInfo, pool));
2482}
2483
2484CMD_BUFFER_STATE_GPUAV::CMD_BUFFER_STATE_GPUAV(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002485 const COMMAND_POOL_STATE *pool)
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002486 : CMD_BUFFER_STATE(ga, cb, pCreateInfo, pool) {}
2487
2488void CMD_BUFFER_STATE_GPUAV::Reset() {
2489 CMD_BUFFER_STATE::Reset();
2490 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2491 // Free the device memory and descriptor set(s) associated with a command buffer.
2492 if (gpuav->aborted) {
2493 return;
2494 }
2495 for (auto &buffer_info : gpuav_buffer_list) {
2496 gpuav->DestroyBuffer(buffer_info);
2497 }
2498 gpuav_buffer_list.clear();
2499
2500 for (auto &as_validation_buffer_info : as_validation_buffers) {
2501 gpuav->DestroyBuffer(as_validation_buffer_info);
2502 }
2503 as_validation_buffers.clear();
2504}