blob: edd606f7afa94d15b2ba856ef258db8b5706f990 [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 }
Jeremy Gebbenc08f6502022-07-15 09:55:06 -06001374 switch (desc.ActiveType()) {
1375 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1376 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1377 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1378 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1379 data[index++] = static_cast<uint32_t>(desc.GetBufferSize());
1380 break;
1381 default:
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001382 data[index++] = 1;
Jeremy Gebbenc08f6502022-07-15 09:55:06 -06001383 break;
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001384 }
1385 }
1386 break;
ziga7a255fb2021-11-20 21:17:07 +01001387 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001388 default: {
1389 for (uint32_t i = 0; i < binding->count; i++, index++) {
1390 data[index] = static_cast<uint32_t>(binding->updated[i]);
1391 }
1392 break;
1393 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001394 }
1395}
1396
Tony-LunarG81efe392019-03-07 15:43:27 -07001397// 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 -06001398void GpuAssisted::UpdateInstrumentationBuffer(gpuav_state::CommandBuffer *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001399 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001400 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001401 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001402 VkResult result =
1403 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001404 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001405 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001406 SetBindingState(data, update.first, update.second);
Tony-LunarG81efe392019-03-07 15:43:27 -07001407 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001408 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001409 }
1410 }
1411 }
1412}
1413
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001414void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001415 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001416 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001417 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001418 auto guard = secondary_cmd_buffer->WriteLock();
Jeremy Gebben135550d2022-03-21 07:15:07 -06001419 UpdateInstrumentationBuffer(static_cast<gpuav_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001420 }
1421}
1422
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001423void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001424 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001425 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1426 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1427 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001428 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001429 }
1430 }
1431}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001432
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001433void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1434 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001435 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001436 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1437 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1438 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1439 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1440 }
1441 }
1442}
1443
Tony-LunarG26fe2842021-11-16 14:07:59 -07001444void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1445 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1446 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1447 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1448 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1449 }
1450 }
1451}
1452
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001453void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1454 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001455 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001456 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001457}
1458
Tony-LunarG745150c2021-07-02 15:07:31 -06001459void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1460 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1461 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001462 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1463 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001464 for (uint32_t i = 0; i < drawCount; i++) {
1465 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1466 }
1467}
1468
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001469void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1470 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001471 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1472 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001473 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001474}
1475
Tony-LunarG745150c2021-07-02 15:07:31 -06001476void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1477 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1478 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001479 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1480 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001481 for (uint32_t i = 0; i < drawCount; i++) {
1482 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1483 }
1484}
1485
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001486void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1487 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001488 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001489 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1490 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001491}
1492
1493void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1494 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001495 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001496 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1497 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001498}
1499
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001500void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1501 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1502 uint32_t stride) {
1503 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1504 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001505 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001506 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001507}
1508
1509void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1510 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001511
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001512 uint32_t stride) {
1513 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1514 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001515 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1516 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001517}
1518
Tony-LunarG54176fb2020-12-02 10:47:22 -07001519void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1520 uint32_t firstInstance, VkBuffer counterBuffer,
1521 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1522 uint32_t vertexStride) {
1523 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1524 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001525 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001526}
1527
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001528void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1529 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1530 uint32_t maxDrawCount, uint32_t stride) {
1531 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1532 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001533 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001534 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001535}
1536
1537void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1538 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1539 uint32_t maxDrawCount, uint32_t stride) {
1540 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1541 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001542 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1543 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001544}
1545
1546void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1547 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001548 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001549}
1550
1551void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1552 uint32_t drawCount, uint32_t stride) {
1553 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001554 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001555}
1556
1557void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1558 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1559 uint32_t maxDrawCount, uint32_t stride) {
1560 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1561 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001562 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001563}
1564
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001565void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001566 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001567 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001568}
1569
1570void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001571 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001572 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001573}
1574
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001575void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1576 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1577 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001578 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1579 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001580 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001581}
1582
Tony-LunarG52c8c602020-09-10 16:29:56 -06001583void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1584 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1585 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001586 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1587 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001588 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001589}
1590
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001591void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1592 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1593 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1594 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1595 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1596 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1597 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001598 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1599 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1600 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1601 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1602 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001603 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001604}
1605
1606void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1607 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1608 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1609 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1610 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1611 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1612 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001613 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1614 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1615 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1616 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1617 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001618 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001619 cb_state->hasTraceRaysCmd = true;
1620}
1621
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001622void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001623 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1624 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1625 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1626 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001627 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001628 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1629 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001630 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001631}
1632
1633void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001634 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1635 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1636 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1637 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001638 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001639 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1640 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1641 depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001642 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001643 cb_state->hasTraceRaysCmd = true;
1644}
1645
1646void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001647 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1648 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1649 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1650 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001651 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001652 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1653 pHitShaderBindingTable, pCallableShaderBindingTable,
1654 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001655 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001656}
1657
sfricke-samsungf91881c2022-03-31 01:12:00 -05001658void GpuAssisted::PreCallRecordCmdTraceRaysIndirect2KHR(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress) {
1659 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress);
1660 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECT2KHR);
1661}
1662
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001663void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001664 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1665 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1666 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1667 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001668 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001669 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1670 pHitShaderBindingTable, pCallableShaderBindingTable,
1671 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001672 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001673 cb_state->hasTraceRaysCmd = true;
1674}
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001675VkPipeline GpuAssisted::GetValidationPipeline(VkRenderPass render_pass) {
1676 VkPipeline pipeline = VK_NULL_HANDLE;
1677 //NOTE: for dynamic rendering, render_pass will be VK_NULL_HANDLE but we'll use that as a map
1678 //key anyways;
1679 auto pipeentry = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1680 if (pipeentry != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1681 pipeline = pipeentry->second;
1682 }
1683 if (pipeline != VK_NULL_HANDLE) {
1684 return pipeline;
1685 }
1686 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1687 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1688 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1689 pipeline_stage_ci.pName = "main";
1690
1691 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1692 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1693 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1694 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1695 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1696 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1697 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1698
1699 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1700 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1701 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1702 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1703 graphicsPipelineCreateInfo.renderPass = render_pass;
1704 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1705 graphicsPipelineCreateInfo.stageCount = 1;
1706 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1707
1708 VkResult result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &pipeline);
1709 if (result != VK_SUCCESS) {
1710 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1711 aborted = true;
1712 return VK_NULL_HANDLE;
1713 }
1714
1715 pre_draw_validation_state.renderpass_to_pipeline.insert(render_pass, pipeline);
1716 return pipeline;
1717}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001718
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001719// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001720// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1721// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001722#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001723void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1724 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001725 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001726 VkResult result;
1727 if (!pre_draw_validation_state.globals_created) {
1728 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001729 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1730 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001731 result =
1732 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001733 if (result != VK_SUCCESS) {
1734 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1735 aborted = true;
1736 return;
1737 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001738
1739 std::vector<VkDescriptorSetLayoutBinding> bindings;
1740 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1741 // 0 - output buffer, 1 - count buffer
1742 bindings.push_back(binding);
1743 binding.binding = 1;
1744 bindings.push_back(binding);
1745
sjfrickee9b39372022-05-22 13:02:17 +09001746 VkDescriptorSetLayoutCreateInfo ds_layout_ci = LvlInitStruct<VkDescriptorSetLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001747 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1748 ds_layout_ci.pBindings = bindings.data();
1749 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001750 if (result != VK_SUCCESS) {
1751 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1752 aborted = true;
1753 return;
1754 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001755
1756 const uint32_t push_constant_range_count = 1;
1757 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1758 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1759 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001760 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001761 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
sjfrickee9b39372022-05-22 13:02:17 +09001762 pipelineLayoutCreateInfo[0] = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001763 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1764 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1765 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1766 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1767 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1768 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001769 if (result != VK_SUCCESS) {
1770 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1771 aborted = true;
1772 return;
1773 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001774
1775 pre_draw_validation_state.globals_created = true;
1776 }
Tony-LunarG463bae32022-02-25 09:31:17 -07001777
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001778 VkRenderPass render_pass = state.pipeline_state->RenderPassState()->renderPass();
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001779 *pPipeline = GetValidationPipeline(render_pass);
1780 if (*pPipeline == VK_NULL_HANDLE) {
1781 // could not find or create a pipeline
1782 return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001783 }
1784
1785 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1786 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001787 if (result != VK_SUCCESS) {
1788 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1789 aborted = true;
1790 return;
1791 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001792
1793 VkDescriptorBufferInfo buffer_infos[3] = {};
1794 // Error output buffer
1795 buffer_infos[0].buffer = output_block.buffer;
1796 buffer_infos[0].offset = 0;
1797 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001798 if (cdi_state->count_buffer) {
1799 // Count buffer
1800 buffer_infos[1].buffer = cdi_state->count_buffer;
1801 } else {
1802 // Draw Buffer
1803 buffer_infos[1].buffer = cdi_state->buffer;
1804 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001805 buffer_infos[1].offset = 0;
1806 buffer_infos[1].range = VK_WHOLE_SIZE;
1807
1808 VkWriteDescriptorSet desc_writes[2] = {};
1809 for (auto i = 0; i < 2; i++) {
sjfrickee9b39372022-05-22 13:02:17 +09001810 desc_writes[i] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001811 desc_writes[i].dstBinding = i;
1812 desc_writes[i].descriptorCount = 1;
1813 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1814 desc_writes[i].pBufferInfo = &buffer_infos[i];
1815 desc_writes[i].dstSet = resources.desc_set;
1816 }
1817 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
1818}
1819
Tony-LunarG7de10e82020-11-24 11:31:55 -07001820void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001821 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07001822 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1823 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001824 return;
1825 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001826 VkResult result;
1827
Tony-LunarG99b880b2019-09-26 11:19:52 -06001828 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001829
Jeremy Gebben04697b02022-03-23 16:18:12 -06001830 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(cmd_buffer);
Nathaniel Cesariobcb79682022-03-31 21:13:52 -06001831 if (!cb_node) {
1832 ReportSetupProblem(device, "Unrecognized command buffer");
1833 aborted = true;
1834 return;
1835 }
1836 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1837 auto const &state = cb_node->lastBound[lv_bind_point];
1838 const auto *pipeline_state = state.pipeline_state;
1839
1840 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for GPU-AV
1841 if (pipeline_state->IsGraphicsLibrary()) {
1842 ReportSetupProblem(device, "GPU-AV does not currently support VK_EXT_graphics_pipeline_library");
1843 aborted = true;
1844 return;
1845 }
1846
Tony-LunarGb2501d22019-01-28 09:59:13 -07001847 std::vector<VkDescriptorSet> desc_sets;
1848 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001849 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001850 assert(result == VK_SUCCESS);
1851 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001852 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001853 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001854 return;
1855 }
1856
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001857 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001858 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001859
Tony-LunarG81efe392019-03-07 15:43:27 -07001860 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001861 GpuAssistedDeviceMemoryBlock output_block = {};
sjfrickee9b39372022-05-22 13:02:17 +09001862 VkBufferCreateInfo buffer_info = LvlInitStruct<VkBufferCreateInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001863 buffer_info.size = output_buffer_size;
1864 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1865 VmaAllocationCreateInfo alloc_info = {};
Tony-LunarGef497962022-04-19 08:48:52 -06001866 alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001867 alloc_info.pool = output_buffer_pool;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001868 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001869 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001870 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001871 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001872 return;
1873 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001874
Tony-LunarG81efe392019-03-07 15:43:27 -07001875 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001876 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001877 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001878 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001879 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001880 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001881 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001882
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001883 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001884 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1885 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1886 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001887 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001888 uint32_t desc_count = 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001889 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001890
sfricke-samsung85584a72021-09-30 21:43:38 -07001891 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
1892 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001893 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
1894 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001895 // 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 -06001896 //
1897 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
1898 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
1899
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001900 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001901 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001902 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001903 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001904 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001905
1906 // Save current graphics pipeline state
1907 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06001908 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001909
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001910 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001911 pre_draw_resources.buffer = cdi_state->buffer;
1912 pre_draw_resources.offset = cdi_state->offset;
1913 pre_draw_resources.stride = cdi_state->stride;
1914
1915 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07001916 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
1917 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001918 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
1919 ReportSetupProblem(device,
1920 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
1921 aborted = true;
1922 return;
1923 }
1924
1925 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
1926 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07001927 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001928 struct_size = sizeof(VkDrawIndirectCommand);
1929 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07001930 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001931 struct_size = sizeof(VkDrawIndexedIndirectCommand);
1932 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06001933 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001934 uint32_t max_count;
1935 uint64_t bufsize = buffer_state->createInfo.size;
1936 uint64_t first_command_bytes = struct_size + cdi_state->offset;
1937 if (first_command_bytes > bufsize) {
1938 max_count = 0;
1939 } else {
1940 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
1941 }
1942 pre_draw_resources.buf_size = buffer_state->createInfo.size;
1943
1944 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
1945 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
1946 pushConstants[1] = max_count;
1947 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
1948 } else {
1949 pushConstants[0] = 0; // firstInstance check instead of count buffer check
1950 pushConstants[1] = cdi_state->drawCount;
1951 if (cmd_type == CMD_DRAWINDIRECT) {
1952 pushConstants[2] = static_cast<uint32_t>(
1953 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1954 } else {
1955 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
1956 pushConstants[2] = static_cast<uint32_t>(
1957 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1958 }
1959 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
1960 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001961
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001962 // Insert diagnostic draw
1963 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001964 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
1965 sizeof(pushConstants), pushConstants);
1966 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1967 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
1968 nullptr);
1969 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
1970
1971 // Restore the previous graphics pipeline state.
1972 restorable_state.Restore(cmd_buffer);
1973 }
1974
Tony-LunarGe29097a2020-12-03 10:59:19 -07001975 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001976 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1977 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001978 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001979 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1980 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07001981 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001982 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001983 if (desc && (desc->GetBindingCount() > 0)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001984 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001985 for (const auto &binding : *desc) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001986 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1987 // blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001988 if (binding->type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001989 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001990 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1991 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1992 "validation");
Tony-LunarGa77cade2019-03-06 10:49:22 -07001993 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001994 descriptor_count += binding->count;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001995 }
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001996 if (!has_buffers && (binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1997 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
1998 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1999 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
2000 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
2001 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002002 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07002003 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06002004 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002005 }
2006 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002007
Tony-LunarGe29097a2020-12-03 10:59:19 -07002008 if (descriptor_indexing || has_buffers) {
2009 // Note that the size of the input buffer is dependent on the maximum binding number, which
2010 // can be very large. This is because for (set = s, binding = b, index = i), the validation
2011 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
2012 // see if descriptors have been written. In gpu_validation.md, we note this and advise
2013 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
2014 uint32_t words_needed;
2015 if (descriptor_indexing) {
2016 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
2017 } else {
2018 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
2019 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002020 buffer_info.size = words_needed * 4;
Tony-LunarG20d18a72022-04-19 11:01:47 -06002021 alloc_info.pool = VK_NULL_HANDLE;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002022 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
2023 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002024 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06002025 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarGe29097a2020-12-03 10:59:19 -07002026 aborted = true;
2027 return;
2028 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002029
Tony-LunarGe29097a2020-12-03 10:59:19 -07002030 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2031 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2032 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002033 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2034 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002035
Tony-LunarGe29097a2020-12-03 10:59:19 -07002036 // Descriptor indexing needs the number of descriptors at each binding.
2037 if (descriptor_indexing) {
2038 // Pointer to a sets array that points into the sizes array
2039 uint32_t *sets_to_sizes = data_ptr + 1;
2040 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2041 uint32_t *sizes = sets_to_sizes + number_of_sets;
2042 // Pointer to another sets array that points into the bindings array that points into the written array
2043 uint32_t *sets_to_bindings = sizes + binding_count;
2044 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2045 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2046 // Index of the next entry in the written array to be updated
2047 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2048 uint32_t bind_counter = number_of_sets + 1;
2049 // Index of the start of the sets_to_bindings array
2050 data_ptr[0] = number_of_sets + binding_count + 1;
2051
John Zulauf79f06582021-02-27 18:38:39 -07002052 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002053 auto desc = s.bound_descriptor_set;
2054 if (desc && (desc->GetBindingCount() > 0)) {
2055 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002056 // For each set, fill in index of its bindings sizes in the sizes array
2057 *sets_to_sizes++ = bind_counter;
2058 // For each set, fill in the index of its bindings in the bindings_to_written array
2059 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002060 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002061 // For each binding, fill in its size in the sizes array
2062 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2063 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002064 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
2065 sizes[binding->binding] = 1;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002066 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002067 sizes[binding->binding] = binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002068 }
2069 // 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 -06002070 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002071
2072 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2073 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002074 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002075 data_ptr[written_index++] = UINT_MAX;
2076 continue;
2077 }
2078
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002079 if ((binding->binding_flags & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) != 0) {
2080 di_input_block.update_at_submit[written_index] = binding.get();
2081 } else {
2082 SetBindingState(data_ptr, written_index, binding.get());
Tony-LunarGe29097a2020-12-03 10:59:19 -07002083 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002084 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002085 }
2086 auto last = desc->GetLayout()->GetMaxBinding();
2087 bindings_to_written += last + 1;
2088 bind_counter += last + 1;
2089 sizes += last + 1;
2090 } else {
2091 *sets_to_sizes++ = 0;
2092 *sets_to_bindings++ = 0;
2093 }
2094 }
2095 } else {
2096 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2097 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2098
2099 // Pointer to sets array that points into the bindings array that points into the written array
2100 uint32_t *sets_to_bindings = data_ptr + 1;
2101 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2102 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2103 // Index of the next entry in the written array to be updated
2104 uint32_t written_index = 1 + number_of_sets + binding_count;
2105 uint32_t bind_counter = number_of_sets + 1;
2106 data_ptr[0] = 1;
2107
John Zulauf79f06582021-02-27 18:38:39 -07002108 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002109 auto desc = s.bound_descriptor_set;
2110 if (desc && (desc->GetBindingCount() > 0)) {
2111 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002112 *sets_to_bindings++ = bind_counter;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002113 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002114 // 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 -06002115 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002116
2117 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2118 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06002119 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002120 data_ptr[written_index++] = UINT_MAX;
2121 continue;
2122 }
2123
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06002124 // note that VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT is part of descriptor indexing
2125 SetBindingState(data_ptr, written_index, binding.get());
2126 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07002127 }
2128 auto last = desc->GetLayout()->GetMaxBinding();
2129 bindings_to_written += last + 1;
2130 bind_counter += last + 1;
2131 } else {
2132 *sets_to_bindings++ = 0;
2133 }
2134 }
2135 }
2136 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2137
2138 di_input_desc_buffer_info.range = (words_needed * 4);
2139 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2140 di_input_desc_buffer_info.offset = 0;
2141
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002142 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002143 desc_writes[1].dstBinding = 1;
2144 desc_writes[1].descriptorCount = 1;
2145 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2146 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2147 desc_writes[1].dstSet = desc_sets[0];
2148
2149 desc_count = 2;
2150 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002151 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002152
sfricke-samsung45996a42021-09-16 13:45:27 -07002153 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2154 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002155 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
2156 auto address_ranges = GetBufferAddressRanges();
2157 if (address_ranges.size() > 0) {
2158 // Example BDA input buffer assuming 2 buffers using BDA:
2159 // Word 0 | Index of start of buffer sizes (in this case 5)
2160 // Word 1 | 0x0000000000000000
2161 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2162 // Word 3 | Device Address of second buffer
2163 // Word 4 | 0xffffffffffffffff
2164 // Word 5 | 0 (size of pretend buffer at word 1)
2165 // Word 6 | Size in bytes of first buffer
2166 // Word 7 | Size in bytes of second buffer
2167 // Word 8 | 0 (size of pretend buffer in word 4)
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002168
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002169 uint32_t num_buffers = static_cast<uint32_t>(address_ranges.size());
2170 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002171 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG20d18a72022-04-19 11:01:47 -06002172 alloc_info.pool = VK_NULL_HANDLE;
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002173 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation,
2174 nullptr);
2175 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06002176 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002177 aborted = true;
2178 return;
2179 }
2180 uint64_t *bda_data;
2181 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
2182 uint32_t address_index = 1;
2183 uint32_t size_index = 3 + num_buffers;
2184 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
2185 bda_data[0] = size_index; // Start of buffer sizes
2186 bda_data[address_index++] = 0; // NULL address
2187 bda_data[size_index++] = 0;
2188
2189 for (const auto &range : address_ranges) {
2190 bda_data[address_index++] = range.begin;
2191 bda_data[size_index++] = range.end - range.begin;
2192 }
2193 bda_data[address_index] = UINTPTR_MAX;
2194 bda_data[size_index] = 0;
2195 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
2196
2197 bda_input_desc_buffer_info.range = (words_needed * 8);
2198 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2199 bda_input_desc_buffer_info.offset = 0;
2200
2201 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
2202 desc_writes[desc_count].dstBinding = 2;
2203 desc_writes[desc_count].descriptorCount = 1;
2204 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2205 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2206 desc_writes[desc_count].dstSet = desc_sets[0];
2207 desc_count++;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002208 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002209 }
2210
Tony-LunarGb2501d22019-01-28 09:59:13 -07002211 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002212 output_desc_buffer_info.buffer = output_block.buffer;
2213 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002214
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002215 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002216 desc_writes[0].descriptorCount = 1;
2217 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2218 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2219 desc_writes[0].dstSet = desc_sets[0];
2220 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002221
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002222 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002223 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
2224 if ((pipeline_layout->set_layouts.size() <= desc_set_bind_index) && !pipeline_layout->Destroyed()) {
2225 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002226 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002227 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002228 if (pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002229 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2230 aborted = true;
2231 } else {
2232 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002233 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2234 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002235 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002236 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002237 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002238 aborted = true;
2239 }
2240 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002241 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2242 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2243 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002244 return;
2245 }
2246}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002247
2248std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2249 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002250 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06002251 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 -06002252}
2253
Jeremy Gebben135550d2022-03-21 07:15:07 -06002254gpuav_state::CommandBuffer::CommandBuffer(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
2255 const COMMAND_POOL_STATE *pool)
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06002256 : gpu_utils_state::CommandBuffer(ga, cb, pCreateInfo, pool) {}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002257
Jeremy Gebben135550d2022-03-21 07:15:07 -06002258void gpuav_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002259 CMD_BUFFER_STATE::Reset();
2260 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2261 // Free the device memory and descriptor set(s) associated with a command buffer.
2262 if (gpuav->aborted) {
2263 return;
2264 }
2265 for (auto &buffer_info : gpuav_buffer_list) {
2266 gpuav->DestroyBuffer(buffer_info);
2267 }
2268 gpuav_buffer_list.clear();
2269
2270 for (auto &as_validation_buffer_info : as_validation_buffers) {
2271 gpuav->DestroyBuffer(as_validation_buffer_info);
2272 }
2273 as_validation_buffers.clear();
2274}