blob: 742917b746176ceb936db92ccaa1db9c91d8a8a3 [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
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001328void GpuAssisted::SetDescriptorInitialized(uint32_t *pData, uint32_t index, const cvdescriptorset::Descriptor *descriptor) {
1329 if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::GeneralBuffer) {
1330 auto buffer = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBuffer();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001331 if (buffer == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001332 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001333 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001334 auto buffer_state = static_cast<const cvdescriptorset::BufferDescriptor *>(descriptor)->GetBufferState();
1335 pData[index] = static_cast<uint32_t>(buffer_state->createInfo.size);
1336 }
1337 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::TexelBuffer) {
1338 auto buffer_view = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferView();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001339 if (buffer_view == VK_NULL_HANDLE) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001340 pData[index] = UINT_MAX;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001341 } else {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001342 auto buffer_view_state = static_cast<const cvdescriptorset::TexelDescriptor *>(descriptor)->GetBufferViewState();
1343 pData[index] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1344 }
ziga7a255fb2021-11-20 21:17:07 +01001345 } else if (descriptor->GetClass() == cvdescriptorset::DescriptorClass::Mutable) {
1346 if (descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1347 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1348 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1349 descriptor->active_descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER) {
1350 const auto size = static_cast<const cvdescriptorset::MutableDescriptor *>(descriptor)->GetBufferSize();
1351 pData[index] = static_cast<uint32_t>(size);
1352 } else {
1353 pData[index] = 1;
1354 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001355 } else {
1356 pData[index] = 1;
1357 }
1358}
1359
Tony-LunarG81efe392019-03-07 15:43:27 -07001360// 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 -06001361void GpuAssisted::UpdateInstrumentationBuffer(gpuav_state::CommandBuffer *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001362 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001363 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001364 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001365 VkResult result =
1366 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001367 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001368 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001369 if (update.second->updated) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001370 SetDescriptorInitialized(data, update.first, update.second);
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001371 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001372 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001373 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001374 }
1375 }
1376 }
1377}
1378
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001379void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001380 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001381 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001382 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001383 auto guard = secondary_cmd_buffer->WriteLock();
Jeremy Gebben135550d2022-03-21 07:15:07 -06001384 UpdateInstrumentationBuffer(static_cast<gpuav_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001385 }
1386}
1387
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001388void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001389 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001390 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1391 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1392 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001393 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001394 }
1395 }
1396}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001397
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001398void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1399 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001400 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001401 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1402 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1403 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1404 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1405 }
1406 }
1407}
1408
Tony-LunarG26fe2842021-11-16 14:07:59 -07001409void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1410 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1411 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1412 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1413 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1414 }
1415 }
1416}
1417
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001418void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1419 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001420 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001421 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001422}
1423
Tony-LunarG745150c2021-07-02 15:07:31 -06001424void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1425 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1426 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001427 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1428 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001429 for (uint32_t i = 0; i < drawCount; i++) {
1430 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1431 }
1432}
1433
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001434void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1435 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001436 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1437 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001438 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001439}
1440
Tony-LunarG745150c2021-07-02 15:07:31 -06001441void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1442 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1443 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001444 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1445 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001446 for (uint32_t i = 0; i < drawCount; i++) {
1447 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1448 }
1449}
1450
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001451void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1452 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001453 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001454 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1455 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001456}
1457
1458void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1459 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001460 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001461 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1462 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001463}
1464
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001465void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1466 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1467 uint32_t stride) {
1468 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1469 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001470 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001471 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001472}
1473
1474void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1475 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001476
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001477 uint32_t stride) {
1478 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1479 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001480 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1481 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001482}
1483
Tony-LunarG54176fb2020-12-02 10:47:22 -07001484void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1485 uint32_t firstInstance, VkBuffer counterBuffer,
1486 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1487 uint32_t vertexStride) {
1488 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1489 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001490 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001491}
1492
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001493void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1494 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1495 uint32_t maxDrawCount, uint32_t stride) {
1496 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1497 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001498 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001499 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001500}
1501
1502void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1503 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1504 uint32_t maxDrawCount, uint32_t stride) {
1505 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1506 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001507 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1508 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001509}
1510
1511void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1512 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001513 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001514}
1515
1516void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1517 uint32_t drawCount, uint32_t stride) {
1518 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001519 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001520}
1521
1522void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1523 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1524 uint32_t maxDrawCount, uint32_t stride) {
1525 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1526 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001527 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001528}
1529
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001530void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001531 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001532 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001533}
1534
1535void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001536 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001537 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001538}
1539
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001540void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1541 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1542 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001543 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1544 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001545 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001546}
1547
Tony-LunarG52c8c602020-09-10 16:29:56 -06001548void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1549 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1550 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001551 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1552 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001553 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001554}
1555
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001556void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1557 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1558 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1559 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1560 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1561 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1562 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001563 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1564 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1565 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1566 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1567 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001568 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001569}
1570
1571void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1572 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1573 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1574 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1575 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1576 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1577 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001578 ValidationStateTracker::PostCallRecordCmdTraceRaysNV(
1579 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1580 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1581 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1582 height, depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001583 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001584 cb_state->hasTraceRaysCmd = true;
1585}
1586
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001587void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001588 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1589 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1590 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1591 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001592 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001593 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1594 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001595 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001596}
1597
1598void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001599 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1600 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1601 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1602 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001603 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001604 ValidationStateTracker::PostCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1605 pHitShaderBindingTable, pCallableShaderBindingTable, width, height,
1606 depth);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001607 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001608 cb_state->hasTraceRaysCmd = true;
1609}
1610
1611void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001612 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1613 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1614 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1615 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001616 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001617 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1618 pHitShaderBindingTable, pCallableShaderBindingTable,
1619 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001620 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001621}
1622
sfricke-samsungf91881c2022-03-31 01:12:00 -05001623void GpuAssisted::PreCallRecordCmdTraceRaysIndirect2KHR(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress) {
1624 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress);
1625 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECT2KHR);
1626}
1627
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001628void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001629 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1630 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1631 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1632 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001633 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001634 ValidationStateTracker::PostCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1635 pHitShaderBindingTable, pCallableShaderBindingTable,
1636 indirectDeviceAddress);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001637 auto cb_state = Get<CMD_BUFFER_STATE>(commandBuffer);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001638 cb_state->hasTraceRaysCmd = true;
1639}
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001640VkPipeline GpuAssisted::GetValidationPipeline(VkRenderPass render_pass) {
1641 VkPipeline pipeline = VK_NULL_HANDLE;
1642 //NOTE: for dynamic rendering, render_pass will be VK_NULL_HANDLE but we'll use that as a map
1643 //key anyways;
1644 auto pipeentry = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1645 if (pipeentry != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1646 pipeline = pipeentry->second;
1647 }
1648 if (pipeline != VK_NULL_HANDLE) {
1649 return pipeline;
1650 }
1651 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1652 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
1653 pipeline_stage_ci.module = pre_draw_validation_state.validation_shader_module;
1654 pipeline_stage_ci.pName = "main";
1655
1656 auto graphicsPipelineCreateInfo = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1657 auto vertexInputState = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1658 auto inputAssemblyState = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1659 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1660 auto rasterizationState = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1661 rasterizationState.rasterizerDiscardEnable = VK_TRUE;
1662 auto colorBlendState = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
1663
1664 graphicsPipelineCreateInfo.pVertexInputState = &vertexInputState;
1665 graphicsPipelineCreateInfo.pInputAssemblyState = &inputAssemblyState;
1666 graphicsPipelineCreateInfo.pRasterizationState = &rasterizationState;
1667 graphicsPipelineCreateInfo.pColorBlendState = &colorBlendState;
1668 graphicsPipelineCreateInfo.renderPass = render_pass;
1669 graphicsPipelineCreateInfo.layout = pre_draw_validation_state.validation_pipeline_layout;
1670 graphicsPipelineCreateInfo.stageCount = 1;
1671 graphicsPipelineCreateInfo.pStages = &pipeline_stage_ci;
1672
1673 VkResult result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &pipeline);
1674 if (result != VK_SUCCESS) {
1675 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1676 aborted = true;
1677 return VK_NULL_HANDLE;
1678 }
1679
1680 pre_draw_validation_state.renderpass_to_pipeline.insert(render_pass, pipeline);
1681 return pipeline;
1682}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001683
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001684// To generate the pre draw validation shader, run the following from the repository base level
Tony-LunarG20678ff2021-05-07 14:56:26 -06001685// python ./scripts/generate_spirv.py --outfilename ./layers/generated/gpu_pre_draw_shader.h ./layers/gpu_pre_draw_shader.vert
1686// ./External/glslang/build/install/bin/glslangValidator.exe
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001687#include "gpu_pre_draw_shader.h"
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001688void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1689 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001690 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001691 VkResult result;
1692 if (!pre_draw_validation_state.globals_created) {
1693 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
Tony-LunarG9d7a3bc2021-04-26 15:55:18 -06001694 shader_module_ci.codeSize = sizeof(gpu_pre_draw_shader_vert);
1695 shader_module_ci.pCode = gpu_pre_draw_shader_vert;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001696 result =
1697 DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.validation_shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001698 if (result != VK_SUCCESS) {
1699 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1700 aborted = true;
1701 return;
1702 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001703
1704 std::vector<VkDescriptorSetLayoutBinding> bindings;
1705 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, NULL};
1706 // 0 - output buffer, 1 - count buffer
1707 bindings.push_back(binding);
1708 binding.binding = 1;
1709 bindings.push_back(binding);
1710
sjfrickee9b39372022-05-22 13:02:17 +09001711 VkDescriptorSetLayoutCreateInfo ds_layout_ci = LvlInitStruct<VkDescriptorSetLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001712 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1713 ds_layout_ci.pBindings = bindings.data();
1714 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.validation_ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001715 if (result != VK_SUCCESS) {
1716 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1717 aborted = true;
1718 return;
1719 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001720
1721 const uint32_t push_constant_range_count = 1;
1722 VkPushConstantRange push_constant_ranges[push_constant_range_count] = {};
1723 push_constant_ranges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1724 push_constant_ranges[0].offset = 0;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001725 push_constant_ranges[0].size = 4 * sizeof(uint32_t);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001726 VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo[1] = {};
sjfrickee9b39372022-05-22 13:02:17 +09001727 pipelineLayoutCreateInfo[0] = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001728 pipelineLayoutCreateInfo[0].pushConstantRangeCount = push_constant_range_count;
1729 pipelineLayoutCreateInfo[0].pPushConstantRanges = push_constant_ranges;
1730 pipelineLayoutCreateInfo[0].setLayoutCount = 1;
1731 pipelineLayoutCreateInfo[0].pSetLayouts = &pre_draw_validation_state.validation_ds_layout;
1732 result = DispatchCreatePipelineLayout(device, pipelineLayoutCreateInfo, NULL,
1733 &pre_draw_validation_state.validation_pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001734 if (result != VK_SUCCESS) {
1735 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1736 aborted = true;
1737 return;
1738 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001739
1740 pre_draw_validation_state.globals_created = true;
1741 }
Tony-LunarG463bae32022-02-25 09:31:17 -07001742
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001743 VkRenderPass render_pass = state.pipeline_state->RenderPassState()->renderPass();
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001744 *pPipeline = GetValidationPipeline(render_pass);
1745 if (*pPipeline == VK_NULL_HANDLE) {
1746 // could not find or create a pipeline
1747 return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001748 }
1749
1750 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.validation_ds_layout,
1751 &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001752 if (result != VK_SUCCESS) {
1753 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1754 aborted = true;
1755 return;
1756 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001757
1758 VkDescriptorBufferInfo buffer_infos[3] = {};
1759 // Error output buffer
1760 buffer_infos[0].buffer = output_block.buffer;
1761 buffer_infos[0].offset = 0;
1762 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001763 if (cdi_state->count_buffer) {
1764 // Count buffer
1765 buffer_infos[1].buffer = cdi_state->count_buffer;
1766 } else {
1767 // Draw Buffer
1768 buffer_infos[1].buffer = cdi_state->buffer;
1769 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001770 buffer_infos[1].offset = 0;
1771 buffer_infos[1].range = VK_WHOLE_SIZE;
1772
1773 VkWriteDescriptorSet desc_writes[2] = {};
1774 for (auto i = 0; i < 2; i++) {
sjfrickee9b39372022-05-22 13:02:17 +09001775 desc_writes[i] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001776 desc_writes[i].dstBinding = i;
1777 desc_writes[i].descriptorCount = 1;
1778 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1779 desc_writes[i].pBufferInfo = &buffer_infos[i];
1780 desc_writes[i].dstSet = resources.desc_set;
1781 }
1782 DispatchUpdateDescriptorSets(device, 2, desc_writes, 0, NULL);
1783}
1784
Tony-LunarG7de10e82020-11-24 11:31:55 -07001785void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001786 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07001787 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1788 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001789 return;
1790 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001791 VkResult result;
1792
Tony-LunarG99b880b2019-09-26 11:19:52 -06001793 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001794
Jeremy Gebben04697b02022-03-23 16:18:12 -06001795 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(cmd_buffer);
Nathaniel Cesariobcb79682022-03-31 21:13:52 -06001796 if (!cb_node) {
1797 ReportSetupProblem(device, "Unrecognized command buffer");
1798 aborted = true;
1799 return;
1800 }
1801 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1802 auto const &state = cb_node->lastBound[lv_bind_point];
1803 const auto *pipeline_state = state.pipeline_state;
1804
1805 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for GPU-AV
1806 if (pipeline_state->IsGraphicsLibrary()) {
1807 ReportSetupProblem(device, "GPU-AV does not currently support VK_EXT_graphics_pipeline_library");
1808 aborted = true;
1809 return;
1810 }
1811
Tony-LunarGb2501d22019-01-28 09:59:13 -07001812 std::vector<VkDescriptorSet> desc_sets;
1813 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001814 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001815 assert(result == VK_SUCCESS);
1816 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001817 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001818 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001819 return;
1820 }
1821
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001822 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001823 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001824
Tony-LunarG81efe392019-03-07 15:43:27 -07001825 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001826 GpuAssistedDeviceMemoryBlock output_block = {};
sjfrickee9b39372022-05-22 13:02:17 +09001827 VkBufferCreateInfo buffer_info = LvlInitStruct<VkBufferCreateInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001828 buffer_info.size = output_buffer_size;
1829 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1830 VmaAllocationCreateInfo alloc_info = {};
Tony-LunarGef497962022-04-19 08:48:52 -06001831 alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001832 alloc_info.pool = output_buffer_pool;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001833 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001834 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001835 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001836 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001837 return;
1838 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001839
Tony-LunarG81efe392019-03-07 15:43:27 -07001840 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001841 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001842 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001843 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001844 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001845 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001846 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001847
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001848 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001849 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1850 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1851 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001852 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001853 uint32_t desc_count = 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001854 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001855
sfricke-samsung85584a72021-09-30 21:43:38 -07001856 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
1857 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001858 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
1859 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001860 // 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 -06001861 //
1862 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
1863 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
1864
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001865 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001866 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001867 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001868 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001869 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001870
1871 // Save current graphics pipeline state
1872 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06001873 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001874
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001875 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001876 pre_draw_resources.buffer = cdi_state->buffer;
1877 pre_draw_resources.offset = cdi_state->offset;
1878 pre_draw_resources.stride = cdi_state->stride;
1879
1880 uint32_t pushConstants[4] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07001881 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
1882 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001883 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
1884 ReportSetupProblem(device,
1885 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
1886 aborted = true;
1887 return;
1888 }
1889
1890 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
1891 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07001892 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001893 struct_size = sizeof(VkDrawIndirectCommand);
1894 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07001895 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001896 struct_size = sizeof(VkDrawIndexedIndirectCommand);
1897 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06001898 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001899 uint32_t max_count;
1900 uint64_t bufsize = buffer_state->createInfo.size;
1901 uint64_t first_command_bytes = struct_size + cdi_state->offset;
1902 if (first_command_bytes > bufsize) {
1903 max_count = 0;
1904 } else {
1905 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
1906 }
1907 pre_draw_resources.buf_size = buffer_state->createInfo.size;
1908
1909 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
1910 pushConstants[0] = phys_dev_props.limits.maxDrawIndirectCount;
1911 pushConstants[1] = max_count;
1912 pushConstants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
1913 } else {
1914 pushConstants[0] = 0; // firstInstance check instead of count buffer check
1915 pushConstants[1] = cdi_state->drawCount;
1916 if (cmd_type == CMD_DRAWINDIRECT) {
1917 pushConstants[2] = static_cast<uint32_t>(
1918 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1919 } else {
1920 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
1921 pushConstants[2] = static_cast<uint32_t>(
1922 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1923 }
1924 pushConstants[3] = (cdi_state->stride / sizeof(uint32_t));
1925 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001926
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001927 // Insert diagnostic draw
1928 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001929 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.validation_pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
1930 sizeof(pushConstants), pushConstants);
1931 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1932 pre_draw_validation_state.validation_pipeline_layout, 0, 1, &pre_draw_resources.desc_set, 0,
1933 nullptr);
1934 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
1935
1936 // Restore the previous graphics pipeline state.
1937 restorable_state.Restore(cmd_buffer);
1938 }
1939
Tony-LunarGe29097a2020-12-03 10:59:19 -07001940 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001941 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1942 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001943 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001944 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1945 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07001946 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001947 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001948 if (desc && (desc->GetBindingCount() > 0)) {
1949 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001950 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1951 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001952 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1953 // blocks
Tony-LunarGe29097a2020-12-03 10:59:19 -07001954 auto descriptor_type = desc->GetLayout()->GetTypeFromBinding(binding);
1955 if (descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001956 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001957 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1958 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1959 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001960 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001961 descriptor_count += desc->GetVariableDescriptorCount();
1962 } else {
1963 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1964 }
Tony-LunarGe29097a2020-12-03 10:59:19 -07001965 if (!has_buffers && (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1966 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
1967 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
Tony-LunarGe8632e42020-11-18 17:03:12 -07001968 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1969 descriptor_type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1970 descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001971 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001972 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001973 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001974 }
1975 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001976
Tony-LunarGe29097a2020-12-03 10:59:19 -07001977 if (descriptor_indexing || has_buffers) {
1978 // Note that the size of the input buffer is dependent on the maximum binding number, which
1979 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1980 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1981 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1982 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1983 uint32_t words_needed;
1984 if (descriptor_indexing) {
1985 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
1986 } else {
1987 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
1988 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001989 buffer_info.size = words_needed * 4;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001990 alloc_info.pool = VK_NULL_HANDLE;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001991 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
1992 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07001993 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001994 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarGe29097a2020-12-03 10:59:19 -07001995 aborted = true;
1996 return;
1997 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001998
Tony-LunarGe29097a2020-12-03 10:59:19 -07001999 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
2000 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
2001 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07002002 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
2003 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002004
Tony-LunarGe29097a2020-12-03 10:59:19 -07002005 // Descriptor indexing needs the number of descriptors at each binding.
2006 if (descriptor_indexing) {
2007 // Pointer to a sets array that points into the sizes array
2008 uint32_t *sets_to_sizes = data_ptr + 1;
2009 // Pointer to the sizes array that contains the array size of the descriptor at each binding
2010 uint32_t *sizes = sets_to_sizes + number_of_sets;
2011 // Pointer to another sets array that points into the bindings array that points into the written array
2012 uint32_t *sets_to_bindings = sizes + binding_count;
2013 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2014 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2015 // Index of the next entry in the written array to be updated
2016 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
2017 uint32_t bind_counter = number_of_sets + 1;
2018 // Index of the start of the sets_to_bindings array
2019 data_ptr[0] = number_of_sets + binding_count + 1;
2020
John Zulauf79f06582021-02-27 18:38:39 -07002021 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002022 auto desc = s.bound_descriptor_set;
2023 if (desc && (desc->GetBindingCount() > 0)) {
2024 auto layout = desc->GetLayout();
2025 auto bindings = layout->GetSortedBindingSet();
2026 // For each set, fill in index of its bindings sizes in the sizes array
2027 *sets_to_sizes++ = bind_counter;
2028 // For each set, fill in the index of its bindings in the bindings_to_written array
2029 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
2030 for (auto binding : bindings) {
2031 // For each binding, fill in its size in the sizes array
2032 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2033 // uniform blocks
2034 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2035 sizes[binding] = 1;
2036 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
2037 sizes[binding] = desc->GetVariableDescriptorCount();
2038 } else {
2039 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
2040 }
2041 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2042 bindings_to_written[binding] = written_index;
2043
2044 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2045 // uniform blocks
2046 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2047 data_ptr[written_index++] = UINT_MAX;
2048 continue;
2049 }
2050
2051 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2052 // For each array element in the binding, update the written array with whether it has been written
2053 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2054 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2055 if (descriptor->updated) {
2056 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2057 } else if (desc->IsUpdateAfterBind(binding)) {
2058 // If it hasn't been written now and it's update after bind, put it in a list to check at
2059 // QueueSubmit
2060 di_input_block.update_at_submit[written_index] = descriptor;
2061 }
2062 written_index++;
2063 }
2064 }
2065 auto last = desc->GetLayout()->GetMaxBinding();
2066 bindings_to_written += last + 1;
2067 bind_counter += last + 1;
2068 sizes += last + 1;
2069 } else {
2070 *sets_to_sizes++ = 0;
2071 *sets_to_bindings++ = 0;
2072 }
2073 }
2074 } else {
2075 // If no descriptor indexing, we don't need number of descriptors at each binding, so
2076 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
2077
2078 // Pointer to sets array that points into the bindings array that points into the written array
2079 uint32_t *sets_to_bindings = data_ptr + 1;
2080 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
2081 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
2082 // Index of the next entry in the written array to be updated
2083 uint32_t written_index = 1 + number_of_sets + binding_count;
2084 uint32_t bind_counter = number_of_sets + 1;
2085 data_ptr[0] = 1;
2086
John Zulauf79f06582021-02-27 18:38:39 -07002087 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07002088 auto desc = s.bound_descriptor_set;
2089 if (desc && (desc->GetBindingCount() > 0)) {
2090 auto layout = desc->GetLayout();
2091 auto bindings = layout->GetSortedBindingSet();
2092 *sets_to_bindings++ = bind_counter;
2093 for (auto binding : bindings) {
2094 // Fill in the starting index for this binding in the written array in the bindings_to_written array
2095 bindings_to_written[binding] = written_index;
2096
2097 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
2098 // uniform blocks
2099 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
2100 data_ptr[written_index++] = UINT_MAX;
2101 continue;
2102 }
2103
2104 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
2105
2106 // For each array element in the binding, update the written array with whether it has been written
2107 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
2108 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
2109 if (descriptor->updated) {
2110 SetDescriptorInitialized(data_ptr, written_index, descriptor);
2111 } else if (desc->IsUpdateAfterBind(binding)) {
2112 // If it hasn't been written now and it's update after bind, put it in a list to check at
2113 // QueueSubmit
2114 di_input_block.update_at_submit[written_index] = descriptor;
2115 }
2116 written_index++;
2117 }
2118 }
2119 auto last = desc->GetLayout()->GetMaxBinding();
2120 bindings_to_written += last + 1;
2121 bind_counter += last + 1;
2122 } else {
2123 *sets_to_bindings++ = 0;
2124 }
2125 }
2126 }
2127 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
2128
2129 di_input_desc_buffer_info.range = (words_needed * 4);
2130 di_input_desc_buffer_info.buffer = di_input_block.buffer;
2131 di_input_desc_buffer_info.offset = 0;
2132
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002133 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07002134 desc_writes[1].dstBinding = 1;
2135 desc_writes[1].descriptorCount = 1;
2136 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2137 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
2138 desc_writes[1].dstSet = desc_sets[0];
2139
2140 desc_count = 2;
2141 }
Tony-LunarG0e564722019-03-19 16:09:14 -06002142 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002143
sfricke-samsung45996a42021-09-16 13:45:27 -07002144 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
2145 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002146 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
2147 auto address_ranges = GetBufferAddressRanges();
2148 if (address_ranges.size() > 0) {
2149 // Example BDA input buffer assuming 2 buffers using BDA:
2150 // Word 0 | Index of start of buffer sizes (in this case 5)
2151 // Word 1 | 0x0000000000000000
2152 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
2153 // Word 3 | Device Address of second buffer
2154 // Word 4 | 0xffffffffffffffff
2155 // Word 5 | 0 (size of pretend buffer at word 1)
2156 // Word 6 | Size in bytes of first buffer
2157 // Word 7 | Size in bytes of second buffer
2158 // Word 8 | 0 (size of pretend buffer in word 4)
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002159
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002160 uint32_t num_buffers = static_cast<uint32_t>(address_ranges.size());
2161 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002162 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG20d18a72022-04-19 11:01:47 -06002163 alloc_info.pool = VK_NULL_HANDLE;
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002164 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation,
2165 nullptr);
2166 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06002167 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06002168 aborted = true;
2169 return;
2170 }
2171 uint64_t *bda_data;
2172 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
2173 uint32_t address_index = 1;
2174 uint32_t size_index = 3 + num_buffers;
2175 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
2176 bda_data[0] = size_index; // Start of buffer sizes
2177 bda_data[address_index++] = 0; // NULL address
2178 bda_data[size_index++] = 0;
2179
2180 for (const auto &range : address_ranges) {
2181 bda_data[address_index++] = range.begin;
2182 bda_data[size_index++] = range.end - range.begin;
2183 }
2184 bda_data[address_index] = UINTPTR_MAX;
2185 bda_data[size_index] = 0;
2186 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
2187
2188 bda_input_desc_buffer_info.range = (words_needed * 8);
2189 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
2190 bda_input_desc_buffer_info.offset = 0;
2191
2192 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
2193 desc_writes[desc_count].dstBinding = 2;
2194 desc_writes[desc_count].descriptorCount = 1;
2195 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2196 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
2197 desc_writes[desc_count].dstSet = desc_sets[0];
2198 desc_count++;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002199 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -06002200 }
2201
Tony-LunarGb2501d22019-01-28 09:59:13 -07002202 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002203 output_desc_buffer_info.buffer = output_block.buffer;
2204 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07002205
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06002206 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07002207 desc_writes[0].descriptorCount = 1;
2208 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
2209 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
2210 desc_writes[0].dstSet = desc_sets[0];
2211 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002212
locke-lunargb8d7a7a2020-10-25 16:01:52 -06002213 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002214 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
2215 if ((pipeline_layout->set_layouts.size() <= desc_set_bind_index) && !pipeline_layout->Destroyed()) {
2216 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06002217 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002218 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07002219 if (pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002220 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
2221 aborted = true;
2222 } else {
2223 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002224 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
2225 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002226 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07002227 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07002228 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06002229 aborted = true;
2230 }
2231 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06002232 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
2233 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
2234 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07002235 return;
2236 }
2237}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002238
2239std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2240 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002241 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06002242 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 -06002243}
2244
Jeremy Gebben135550d2022-03-21 07:15:07 -06002245gpuav_state::CommandBuffer::CommandBuffer(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
2246 const COMMAND_POOL_STATE *pool)
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06002247 : gpu_utils_state::CommandBuffer(ga, cb, pCreateInfo, pool) {}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002248
Jeremy Gebben135550d2022-03-21 07:15:07 -06002249void gpuav_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002250 CMD_BUFFER_STATE::Reset();
2251 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2252 // Free the device memory and descriptor set(s) associated with a command buffer.
2253 if (gpuav->aborted) {
2254 return;
2255 }
2256 for (auto &buffer_info : gpuav_buffer_list) {
2257 gpuav->DestroyBuffer(buffer_info);
2258 }
2259 gpuav_buffer_list.clear();
2260
2261 for (auto &as_validation_buffer_info : as_validation_buffers) {
2262 gpuav->DestroyBuffer(as_validation_buffer_info);
2263 }
2264 as_validation_buffers.clear();
2265}