blob: aefbb3d6ab93288340e32170d0ca7f5ec04385df [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
Tony-LunarG5c38b182020-06-10 16:15:32 -0600187bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
188 bool result =
189 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
190 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
191 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
192 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
193 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
194 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
195 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
196 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
197 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
198 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
199 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
200 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
201 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
202 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
203 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
204 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
205 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
206 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
207 enabled_features.core12.descriptorBindingPartiallyBound ||
208 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
209 return result;
210}
211
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600212void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
213 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700214 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
215 // acceleration structure build validation will find and replace invalid acceleration structure
216 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600217 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
218 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
219 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700220 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600221
222 // Validating DrawIndirectCount countBuffer will require validation shader to bind the count buffer as a storage buffer
Tony-LunarG3723a3a2021-05-04 14:52:39 -0600223 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 -0600224 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
225 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600226 ValidationStateTracker::PreCallRecordCreateBuffer(device, pCreateInfo, pAllocator, pBuffer, cb_state_data);
Jason Macnak83cfd582019-07-31 10:14:24 -0700227}
Karl Schultz7b024b42018-08-30 16:18:18 -0600228// Perform initializations that can be done at Create Device time.
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600229void GpuAssisted::CreateDevice(const VkDeviceCreateInfo *pCreateInfo) {
Jeremy Gebben33717862022-03-28 15:53:56 -0600230 // GpuAssistedBase::CreateDevice will set up bindings
231 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
232 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
233 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
234 kShaderStageAllRayTracing,
235 NULL};
236 bindings_.push_back(binding);
237 for (auto i = 1; i < 3; i++) {
238 binding.binding = i;
239 bindings_.push_back(binding);
240 }
241 GpuAssistedBase::CreateDevice(pCreateInfo);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600242
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600243 if (enabled_features.core.robustBufferAccess || enabled_features.robustness2_features.robustBufferAccess2) {
244 buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700245 } else {
Tony-LunarGbcfeccf2022-04-19 09:14:35 -0600246 buffer_oob_enabled = GpuGetOption("khronos_validation.gpuav_buffer_oob", true);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700247 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600248
Tony-LunarGbcfeccf2022-04-19 09:14:35 -0600249 bool validate_descriptor_indexing = GpuGetOption("khronos_validation.gpuav_descriptor_indexing", true);
250 validate_draw_indirect = GpuGetOption("khronos_validation.validate_draw_indirect", true);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600251
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600252 if (phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700253 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600254 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600255 return;
256 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600257
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600258 DispatchGetPhysicalDeviceFeatures(physical_device, &supported_features);
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600259 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700260 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600261 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
262 "GPU-Assisted Validation disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600263 aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600264 return;
265 }
266
sfricke-samsung45996a42021-09-16 13:45:27 -0700267 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
268 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600269 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700270 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
271 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600272 }
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600273 shaderInt64 = supported_features.shaderInt64;
274 output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600275 if (validate_descriptor_indexing) {
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600276 descriptor_indexing = CheckForDescriptorIndexing(enabled_features);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600277 }
Tony-LunarG3b1c19f2022-05-02 14:11:06 -0600278 bool use_linear_output_pool = GpuGetOption("khronos_validation.vma_linear_output", true);
Tony-LunarG20d18a72022-04-19 11:01:47 -0600279 if (use_linear_output_pool) {
280 auto output_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
281 output_buffer_create_info.size = output_buffer_size;
282 output_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
283 VmaAllocationCreateInfo alloc_create_info = {};
284 alloc_create_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
285 uint32_t mem_type_index;
286 vmaFindMemoryTypeIndexForBufferInfo(vmaAllocator, &output_buffer_create_info, &alloc_create_info, &mem_type_index);
287 VmaPoolCreateInfo pool_create_info = {};
288 pool_create_info.memoryTypeIndex = mem_type_index;
289 pool_create_info.blockSize = 0;
290 pool_create_info.maxBlockCount = 0;
291 pool_create_info.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
292 VkResult result = vmaCreatePool(vmaAllocator, &pool_create_info, &output_buffer_pool);
293 if (result != VK_SUCCESS) {
294 ReportSetupProblem(device, "Unable to create VMA memory pool");
295 }
296 }
297
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600298 CreateAccelerationStructureBuildValidationState();
Karl Schultz7b024b42018-08-30 16:18:18 -0600299}
300
301// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600302void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600303 DestroyAccelerationStructureBuildValidationState();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600304 if (pre_draw_validation_state.globals_created) {
305 DispatchDestroyShaderModule(device, pre_draw_validation_state.validation_shader_module, nullptr);
306 DispatchDestroyDescriptorSetLayout(device, pre_draw_validation_state.validation_ds_layout, nullptr);
307 DispatchDestroyPipelineLayout(device, pre_draw_validation_state.validation_pipeline_layout, nullptr);
Jeremy Gebbenbba39212022-03-29 16:39:06 -0600308 auto to_destroy = pre_draw_validation_state.renderpass_to_pipeline.snapshot();
309 for (auto &entry: to_destroy) {
310 DispatchDestroyPipeline(device, entry.second, nullptr);
311 pre_draw_validation_state.renderpass_to_pipeline.erase(entry.first);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600312 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600313 pre_draw_validation_state.globals_created = false;
314 }
Tony-LunarG20d18a72022-04-19 11:01:47 -0600315 if (output_buffer_pool) {
316 vmaDestroyPool(vmaAllocator, output_buffer_pool);
317 }
Jeremy Gebben33717862022-03-28 15:53:56 -0600318 GpuAssistedBase::PreCallRecordDestroyDevice(device, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -0600319}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600320
Jeremy Gebben21782012022-03-15 16:23:27 -0600321void GpuAssisted::CreateAccelerationStructureBuildValidationState() {
322 if (aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700323 return;
324 }
325
Jeremy Gebben21782012022-03-15 16:23:27 -0600326 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700327 if (as_validation_state.initialized) {
328 return;
329 }
330
sfricke-samsung45996a42021-09-16 13:45:27 -0700331 if (!IsExtEnabled(device_extensions.vk_nv_ray_tracing)) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700332 return;
333 }
334
335 // Outline:
336 // - Create valid bottom level acceleration structure which acts as replacement
337 // - Create and load vertex buffer
338 // - Create and load index buffer
339 // - Create, allocate memory for, and bind memory for acceleration structure
340 // - Query acceleration structure handle
341 // - Create command pool and command buffer
342 // - Record build acceleration structure command
343 // - Submit command buffer and wait for completion
344 // - Cleanup
345 // - Create compute pipeline for validating instance buffers
346 // - Create descriptor set layout
347 // - Create pipeline layout
348 // - Create pipeline
349 // - Cleanup
350
351 VkResult result = VK_SUCCESS;
352
353 VkBuffer vbo = VK_NULL_HANDLE;
354 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
355 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600356 auto vbo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700357 vbo_ci.size = sizeof(float) * 9;
358 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
359
360 VmaAllocationCreateInfo vbo_ai = {};
361 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
362 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
363
Jeremy Gebben21782012022-03-15 16:23:27 -0600364 result = vmaCreateBuffer(vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700365 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700366 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700367 }
368 }
369
370 if (result == VK_SUCCESS) {
371 uint8_t *mapped_vbo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600372 result = vmaMapMemory(vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700373 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700374 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700375 } else {
376 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
377 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600378 vmaUnmapMemory(vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700379 }
380 }
381
382 VkBuffer ibo = VK_NULL_HANDLE;
383 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
384 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600385 auto ibo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700386 ibo_ci.size = sizeof(uint32_t) * 3;
387 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
388
389 VmaAllocationCreateInfo ibo_ai = {};
390 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
391 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
392
Jeremy Gebben21782012022-03-15 16:23:27 -0600393 result = vmaCreateBuffer(vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700394 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700395 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700396 }
397 }
398
399 if (result == VK_SUCCESS) {
400 uint8_t *mapped_ibo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600401 result = vmaMapMemory(vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700402 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700403 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700404 } else {
405 const std::vector<uint32_t> indicies = {0, 1, 2};
406 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600407 vmaUnmapMemory(vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700408 }
409 }
410
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600411 auto geometry = LvlInitStruct<VkGeometryNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700412 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600413 geometry.geometry.triangles = LvlInitStruct<VkGeometryTrianglesNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700414 geometry.geometry.triangles.vertexData = vbo;
415 geometry.geometry.triangles.vertexOffset = 0;
416 geometry.geometry.triangles.vertexCount = 3;
417 geometry.geometry.triangles.vertexStride = 12;
418 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
419 geometry.geometry.triangles.indexData = ibo;
420 geometry.geometry.triangles.indexOffset = 0;
421 geometry.geometry.triangles.indexCount = 3;
422 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
423 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
424 geometry.geometry.triangles.transformOffset = 0;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600425 geometry.geometry.aabbs = LvlInitStruct<VkGeometryAABBNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700426
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600427 auto as_ci = LvlInitStruct<VkAccelerationStructureCreateInfoNV>();
428 as_ci.info = LvlInitStruct<VkAccelerationStructureInfoNV>();
Tony-LunarG80fecea2022-06-28 10:05:21 -0600429 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700430 as_ci.info.instanceCount = 0;
431 as_ci.info.geometryCount = 1;
432 as_ci.info.pGeometries = &geometry;
433 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600434 result = DispatchCreateAccelerationStructureNV(device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700435 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600436 ReportSetupProblem(device, "Failed to create acceleration structure for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700437 }
438 }
439
440 VkMemoryRequirements2 as_mem_requirements = {};
441 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600442 auto as_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700443 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
444 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
445
Jeremy Gebben21782012022-03-15 16:23:27 -0600446 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700447 }
448
449 VmaAllocationInfo as_memory_ai = {};
450 if (result == VK_SUCCESS) {
451 VmaAllocationCreateInfo as_memory_aci = {};
452 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
453
Jeremy Gebben21782012022-03-15 16:23:27 -0600454 result = vmaAllocateMemory(vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
Tony-LunarG99b880b2019-09-26 11:19:52 -0600455 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700456 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600457 ReportSetupProblem(device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700458 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
459 }
460 }
461
462 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600463 auto as_bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700464 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
465 as_bind_info.memory = as_memory_ai.deviceMemory;
466 as_bind_info.memoryOffset = as_memory_ai.offset;
467
Jeremy Gebben21782012022-03-15 16:23:27 -0600468 result = DispatchBindAccelerationStructureMemoryNV(device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700469 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600470 ReportSetupProblem(device, "Failed to bind acceleration structure memory for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700471 }
472 }
473
474 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600475 result = DispatchGetAccelerationStructureHandleNV(device, as_validation_state.replacement_as, sizeof(uint64_t),
476 &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700477 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600478 ReportSetupProblem(device, "Failed to get acceleration structure handle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700479 }
480 }
481
482 VkMemoryRequirements2 scratch_mem_requirements = {};
483 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600484 auto scratch_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700485 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
486 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
487
Jeremy Gebben21782012022-03-15 16:23:27 -0600488 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_mem_requirements_info, &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700489 }
490
491 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600492 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700493 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600494 auto scratch_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700495 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
496 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700497 VmaAllocationCreateInfo scratch_aci = {};
498 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
499
Jeremy Gebben21782012022-03-15 16:23:27 -0600500 result = vmaCreateBuffer(vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700501 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600502 ReportSetupProblem(device, "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700503 }
504 }
505
506 VkCommandPool command_pool = VK_NULL_HANDLE;
507 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600508 auto command_pool_ci = LvlInitStruct<VkCommandPoolCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700509 command_pool_ci.queueFamilyIndex = 0;
510
Jeremy Gebben21782012022-03-15 16:23:27 -0600511 result = DispatchCreateCommandPool(device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700512 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600513 ReportSetupProblem(device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700514 }
515 }
516
517 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
518
519 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600520 auto command_buffer_ai = LvlInitStruct<VkCommandBufferAllocateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700521 command_buffer_ai.commandPool = command_pool;
522 command_buffer_ai.commandBufferCount = 1;
523 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
524
Jeremy Gebben21782012022-03-15 16:23:27 -0600525 result = DispatchAllocateCommandBuffers(device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700526 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600527 ReportSetupProblem(device, "Failed to create command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700528 }
529
530 // Hook up command buffer dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600531 vkSetDeviceLoaderData(device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700532 }
533
534 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600535 auto command_buffer_bi = LvlInitStruct<VkCommandBufferBeginInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700536
537 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
538 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600539 ReportSetupProblem(device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700540 }
541 }
542
543 if (result == VK_SUCCESS) {
544 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
545 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
546 DispatchEndCommandBuffer(command_buffer);
547 }
548
549 VkQueue queue = VK_NULL_HANDLE;
550 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600551 DispatchGetDeviceQueue(device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700552
553 // Hook up queue dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600554 vkSetDeviceLoaderData(device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700555
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600556 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700557 submit_info.commandBufferCount = 1;
558 submit_info.pCommandBuffers = &command_buffer;
559 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
560 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600561 ReportSetupProblem(device, "Failed to submit command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700562 }
563 }
564
565 if (result == VK_SUCCESS) {
566 result = DispatchQueueWaitIdle(queue);
567 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600568 ReportSetupProblem(device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700569 }
570 }
571
572 if (vbo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600573 vmaDestroyBuffer(vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700574 }
575 if (ibo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600576 vmaDestroyBuffer(vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700577 }
578 if (scratch != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600579 vmaDestroyBuffer(vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700580 }
581 if (command_pool != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600582 DispatchDestroyCommandPool(device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700583 }
584
Jeremy Gebben21782012022-03-15 16:23:27 -0600585 if (debug_desc_layout == VK_NULL_HANDLE) {
586 ReportSetupProblem(device, "Failed to find descriptor set layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700587 result = VK_INCOMPLETE;
588 }
589
590 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600591 auto pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700592 pipeline_layout_ci.setLayoutCount = 1;
Jeremy Gebben21782012022-03-15 16:23:27 -0600593 pipeline_layout_ci.pSetLayouts = &debug_desc_layout;
594 result = DispatchCreatePipelineLayout(device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700595 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600596 ReportSetupProblem(device, "Failed to create pipeline layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700597 }
598 }
599
600 VkShaderModule shader_module = VK_NULL_HANDLE;
601 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600602 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700603 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
604 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
605
Jeremy Gebben21782012022-03-15 16:23:27 -0600606 result = DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700607 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600608 ReportSetupProblem(device, "Failed to create compute shader module for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700609 }
610 }
611
612 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600613 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700614 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
615 pipeline_stage_ci.module = shader_module;
616 pipeline_stage_ci.pName = "main";
617
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600618 auto pipeline_ci = LvlInitStruct<VkComputePipelineCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700619 pipeline_ci.stage = pipeline_stage_ci;
620 pipeline_ci.layout = as_validation_state.pipeline_layout;
621
Jeremy Gebben21782012022-03-15 16:23:27 -0600622 result = DispatchCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr, &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700623 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600624 ReportSetupProblem(device, "Failed to create compute pipeline for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700625 }
626 }
627
628 if (shader_module != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600629 DispatchDestroyShaderModule(device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700630 }
631
632 if (result == VK_SUCCESS) {
633 as_validation_state.initialized = true;
Jeremy Gebben21782012022-03-15 16:23:27 -0600634 LogInfo(device, "UNASSIGNED-GPU-Assisted Validation.", "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700635 } else {
Jeremy Gebben21782012022-03-15 16:23:27 -0600636 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700637 }
638}
639
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600640void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600641 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700642 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
643 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
644 }
645 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
646 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
647 }
648 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
649 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
650 }
651 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600652 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700653 }
654}
655
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600656struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700657 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
658 VkPipeline pipeline = VK_NULL_HANDLE;
659 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
660 std::vector<VkDescriptorSet> descriptor_sets;
661 std::vector<std::vector<uint32_t>> dynamic_offsets;
662 uint32_t push_descriptor_set_index = 0;
663 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
664 std::vector<uint8_t> push_constants_data;
665 PushConstantRangesId push_constants_ranges;
666
667 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
668 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600669 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700670
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600671 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700672 if (last_bound.pipeline_state) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600673 pipeline = last_bound.pipeline_state->pipeline();
Jason Macnak83cfd582019-07-31 10:14:24 -0700674 pipeline_layout = last_bound.pipeline_layout;
675 descriptor_sets.reserve(last_bound.per_set.size());
676 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700677 const auto &bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
ziga-lunarge0b552b2021-09-05 21:39:57 +0200678 if (bound_descriptor_set) {
679 descriptor_sets.push_back(bound_descriptor_set->GetSet());
680 if (bound_descriptor_set->IsPushDescriptor()) {
681 push_descriptor_set_index = static_cast<uint32_t>(i);
682 }
683 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
Jason Macnak83cfd582019-07-31 10:14:24 -0700684 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700685 }
686
687 if (last_bound.push_descriptor_set) {
688 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
689 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700690 const auto &pipeline_layout = last_bound.pipeline_state->PipelineLayoutState();
691 if (pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700692 push_constants_data = cb_state->push_constant_data;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700693 push_constants_ranges = pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700694 }
695 }
696 }
697
698 void Restore(VkCommandBuffer command_buffer) const {
699 if (pipeline != VK_NULL_HANDLE) {
700 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
701 if (!descriptor_sets.empty()) {
702 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
703 VkDescriptorSet descriptor_set = descriptor_sets[i];
704 if (descriptor_set != VK_NULL_HANDLE) {
705 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
706 static_cast<uint32_t>(i), 1, &descriptor_set,
707 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
708 }
709 }
710 }
711 if (!push_descriptor_set_writes.empty()) {
712 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
713 static_cast<uint32_t>(push_descriptor_set_writes.size()),
714 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
715 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600716 if (!push_constants_data.empty()) {
717 for (const auto &push_constant_range : *push_constants_ranges) {
718 if (push_constant_range.size == 0) continue;
719 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
720 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
721 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700722 }
723 }
724 }
725};
726
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600727void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
728 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
729 VkDeviceSize instanceOffset, VkBool32 update,
730 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
731 VkBuffer scratch, VkDeviceSize scratchOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600732 ValidationStateTracker::PreCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update,
733 dst, src, scratch, scratchOffset);
Jason Macnak83cfd582019-07-31 10:14:24 -0700734 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
735 return;
736 }
737
Tony-LunarG99b880b2019-09-26 11:19:52 -0600738 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700739 if (!as_validation_state.initialized) {
740 return;
741 }
742
743 // Empty acceleration structure is valid according to the spec.
744 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
745 return;
746 }
747
Jeremy Gebben04697b02022-03-23 16:18:12 -0600748 auto cb_state = GetWrite<gpuav_state::CommandBuffer>(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700749 assert(cb_state != nullptr);
750
751 std::vector<uint64_t> current_valid_handles;
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600752 ForEach<ACCELERATION_STRUCTURE_STATE>([&current_valid_handles](const ACCELERATION_STRUCTURE_STATE &as_state) {
Jeff Bolz95176d02020-04-01 00:36:16 -0500753 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700754 current_valid_handles.push_back(as_state.opaque_handle);
755 }
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600756 });
Jason Macnak83cfd582019-07-31 10:14:24 -0700757
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600758 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700759 as_validation_buffer_info.acceleration_structure = dst;
760
761 const VkDeviceSize validation_buffer_size =
762 // One uint for number of instances to validate
763 4 +
764 // Two uint for the replacement acceleration structure handle
765 8 +
766 // One uint for number of invalid handles found
767 4 +
768 // Two uint for the first invalid handle found
769 8 +
770 // One uint for the number of current valid handles
771 4 +
772 // Two uint for each current valid handle
773 (8 * current_valid_handles.size());
774
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600775 auto validation_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700776 validation_buffer_create_info.size = validation_buffer_size;
777 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
778
779 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
780 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
781
Tony-LunarG99b880b2019-09-26 11:19:52 -0600782 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
783 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700784 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
785 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700786 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600787 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700788 return;
789 }
790
791 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700792 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
793 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700794 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700795 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600796 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700797 return;
798 }
799
800 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
801 mapped_validation_buffer->replacement_handle_bits_0 =
802 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
803 mapped_validation_buffer->replacement_handle_bits_1 =
804 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
805 mapped_validation_buffer->invalid_handle_found = 0;
806 mapped_validation_buffer->invalid_handle_bits_0 = 0;
807 mapped_validation_buffer->invalid_handle_bits_1 = 0;
808 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
809
810 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
811 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
812 const uint64_t current_valid_handle = current_valid_handles[i];
813
814 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
815 ++mapped_valid_handles;
816 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
817 ++mapped_valid_handles;
818 }
819
Tony-LunarG99b880b2019-09-26 11:19:52 -0600820 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700821
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700822 static constexpr const VkDeviceSize k_instance_size = 64;
823 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700824
Tony-LunarG1dce2392019-10-23 16:49:29 -0600825 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
826 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700827 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700828 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600829 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700830 return;
831 }
832
833 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
834 descriptor_buffer_infos[0].buffer = instanceData;
835 descriptor_buffer_infos[0].offset = instanceOffset;
836 descriptor_buffer_infos[0].range = instance_buffer_size;
837 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
838 descriptor_buffer_infos[1].offset = 0;
839 descriptor_buffer_infos[1].range = validation_buffer_size;
840
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600841 VkWriteDescriptorSet descriptor_set_writes[2] = {
842 LvlInitStruct<VkWriteDescriptorSet>(),
843 LvlInitStruct<VkWriteDescriptorSet>(),
844 };
Jason Macnak83cfd582019-07-31 10:14:24 -0700845 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
846 descriptor_set_writes[0].dstBinding = 0;
847 descriptor_set_writes[0].descriptorCount = 1;
848 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
849 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
Jason Macnak83cfd582019-07-31 10:14:24 -0700850 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
851 descriptor_set_writes[1].dstBinding = 1;
852 descriptor_set_writes[1].descriptorCount = 1;
853 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
854 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
855
856 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
857
858 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600859 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700860 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
861 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
862 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
863 &memory_barrier, 0, nullptr, 0, nullptr);
864
865 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600866 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -0600867 restorable_state.Create(cb_state.get(), VK_PIPELINE_BIND_POINT_COMPUTE);
Jason Macnak83cfd582019-07-31 10:14:24 -0700868
869 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
870 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
871 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
872 &as_validation_buffer_info.descriptor_set, 0, nullptr);
873 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
874
875 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
876 // have been replaced by the validation compute shader before any builds take place.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600877 auto instance_buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700878 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
879 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
880 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
881 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
882 instance_buffer_barrier.buffer = instanceData;
883 instance_buffer_barrier.offset = instanceOffset;
884 instance_buffer_barrier.size = instance_buffer_size;
885 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
886 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
887 nullptr);
888
889 // Restore the previous compute pipeline state.
890 restorable_state.Restore(commandBuffer);
891
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600892 cb_state->as_validation_buffers.emplace_back(std::move(as_validation_buffer_info));
Jason Macnak83cfd582019-07-31 10:14:24 -0700893}
894
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600895void gpuav_state::CommandBuffer::ProcessAccelerationStructure(VkQueue queue) {
896 if (!hasBuildAccelerationStructureCmd) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700897 return;
898 }
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600899 auto *device_state = static_cast<GpuAssisted *>(dev_data);
900 for (const auto &as_validation_buffer_info : as_validation_buffers) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700901 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
902
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600903 VkResult result = vmaMapMemory(device_state->vmaAllocator, as_validation_buffer_info.validation_buffer_allocation,
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700904 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700905 if (result == VK_SUCCESS) {
906 if (mapped_validation_buffer->invalid_handle_found > 0) {
907 uint64_t invalid_handle = 0;
908 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
909 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
910
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600911 device_state->LogError(
912 as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
913 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
914 "handle (%" PRIu64 ")",
915 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700916 }
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600917 vmaUnmapMemory(device_state->vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700918 }
919 }
920}
921
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600922void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
923 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
924 VkResult result) {
925 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600926 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600927 for (uint32_t i = 0; i < bindInfoCount; i++) {
928 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600929 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600930 if (as_state) {
931 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
932 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600933 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600934}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700935
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600936// Free the device memory and descriptor set(s) associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600937void GpuAssisted::DestroyBuffer(GpuAssistedBufferInfo &buffer_info) {
938 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
939 if (buffer_info.di_input_mem_block.buffer) {
940 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600941 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600942 if (buffer_info.bda_input_mem_block.buffer) {
943 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600944 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600945 if (buffer_info.desc_set != VK_NULL_HANDLE) {
946 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700947 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600948 if (buffer_info.pre_draw_resources.desc_set != VK_NULL_HANDLE) {
949 desc_set_manager->PutBackDescriptorSet(buffer_info.pre_draw_resources.desc_pool, buffer_info.pre_draw_resources.desc_set);
950 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600951}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600952
953void GpuAssisted::DestroyBuffer(GpuAssistedAccelerationStructureBuildValidationBufferInfo &as_validation_buffer_info) {
954 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
955 as_validation_buffer_info.validation_buffer_allocation);
956
957 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
958 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool, as_validation_buffer_info.descriptor_set);
959 }
960}
961
Karl Schultz7b024b42018-08-30 16:18:18 -0600962// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600963bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
964 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
965 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
966 uint32_t bufferMemoryBarrierCount,
967 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -0500968 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600969 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700970 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -0600971 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700972 "GPU-Assisted validation waits on queue completion. "
Karl Schultz7b024b42018-08-30 16:18:18 -0600973 "This wait could block the host's signaling of this event, resulting in deadlock.");
974 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600975 ValidationStateTracker::PreCallValidateCmdWaitEvents(commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask,
976 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
977 pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600978 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -0600979}
980
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700981bool GpuAssisted::PreCallValidateCmdWaitEvents2KHR(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
982 const VkDependencyInfoKHR *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700983 VkPipelineStageFlags2KHR src_stage_mask = 0;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700984
985 for (uint32_t i = 0; i < eventCount; i++) {
986 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700987 src_stage_mask |= stage_masks.src;
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700988 }
989
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700990 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700991 ReportSetupProblem(commandBuffer,
992 "CmdWaitEvents2KHR recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -0700993 "GPU-Assisted validation waits on queue completion. "
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700994 "This wait could block the host's signaling of this event, resulting in deadlock.");
995 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600996 ValidationStateTracker::PreCallValidateCmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfos);
Jeremy Gebbena3705f42021-01-19 16:47:43 -0700997 return false;
998}
999
Tony-LunarG1364cf52021-11-17 16:10:11 -07001000bool GpuAssisted::PreCallValidateCmdWaitEvents2(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1001 const VkDependencyInfo *pDependencyInfos) const {
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001002 VkPipelineStageFlags2 src_stage_mask = 0;
Tony-LunarG1364cf52021-11-17 16:10:11 -07001003
1004 for (uint32_t i = 0; i < eventCount; i++) {
1005 auto stage_masks = sync_utils::GetGlobalStageMasks(pDependencyInfos[i]);
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001006 src_stage_mask |= stage_masks.src;
Tony-LunarG1364cf52021-11-17 16:10:11 -07001007 }
1008
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001009 if (src_stage_mask & VK_PIPELINE_STAGE_HOST_BIT) {
Tony-LunarG1364cf52021-11-17 16:10:11 -07001010 ReportSetupProblem(commandBuffer,
1011 "CmdWaitEvents2 recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
Jeremy Gebbenf18d4362022-01-27 14:37:25 -07001012 "GPU-Assisted validation waits on queue completion. "
Tony-LunarG1364cf52021-11-17 16:10:11 -07001013 "This wait could block the host's signaling of this event, resulting in deadlock.");
1014 }
1015 ValidationStateTracker::PreCallValidateCmdWaitEvents2(commandBuffer, eventCount, pEvents, pDependencyInfos);
1016 return false;
1017}
1018
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001019void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1020 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1021 // 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 -06001022 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001023 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1024 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1025 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001026 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1027 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001028 }
1029 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001030 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pPhysicalDeviceProperties);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001031}
1032
1033void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1034 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1035 // 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 -06001036 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001037 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1038 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1039 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001040 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1041 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001042 }
1043 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001044 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pPhysicalDeviceProperties2);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001045}
1046
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001047void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
1048 const VkAllocationCallbacks *pAllocator) {
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001049 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.pop(renderPass);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001050 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1051 DispatchDestroyPipeline(device, pipeline->second, nullptr);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001052 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001053 ValidationStateTracker::PreCallRecordDestroyRenderPass(device, renderPass, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001054}
1055
Karl Schultz7b024b42018-08-30 16:18:18 -06001056// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001057bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001058 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001059 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001060 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1061
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001062 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -06001063 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
1064 switch (level) {
1065 case SPV_MSG_FATAL:
1066 case SPV_MSG_INTERNAL_ERROR:
1067 case SPV_MSG_ERROR:
1068 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
1069 position.index, message);
1070 break;
1071 default:
1072 break;
1073 }
1074 };
1075
Karl Schultz7b024b42018-08-30 16:18:18 -06001076 // Load original shader SPIR-V
1077 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1078 new_pgm.clear();
1079 new_pgm.reserve(num_words);
1080 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1081
1082 // Call the optimizer to instrument the shader.
1083 // 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 -07001084 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -06001085 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -07001086 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001087 spvtools::ValidatorOptions val_options;
1088 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
1089 spvtools::OptimizerOptions opt_options;
1090 opt_options.set_run_validator(true);
1091 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001092 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001093 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001094 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -07001095 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Tony-LunarG57400d42021-10-14 11:18:43 -06001096 // Call CreateAggressiveDCEPass with preserve_interface == true
1097 optimizer.RegisterPass(CreateAggressiveDCEPass(true));
sfricke-samsung45996a42021-09-16 13:45:27 -07001098 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
1099 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
1100 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001101 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001102 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -06001103 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -06001104 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001105 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001106 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001107 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001108 return pass;
1109}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001110// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001111void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1112 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1113 void *csm_state_data) {
1114 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1115 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001116 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001117 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001118 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Karl Schultz7b024b42018-08-30 16:18:18 -06001119 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001120 ValidationStateTracker::PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, csm_state_data);
Karl Schultz7b024b42018-08-30 16:18:18 -06001121}
Tony-LunarG20678ff2021-05-07 14:56:26 -06001122
Tony-LunarG7345a062021-06-24 13:16:38 -06001123static const int kInstErrorPreDrawValidate = spvtools::kInstErrorMax + 1;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001124static const int kPreDrawValidateSubError = spvtools::kInstValidationOutError + 1;
Karl Schultz7b024b42018-08-30 16:18:18 -06001125// Generate the part of the message describing the violation.
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001126bool 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 -06001127 using namespace spvtools;
1128 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001129 bool return_code = true;
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001130 assert(kInstErrorPreDrawValidate == _kInstErrorPreDrawValidate);
1131 assert(kInstValidationOutError == _kInstValidationOutError);
Tony-LunarGab47cac2019-12-20 15:28:01 -07001132 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001133 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001134 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1135 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001136 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001137 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001138 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001139 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001140 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001141 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001142 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001143 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001144 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1145 vuid_msg = "UNASSIGNED-Device address out of bounds";
1146 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001147 case kInstErrorBuffOOBUniform:
1148 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001149 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1150 if (size == 0) {
1151 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1152 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
1153 } else {
1154 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
1155 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -07001156 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001157 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001158 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
1159 vuid_msg = vuid.uniform_access_oob;
1160 else
1161 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001162 }
1163 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -07001164 case kInstErrorBuffOOBUniformTexel:
1165 case kInstErrorBuffOOBStorageTexel: {
1166 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
1167 if (size == 0) {
1168 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
1169 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001170 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -07001171 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001172 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
1173 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001174 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001175 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
1176 vuid_msg = vuid.uniform_access_oob;
1177 else
1178 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001179 }
Tony-LunarG63f82e02021-04-12 16:13:48 -06001180 } break;
1181 case kInstErrorPreDrawValidate: {
Tim Van Patten38bdcdd2021-05-14 16:41:00 -06001182 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001183 if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_bufsize_error) {
Tony-LunarG63f82e02021-04-12 16:13:48 -06001184 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001185 uint32_t stride = buf_info.pre_draw_resources.stride;
1186 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
1187 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
1188 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1189 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
1190 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
1191 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001192 if (count == 1) {
1193 vuid_msg = vuid.count_exceeds_bufsize_1;
1194 } else {
1195 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001196 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001197 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_count_exceeds_limit_error) {
1198 uint32_t count = debug_record[kPreDrawValidateSubError + 1];
1199 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1200 strm << "Indirect draw count of " << count << " would exceed maxDrawIndirectCount limit of "
1201 << gpu_assisted->phys_dev_props.limits.maxDrawIndirectCount;
1202 vuid_msg = vuid.count_exceeds_device_limit;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001203 } else if (debug_record[kPreDrawValidateSubError] == pre_draw_first_instance_error) {
1204 uint32_t index = debug_record[kPreDrawValidateSubError + 1];
1205 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1206 strm << "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the "
1207 "VkDrawIndirectCommand structure at index "
1208 << index << " is not zero";
1209 vuid_msg = vuid.first_instance_not_zero;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001210 }
1211 return_code = false;
1212 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001213 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001214 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001215 vuid_msg = "UNASSIGNED-Internal Error";
1216 assert(false);
1217 } break;
1218 }
1219 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001220 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001221}
1222
Karl Schultz7b024b42018-08-30 16:18:18 -06001223// Pull together all the information from the debug record to build the error message strings,
1224// and then assemble them into a single message string.
1225// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1226// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1227// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1228// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1229//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001230void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001231 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001232 using namespace spvtools;
1233 const uint32_t total_words = debug_output_buffer[0];
1234 // A zero here means that the shader instrumentation didn't write anything.
1235 // If you have nothing to say, don't say it here.
1236 if (0 == total_words) {
1237 return;
1238 }
1239 // The first word in the debug output buffer is the number of words that would have
1240 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1241 // The number of words actually written by the shaders is determined by the size of the buffer
1242 // we provide via the descriptor. So, we process only the number of words that can fit in the
1243 // buffer.
1244 // Each "report" written by the shader instrumentation is considered a "record". This function
1245 // is hard-coded to process only one record because it expects the buffer to be large enough to
1246 // hold only one record. If there is a desire to process more than one record, this function needs
1247 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001248 std::string validation_message;
1249 std::string stage_message;
1250 std::string common_message;
1251 std::string filename_message;
1252 std::string source_message;
1253 std::string vuid_msg;
1254 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1255 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001256 std::vector<uint32_t> pgm;
Karl Schultz7b024b42018-08-30 16:18:18 -06001257 // The first record starts at this offset after the total_words.
1258 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1259 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1260 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001261 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1262 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001263 shader_module_handle = it->second.shader_module;
1264 pipeline_handle = it->second.pipeline;
1265 pgm = it->second.pgm;
1266 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001267 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info, this);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001268 if (gen_full_message) {
1269 UtilGenerateStageMessage(debug_record, stage_message);
1270 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1271 buffer_info.pipeline_bind_point, operation_index, common_message);
1272 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1273 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1274 filename_message.c_str(), source_message.c_str());
1275 }
1276 else {
1277 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1278 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001279 // The debug record at word kInstCommonOutSize is the number of words in the record
1280 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001281 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001282 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1283}
1284
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001285// For the given command buffer, map its debug data buffers and read their contents for analysis.
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001286void gpuav_state::CommandBuffer::Process(VkQueue queue) {
1287 auto *device_state = static_cast<GpuAssisted *>(dev_data);
1288 if (hasDrawCmd || hasTraceRaysCmd || hasDispatchCmd) {
1289 auto &gpu_buffer_list = gpuav_buffer_list;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001290 uint32_t draw_index = 0;
1291 uint32_t compute_index = 0;
1292 uint32_t ray_trace_index = 0;
1293
1294 for (auto &buffer_info : gpu_buffer_list) {
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001295 char *data;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001296
1297 uint32_t operation_index = 0;
1298 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
1299 operation_index = draw_index;
1300 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1301 operation_index = compute_index;
1302 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
1303 operation_index = ray_trace_index;
1304 } else {
1305 assert(false);
1306 }
1307
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001308 VkResult result = vmaMapMemory(device_state->vmaAllocator, buffer_info.output_mem_block.allocation, (void **)&data);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001309 if (result == VK_SUCCESS) {
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001310 device_state->AnalyzeAndGenerateMessages(commandBuffer(), queue, buffer_info, operation_index, (uint32_t *)data);
1311 vmaUnmapMemory(device_state->vmaAllocator, buffer_info.output_mem_block.allocation);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001312 }
1313
1314 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
1315 draw_index++;
1316 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1317 compute_index++;
1318 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
1319 ray_trace_index++;
1320 } else {
1321 assert(false);
1322 }
1323 }
1324 }
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001325 ProcessAccelerationStructure(queue);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001326}
1327
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001328void GpuAssisted::SetBindingState(uint32_t *data, uint32_t index, const cvdescriptorset::DescriptorBinding *binding) {
1329 switch (binding->descriptor_class) {
1330 case cvdescriptorset::DescriptorClass::GeneralBuffer: {
1331 auto buffer_binding = static_cast<const cvdescriptorset::BufferBinding *>(binding);
1332 for (uint32_t di = 0; di < buffer_binding->count; di++) {
1333 const auto &desc = buffer_binding->descriptors[di];
1334 if (!buffer_binding->updated[di]) {
1335 data[index++] = 0;
1336 continue;
1337 }
1338 auto buffer = desc.GetBuffer();
1339 if (buffer == VK_NULL_HANDLE) {
1340 data[index++] = UINT_MAX;
1341 } else {
1342 auto buffer_state = desc.GetBufferState();
1343 data[index++] = static_cast<uint32_t>(buffer_state->createInfo.size);
1344 }
1345 }
1346 break;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001347 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001348 case cvdescriptorset::DescriptorClass::TexelBuffer: {
1349 auto texel_binding = static_cast<const cvdescriptorset::TexelBinding *>(binding);
1350 for (uint32_t di = 0; di < texel_binding->count; di++) {
1351 const auto &desc = texel_binding->descriptors[di];
1352 if (!texel_binding->updated[di]) {
1353 data[index++] = 0;
1354 continue;
1355 }
1356 auto buffer_view = desc.GetBufferView();
1357 if (buffer_view == VK_NULL_HANDLE) {
1358 data[index++] = UINT_MAX;
1359 } else {
1360 auto buffer_view_state = desc.GetBufferViewState();
1361 data[index++] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1362 }
1363 }
1364 break;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001365 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001366 case cvdescriptorset::DescriptorClass::Mutable: {
1367 auto mutable_binding = static_cast<const cvdescriptorset::MutableBinding *>(binding);
1368 for (uint32_t di = 0; di < mutable_binding->count; di++) {
1369 const auto &desc = mutable_binding->descriptors[di];
1370 if (!mutable_binding->updated[di]) {
1371 data[index++] = 0;
1372 continue;
1373 }
1374 if (desc.active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1375 desc.active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1376 desc.active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1377 desc.active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
1378 const auto size = desc.GetBufferSize();
1379 data[index++] = static_cast<uint32_t>(size);
1380 } else {
1381 data[index++] = 1;
1382 }
1383 }
1384 break;
ziga7a255fb2021-11-20 21:17:07 +01001385 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001386 default: {
1387 for (uint32_t i = 0; i < binding->count; i++, index++) {
1388 data[index] = static_cast<uint32_t>(binding->updated[i]);
1389 }
1390 break;
1391 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001392 }
1393}
1394
Tony-LunarG81efe392019-03-07 15:43:27 -07001395// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Jeremy Gebben135550d2022-03-21 07:15:07 -06001396void GpuAssisted::UpdateInstrumentationBuffer(gpuav_state::CommandBuffer *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001397 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001398 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001399 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001400 VkResult result =
1401 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001402 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001403 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001404 SetBindingState(data, update.first, update.second);
Tony-LunarG81efe392019-03-07 15:43:27 -07001405 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001406 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001407 }
1408 }
1409 }
1410}
1411
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001412void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001413 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001414 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001415 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001416 auto guard = secondary_cmd_buffer->WriteLock();
Jeremy Gebben135550d2022-03-21 07:15:07 -06001417 UpdateInstrumentationBuffer(static_cast<gpuav_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001418 }
1419}
1420
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001421void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001422 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001423 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1424 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1425 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001426 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001427 }
1428 }
1429}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001430
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001431void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1432 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001433 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001434 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1435 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1436 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1437 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1438 }
1439 }
1440}
1441
Tony-LunarG26fe2842021-11-16 14:07:59 -07001442void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1443 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1444 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1445 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1446 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1447 }
1448 }
1449}
1450
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001451void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1452 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001453 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001454 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001455}
1456
Tony-LunarG745150c2021-07-02 15:07:31 -06001457void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1458 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1459 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001460 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1461 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001462 for (uint32_t i = 0; i < drawCount; i++) {
1463 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1464 }
1465}
1466
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001467void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1468 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001469 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1470 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001471 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001472}
1473
Tony-LunarG745150c2021-07-02 15:07:31 -06001474void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1475 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1476 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001477 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1478 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001479 for (uint32_t i = 0; i < drawCount; i++) {
1480 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1481 }
1482}
1483
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001484void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1485 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001486 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001487 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1488 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001489}
1490
1491void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1492 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001493 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001494 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1495 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001496}
1497
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001498void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1499 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1500 uint32_t stride) {
1501 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1502 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001503 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001504 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001505}
1506
1507void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1508 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001509
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001510 uint32_t stride) {
1511 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1512 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001513 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1514 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001515}
1516
Tony-LunarG54176fb2020-12-02 10:47:22 -07001517void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1518 uint32_t firstInstance, VkBuffer counterBuffer,
1519 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1520 uint32_t vertexStride) {
1521 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1522 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001523 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001524}
1525
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001526void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1527 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1528 uint32_t maxDrawCount, uint32_t stride) {
1529 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1530 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001531 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001532 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001533}
1534
1535void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1536 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1537 uint32_t maxDrawCount, uint32_t stride) {
1538 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1539 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001540 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1541 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001542}
1543
1544void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1545 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001546 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001547}
1548
1549void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1550 uint32_t drawCount, uint32_t stride) {
1551 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001552 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001553}
1554
1555void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1556 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1557 uint32_t maxDrawCount, uint32_t stride) {
1558 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1559 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001560 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001561}
1562
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001563void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001564 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001565 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001566}
1567
1568void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001569 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001570 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001571}
1572
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001573void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1574 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1575 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001576 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1577 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001578 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001579}
1580
Tony-LunarG52c8c602020-09-10 16:29:56 -06001581void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1582 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1583 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001584 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1585 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001586 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001587}
1588
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001589void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1590 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1591 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1592 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1593 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1594 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1595 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001596 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1597 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1598 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1599 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1600 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001601 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001602}
1603
1604void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1605 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1606 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1607 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1608 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1609 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1610 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001611 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1612 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1613 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1614 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1615 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001616 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001617 cb_state->hasTraceRaysCmd = true;
1618}
1619
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001620void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001621 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1622 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1623 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1624 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001625 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001626 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1627 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001628 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001629}
1630
1631void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001632 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1633 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1634 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1635 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001636 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001637 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1638 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1639 depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001640 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001641 cb_state->hasTraceRaysCmd = true;
1642}
1643
1644void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001645 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1646 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1647 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1648 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001649 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001650 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1651 pHitShaderBindingTable, pCallableShaderBindingTable,
1652 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001653 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001654}
1655
sfricke-samsungf91881c2022-03-31 01:12:00 -05001656void GpuAssisted::PreCallRecordCmdTraceRaysIndirect2KHR(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress) {
1657 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress);
1658 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECT2KHR);
1659}
1660
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001661void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001662 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1663 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1664 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1665 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001666 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001667 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1668 pHitShaderBindingTable, pCallableShaderBindingTable,
1669 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001670 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001671 cb_state->hasTraceRaysCmd = true;
1672}
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001673VkPipeline GpuAssisted::GetValidationPipeline(VkRenderPass render_pass) {
1674 VkPipeline pipeline = VK_NULL_HANDLE;
1675 //NOTE: for dynamic rendering, render_pass will be VK_NULL_HANDLE but we'll use that as a map
1676 //key anyways;
1677 auto pipeentry = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1678 if (pipeentry != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1679 pipeline = pipeentry->second;
1680 }
1681 if (pipeline != VK_NULL_HANDLE) {
1682 return pipeline;
1683 }
1684 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1685 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1686 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1687 pipeline_stage_ci.pName = "main";
1688
1689 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1690 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1691 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1692 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1693 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1694 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1695 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1696
1697 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1698 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1699 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1700 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1701 graphicsPipelineCreateInfo.renderPass = render_pass;
1702 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1703 graphicsPipelineCreateInfo.stageCount = 1;
1704 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1705
1706 VkResult result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &pipeline);
1707 if (result != VK_SUCCESS) {
1708 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1709 aborted = true;
1710 return VK_NULL_HANDLE;
1711 }
1712
1713 pre_draw_validation_state.renderpass_to_pipeline.insert(render_pass, pipeline);
1714 return pipeline;
1715}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001716
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001717// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001718// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1719// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001720#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001721void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1722 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001723 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001724 VkResult result;
1725 if (!pre_draw_validation_state.globals_created) {
1726 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001727 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1728 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001729 result =
1730 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001731 if (result != VK_SUCCESS) {
1732 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1733 aborted = true;
1734 return;
1735 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001736
1737 std::vector<VkDescriptorSetLayoutBinding> bindings;
1738 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1739 // 0 - output buffer, 1 - count buffer
1740 bindings.push_back(binding);
1741 binding.binding = 1;
1742 bindings.push_back(binding);
1743
sjfrickee9b39372022-05-22 13:02:17 +09001744 VkDescriptorSetLayoutCreateInfo ds_layout_ci = LvlInitStruct<VkDescriptorSetLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001745 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1746 ds_layout_ci.pBindings = bindings.data();
1747 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001748 if (result != VK_SUCCESS) {
1749 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1750 aborted = true;
1751 return;
1752 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001753
1754 const uint32_t push_constant_range_count = 1;
1755 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1756 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1757 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001758 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001759 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
sjfrickee9b39372022-05-22 13:02:17 +09001760 pipelineLayoutCreateInfo[0] = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001761 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1762 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1763 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1764 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1765 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1766 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001767 if (result != VK_SUCCESS) {
1768 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1769 aborted = true;
1770 return;
1771 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001772
1773 pre_draw_validation_state.globals_created = true;
1774 }
Tony-LunarG463bae32022-02-25 09:31:17 -07001775
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001776 VkRenderPass render_pass = state.pipeline_state->RenderPassState()->renderPass();
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001777 *pPipeline = GetValidationPipeline(render_pass);
1778 if (*pPipeline == VK_NULL_HANDLE) {
1779 // could not find or create a pipeline
1780 return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001781 }
1782
1783 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1784 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001785 if (result != VK_SUCCESS) {
1786 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1787 aborted = true;
1788 return;
1789 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001790
1791 VkDescriptorBufferInfo buffer_infos[3] = {};
1792 // Error output buffer
1793 buffer_infos[0].buffer = output_block.buffer;
1794 buffer_infos[0].offset = 0;
1795 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001796 if (cdi_state->count_buffer) {
1797 // Count buffer
1798 buffer_infos[1].buffer = cdi_state->count_buffer;
1799 } else {
1800 // Draw Buffer
1801 buffer_infos[1].buffer = cdi_state->buffer;
1802 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001803 buffer_infos[1].offset = 0;
1804 buffer_infos[1].range = VK_WHOLE_SIZE;
1805
1806 VkWriteDescriptorSet desc_writes[2] = {};
1807 for (auto i = 0; i < 2; i++) {
sjfrickee9b39372022-05-22 13:02:17 +09001808 desc_writes[i] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001809 desc_writes[i].dstBinding = i;
1810 desc_writes[i].descriptorCount = 1;
1811 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1812 desc_writes[i].pBufferInfo = &buffer_infos[i];
1813 desc_writes[i].dstSet = resources.desc_set;
1814 }
1815 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
1816}
1817
Tony-LunarG7de10e82020-11-24 11:31:55 -07001818void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001819 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07001820 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1821 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001822 return;
1823 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001824 VkResult result;
1825
Tony-LunarG99b880b2019-09-26 11:19:52 -06001826 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001827
Jeremy Gebben04697b02022-03-23 16:18:12 -06001828 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(cmd_buffer);
Nathaniel Cesariobcb79682022-03-31 21:13:52 -06001829 if (!cb_node) {
1830 ReportSetupProblem(device, "Unrecognized command buffer");
1831 aborted = true;
1832 return;
1833 }
1834 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1835 auto const &state = cb_node->lastBound[lv_bind_point];
1836 const auto *pipeline_state = state.pipeline_state;
1837
1838 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for GPU-AV
1839 if (pipeline_state->IsGraphicsLibrary()) {
1840 ReportSetupProblem(device, "GPU-AV does not currently support VK_EXT_graphics_pipeline_library");
1841 aborted = true;
1842 return;
1843 }
1844
Tony-LunarGb2501d22019-01-28 09:59:13 -07001845 std::vector<VkDescriptorSet> desc_sets;
1846 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001847 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001848 assert(result == VK_SUCCESS);
1849 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001850 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001851 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001852 return;
1853 }
1854
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001855 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001856 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001857
Tony-LunarG81efe392019-03-07 15:43:27 -07001858 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001859 GpuAssistedDeviceMemoryBlock output_block = {};
sjfrickee9b39372022-05-22 13:02:17 +09001860 VkBufferCreateInfo buffer_info = LvlInitStruct<VkBufferCreateInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001861 buffer_info.size = output_buffer_size;
1862 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1863 VmaAllocationCreateInfo alloc_info = {};
Tony-LunarGef497962022-04-19 08:48:52 -06001864 alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001865 alloc_info.pool = output_buffer_pool;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001866 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001867 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001868 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001869 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001870 return;
1871 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001872
Tony-LunarG81efe392019-03-07 15:43:27 -07001873 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001874 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001875 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001876 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001877 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001878 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001879 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001880
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001881 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001882 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1883 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1884 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001885 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001886 uint32_t desc_count = 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001887 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001888
sfricke-samsung85584a72021-09-30 21:43:38 -07001889 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
1890 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001891 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
1892 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001893 // 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 -06001894 //
1895 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
1896 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
1897
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001898 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001899 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001900 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001901 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001902 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001903
1904 // Save current graphics pipeline state
1905 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06001906 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001907
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001908 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001909 pre_draw_resources.buffer = cdi_state->buffer;
1910 pre_draw_resources.offset = cdi_state->offset;
1911 pre_draw_resources.stride = cdi_state->stride;
1912
1913 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07001914 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
1915 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001916 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
1917 ReportSetupProblem(device,
1918 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
1919 aborted = true;
1920 return;
1921 }
1922
1923 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
1924 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07001925 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001926 struct_size = sizeof(VkDrawIndirectCommand);
1927 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07001928 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001929 struct_size = sizeof(VkDrawIndexedIndirectCommand);
1930 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06001931 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001932 uint32_t max_count;
1933 uint64_t bufsize = buffer_state->createInfo.size;
1934 uint64_t first_command_bytes = struct_size + cdi_state->offset;
1935 if (first_command_bytes > bufsize) {
1936 max_count = 0;
1937 } else {
1938 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
1939 }
1940 pre_draw_resources.buf_size = buffer_state->createInfo.size;
1941
1942 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
1943 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
1944 pushConstants[1] = max_count;
1945 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
1946 } else {
1947 pushConstants[0] = 0; // firstInstance check instead of count buffer check
1948 pushConstants[1] = cdi_state->drawCount;
1949 if (cmd_type == CMD_DRAWINDIRECT) {
1950 pushConstants[2] = static_cast<uint32_t>(
1951 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1952 } else {
1953 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
1954 pushConstants[2] = static_cast<uint32_t>(
1955 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1956 }
1957 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
1958 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001959
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001960 // Insert diagnostic draw
1961 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001962 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
1963 sizeof(pushConstants), pushConstants);
1964 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1965 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
1966 nullptr);
1967 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
1968
1969 // Restore the previous graphics pipeline state.
1970 restorable_state.Restore(cmd_buffer);
1971 }
1972
Tony-LunarGe29097a2020-12-03 10:59:19 -07001973 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001974 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1975 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001976 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001977 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1978 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07001979 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001980 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001981 if (desc && (desc->GetBindingCount() > 0)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001982 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001983 for (const auto &binding : *desc) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001984 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1985 // blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001986 if (binding->type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001987 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001988 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1989 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1990 "validation");
Tony-LunarGa77cade2019-03-06 10:49:22 -07001991 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001992 descriptor_count += binding->count;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001993 }
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001994 if (!has_buffers && (binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1995 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
1996 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1997 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1998 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1999 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002000 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002001 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002002 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002003 }
2004 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002005
Tony-LunarGe29097a2020-12-03 10:59:19 -07002006 if (descriptor_indexing || has_buffers) {
2007 // Note that the size of the input buffer is dependent on the maximum binding number, which
2008 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2009 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2010 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2011 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2012 uint32_t words_needed;
2013 if (descriptor_indexing) {
2014 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2015 } else {
2016 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2017 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002018 buffer_info.size = words_needed * 4;
Tony-LunarG20d18a72022-04-19 11:01:47 -06002019 alloc_info.pool = VK_NULL_HANDLE;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002020 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2021 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002022 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06002023 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002024 aborted = true;
2025 return;
2026 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002027
Tony-LunarGe29097a2020-12-03 10:59:19 -07002028 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2029 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2030 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002031 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2032 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002033
Tony-LunarGe29097a2020-12-03 10:59:19 -07002034 // Descriptor indexing needs the number of descriptors at each binding.
2035 if (descriptor_indexing) {
2036 // Pointer to a sets array that points into the sizes array
2037 uint32_t *sets_to_sizes = data_ptr + 1;
2038 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2039 uint32_t *sizes = sets_to_sizes + number_of_sets;
2040 // Pointer to another sets array that points into the bindings array that points into the written array
2041 uint32_t *sets_to_bindings = sizes + binding_count;
2042 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2043 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2044 // Index of the next entry in the written array to be updated
2045 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2046 uint32_t bind_counter = number_of_sets + 1;
2047 // Index of the start of the sets_to_bindings array
2048 data_ptr[0] = number_of_sets + binding_count + 1;
2049
John Zulauf79f06582021-02-27 18:38:39 -07002050 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002051 auto desc = s.bound_descriptor_set;
2052 if (desc && (desc->GetBindingCount() > 0)) {
2053 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002054 // For each set, fill in index of its bindings sizes in the sizes array
2055 *sets_to_sizes++ = bind_counter;
2056 // For each set, fill in the index of its bindings in the bindings_to_written array
2057 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002058 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002059 // For each binding, fill in its size in the sizes array
2060 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2061 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002062 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
2063 sizes[binding->binding] = 1;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002064 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002065 sizes[binding->binding] = binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002066 }
2067 // Fill in the starting index for this binding in the written array in the bindings_to_written array
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002068 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002069
2070 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2071 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002072 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002073 data_ptr[written_index++] = UINT_MAX;
2074 continue;
2075 }
2076
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002077 if ((binding->binding_flags & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) != 0) {
2078 di_input_block.update_at_submit[written_index] = binding.get();
2079 } else {
2080 SetBindingState(data_ptr, written_index, binding.get());
Tony-LunarGe29097a2020-12-03 10:59:19 -07002081 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002082 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002083 }
2084 auto last = desc->GetLayout()->GetMaxBinding();
2085 bindings_to_written += last + 1;
2086 bind_counter += last + 1;
2087 sizes += last + 1;
2088 } else {
2089 *sets_to_sizes++ = 0;
2090 *sets_to_bindings++ = 0;
2091 }
2092 }
2093 } else {
2094 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2095 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2096
2097 // Pointer to sets array that points into the bindings array that points into the written array
2098 uint32_t *sets_to_bindings = data_ptr + 1;
2099 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2100 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2101 // Index of the next entry in the written array to be updated
2102 uint32_t written_index = 1 + number_of_sets + binding_count;
2103 uint32_t bind_counter = number_of_sets + 1;
2104 data_ptr[0] = 1;
2105
John Zulauf79f06582021-02-27 18:38:39 -07002106 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002107 auto desc = s.bound_descriptor_set;
2108 if (desc && (desc->GetBindingCount() > 0)) {
2109 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002110 *sets_to_bindings++ = bind_counter;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002111 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002112 // Fill in the starting index for this binding in the written array in the bindings_to_written array
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002113 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002114
2115 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2116 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002117 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002118 data_ptr[written_index++] = UINT_MAX;
2119 continue;
2120 }
2121
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002122 // note that VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT is part of descriptor indexing
2123 SetBindingState(data_ptr, written_index, binding.get());
2124 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002125 }
2126 auto last = desc->GetLayout()->GetMaxBinding();
2127 bindings_to_written += last + 1;
2128 bind_counter += last + 1;
2129 } else {
2130 *sets_to_bindings++ = 0;
2131 }
2132 }
2133 }
2134 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2135
2136 di_input_desc_buffer_info.range = (words_needed * 4);
2137 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2138 di_input_desc_buffer_info.offset = 0;
2139
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002140 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002141 desc_writes[1].dstBinding = 1;
2142 desc_writes[1].descriptorCount = 1;
2143 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2144 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2145 desc_writes[1].dstSet = desc_sets[0];
2146
2147 desc_count = 2;
2148 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002149 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002150
sfricke-samsung45996a42021-09-16 13:45:27 -07002151 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2152 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002153 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
2154 auto address_ranges = GetBufferAddressRanges();
2155 if (address_ranges.size() > 0) {
2156 // Example BDA input buffer assuming 2 buffers using BDA:
2157 // Word 0 | Index of start of buffer sizes (in this case 5)
2158 // Word 1 | 0x0000000000000000
2159 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2160 // Word 3 | Device Address of second buffer
2161 // Word 4 | 0xffffffffffffffff
2162 // Word 5 | 0 (size of pretend buffer at word 1)
2163 // Word 6 | Size in bytes of first buffer
2164 // Word 7 | Size in bytes of second buffer
2165 // Word 8 | 0 (size of pretend buffer in word 4)
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002166
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002167 uint32_t num_buffers = static_cast<uint32_t>(address_ranges.size());
2168 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002169 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG20d18a72022-04-19 11:01:47 -06002170 alloc_info.pool = VK_NULL_HANDLE;
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002171 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation,
2172 nullptr);
2173 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06002174 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002175 aborted = true;
2176 return;
2177 }
2178 uint64_t *bda_data;
2179 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
2180 uint32_t address_index = 1;
2181 uint32_t size_index = 3 + num_buffers;
2182 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
2183 bda_data[0] = size_index; // Start of buffer sizes
2184 bda_data[address_index++] = 0; // NULL address
2185 bda_data[size_index++] = 0;
2186
2187 for (const auto &range : address_ranges) {
2188 bda_data[address_index++] = range.begin;
2189 bda_data[size_index++] = range.end - range.begin;
2190 }
2191 bda_data[address_index] = UINTPTR_MAX;
2192 bda_data[size_index] = 0;
2193 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
2194
2195 bda_input_desc_buffer_info.range = (words_needed * 8);
2196 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2197 bda_input_desc_buffer_info.offset = 0;
2198
2199 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
2200 desc_writes[desc_count].dstBinding = 2;
2201 desc_writes[desc_count].descriptorCount = 1;
2202 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2203 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2204 desc_writes[desc_count].dstSet = desc_sets[0];
2205 desc_count++;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002206 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002207 }
2208
Tony-LunarGb2501d22019-01-28 09:59:13 -07002209 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002210 output_desc_buffer_info.buffer = output_block.buffer;
2211 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002212
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002213 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002214 desc_writes[0].descriptorCount = 1;
2215 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2216 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2217 desc_writes[0].dstSet = desc_sets[0];
2218 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002219
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002220 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002221 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
2222 if ((pipeline_layout->set_layouts.size() <= desc_set_bind_index) && !pipeline_layout->Destroyed()) {
2223 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002224 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002225 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002226 if (pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002227 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2228 aborted = true;
2229 } else {
2230 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002231 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2232 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002233 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002234 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002235 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002236 aborted = true;
2237 }
2238 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002239 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2240 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2241 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002242 return;
2243 }
2244}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002245
2246std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2247 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002248 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06002249 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<gpuav_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002250}
2251
Jeremy Gebben135550d2022-03-21 07:15:07 -06002252gpuav_state::CommandBuffer::CommandBuffer(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
2253 const COMMAND_POOL_STATE *pool)
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06002254 : gpu_utils_state::CommandBuffer(ga, cb, pCreateInfo, pool) {}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002255
Jeremy Gebben135550d2022-03-21 07:15:07 -06002256void gpuav_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002257 CMD_BUFFER_STATE::Reset();
2258 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2259 // Free the device memory and descriptor set(s) associated with a command buffer.
2260 if (gpuav->aborted) {
2261 return;
2262 }
2263 for (auto &buffer_info : gpuav_buffer_list) {
2264 gpuav->DestroyBuffer(buffer_info);
2265 }
2266 gpuav_buffer_list.clear();
2267
2268 for (auto &as_validation_buffer_info : as_validation_buffers) {
2269 gpuav->DestroyBuffer(as_validation_buffer_info);
2270 }
2271 as_validation_buffers.clear();
2272}