blob: d8fd1d683d1e466ae256b14f14db10f351f97231 [file] [log] [blame]
Mark Lobodzinski103c58a2020-01-29 13:20:00 -07001/* Copyright (c) 2018-2020 The Khronos Group Inc.
2 * Copyright (c) 2018-2020 Valve Corporation
3 * Copyright (c) 2018-2020 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
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070021#include "gpu_validation.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060022#include "spirv-tools/optimizer.hpp"
23#include "spirv-tools/instrument.hpp"
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060024#include "layer_chassis_dispatch.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060025
Jason Macnak67407e72019-07-11 11:05:09 -070026static const VkShaderStageFlags kShaderStageAllRayTracing =
27 VK_SHADER_STAGE_ANY_HIT_BIT_NV | VK_SHADER_STAGE_CALLABLE_BIT_NV | VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV |
28 VK_SHADER_STAGE_INTERSECTION_BIT_NV | VK_SHADER_STAGE_MISS_BIT_NV | VK_SHADER_STAGE_RAYGEN_BIT_NV;
29
Jason Macnak83cfd582019-07-31 10:14:24 -070030// Keep in sync with the GLSL shader below.
31struct GpuAccelerationStructureBuildValidationBuffer {
32 uint32_t instances_to_validate;
33 uint32_t replacement_handle_bits_0;
34 uint32_t replacement_handle_bits_1;
35 uint32_t invalid_handle_found;
36 uint32_t invalid_handle_bits_0;
37 uint32_t invalid_handle_bits_1;
38 uint32_t valid_handles_count;
39};
40
41// This is the GLSL source for the compute shader that is used during ray tracing acceleration structure
42// building validation which inspects instance buffers for top level acceleration structure builds and
43// reports and replaces invalid bottom level acceleration structure handles with good bottom level
44// acceleration structure handle so that applications can continue without undefined behavior long enough
45// to report errors.
46//
47// #version 450
48// layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
49// struct VkGeometryInstanceNV {
50// uint unused[14];
51// uint handle_bits_0;
52// uint handle_bits_1;
53// };
54// layout(set=0, binding=0, std430) buffer InstanceBuffer {
55// VkGeometryInstanceNV instances[];
56// };
57// layout(set=0, binding=1, std430) buffer ValidationBuffer {
58// uint instances_to_validate;
59// uint replacement_handle_bits_0;
60// uint replacement_handle_bits_1;
61// uint invalid_handle_found;
62// uint invalid_handle_bits_0;
63// uint invalid_handle_bits_1;
64// uint valid_handles_count;
65// uint valid_handles[];
66// };
67// void main() {
68// for (uint instance_index = 0; instance_index < instances_to_validate; instance_index++) {
69// uint instance_handle_bits_0 = instances[instance_index].handle_bits_0;
70// uint instance_handle_bits_1 = instances[instance_index].handle_bits_1;
71// bool valid = false;
72// for (uint valid_handle_index = 0; valid_handle_index < valid_handles_count; valid_handle_index++) {
73// if (instance_handle_bits_0 == valid_handles[2*valid_handle_index+0] &&
74// instance_handle_bits_1 == valid_handles[2*valid_handle_index+1]) {
75// valid = true;
76// break;
77// }
78// }
79// if (!valid) {
80// invalid_handle_found += 1;
81// invalid_handle_bits_0 = instance_handle_bits_0;
82// invalid_handle_bits_1 = instance_handle_bits_1;
83// instances[instance_index].handle_bits_0 = replacement_handle_bits_0;
84// instances[instance_index].handle_bits_1 = replacement_handle_bits_1;
85// }
86// }
87// }
88//
89// To regenerate the spirv below:
90// 1. Save the above GLSL source to a file called validation_shader.comp.
91// 2. Run in terminal
92//
93// glslangValidator.exe -x -V validation_shader.comp -o validation_shader.comp.spv
94//
95// 4. Copy-paste the contents of validation_shader.comp.spv here (clang-format will fix up the alignment).
96static const uint32_t kComputeShaderSpirv[] = {
97 0x07230203, 0x00010000, 0x00080007, 0x0000006d, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47,
98 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005, 0x00000004, 0x6e69616d,
99 0x00000000, 0x00060010, 0x00000004, 0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00030003, 0x00000002, 0x000001c2,
100 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, 0x00000008, 0x74736e69, 0x65636e61, 0x646e695f, 0x00007865,
101 0x00070005, 0x00000011, 0x696c6156, 0x69746164, 0x75426e6f, 0x72656666, 0x00000000, 0x00090006, 0x00000011, 0x00000000,
102 0x74736e69, 0x65636e61, 0x6f745f73, 0x6c61765f, 0x74616469, 0x00000065, 0x000a0006, 0x00000011, 0x00000001, 0x6c706572,
103 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x000a0006, 0x00000011, 0x00000002, 0x6c706572,
104 0x6d656361, 0x5f746e65, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00090006, 0x00000011, 0x00000003, 0x61766e69,
105 0x5f64696c, 0x646e6168, 0x665f656c, 0x646e756f, 0x00000000, 0x00090006, 0x00000011, 0x00000004, 0x61766e69, 0x5f64696c,
106 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00090006, 0x00000011, 0x00000005, 0x61766e69, 0x5f64696c, 0x646e6168,
107 0x625f656c, 0x5f737469, 0x00000031, 0x00080006, 0x00000011, 0x00000006, 0x696c6176, 0x61685f64, 0x656c646e, 0x6f635f73,
108 0x00746e75, 0x00070006, 0x00000011, 0x00000007, 0x696c6176, 0x61685f64, 0x656c646e, 0x00000073, 0x00030005, 0x00000013,
109 0x00000000, 0x00080005, 0x0000001b, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000305f, 0x00080005,
110 0x0000001e, 0x65476b56, 0x74656d6f, 0x6e497972, 0x6e617473, 0x564e6563, 0x00000000, 0x00050006, 0x0000001e, 0x00000000,
111 0x73756e75, 0x00006465, 0x00070006, 0x0000001e, 0x00000001, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000030, 0x00070006,
112 0x0000001e, 0x00000002, 0x646e6168, 0x625f656c, 0x5f737469, 0x00000031, 0x00060005, 0x00000020, 0x74736e49, 0x65636e61,
113 0x66667542, 0x00007265, 0x00060006, 0x00000020, 0x00000000, 0x74736e69, 0x65636e61, 0x00000073, 0x00030005, 0x00000022,
114 0x00000000, 0x00080005, 0x00000027, 0x74736e69, 0x65636e61, 0x6e61685f, 0x5f656c64, 0x73746962, 0x0000315f, 0x00040005,
115 0x0000002d, 0x696c6176, 0x00000064, 0x00070005, 0x0000002f, 0x696c6176, 0x61685f64, 0x656c646e, 0x646e695f, 0x00007865,
116 0x00040047, 0x00000010, 0x00000006, 0x00000004, 0x00050048, 0x00000011, 0x00000000, 0x00000023, 0x00000000, 0x00050048,
117 0x00000011, 0x00000001, 0x00000023, 0x00000004, 0x00050048, 0x00000011, 0x00000002, 0x00000023, 0x00000008, 0x00050048,
118 0x00000011, 0x00000003, 0x00000023, 0x0000000c, 0x00050048, 0x00000011, 0x00000004, 0x00000023, 0x00000010, 0x00050048,
119 0x00000011, 0x00000005, 0x00000023, 0x00000014, 0x00050048, 0x00000011, 0x00000006, 0x00000023, 0x00000018, 0x00050048,
120 0x00000011, 0x00000007, 0x00000023, 0x0000001c, 0x00030047, 0x00000011, 0x00000003, 0x00040047, 0x00000013, 0x00000022,
121 0x00000000, 0x00040047, 0x00000013, 0x00000021, 0x00000001, 0x00040047, 0x0000001d, 0x00000006, 0x00000004, 0x00050048,
122 0x0000001e, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x0000001e, 0x00000001, 0x00000023, 0x00000038, 0x00050048,
123 0x0000001e, 0x00000002, 0x00000023, 0x0000003c, 0x00040047, 0x0000001f, 0x00000006, 0x00000040, 0x00050048, 0x00000020,
124 0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000020, 0x00000003, 0x00040047, 0x00000022, 0x00000022, 0x00000000,
125 0x00040047, 0x00000022, 0x00000021, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00040015,
126 0x00000006, 0x00000020, 0x00000000, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x0004002b, 0x00000006, 0x00000009,
127 0x00000000, 0x0003001d, 0x00000010, 0x00000006, 0x000a001e, 0x00000011, 0x00000006, 0x00000006, 0x00000006, 0x00000006,
128 0x00000006, 0x00000006, 0x00000006, 0x00000010, 0x00040020, 0x00000012, 0x00000002, 0x00000011, 0x0004003b, 0x00000012,
129 0x00000013, 0x00000002, 0x00040015, 0x00000014, 0x00000020, 0x00000001, 0x0004002b, 0x00000014, 0x00000015, 0x00000000,
130 0x00040020, 0x00000016, 0x00000002, 0x00000006, 0x00020014, 0x00000019, 0x0004002b, 0x00000006, 0x0000001c, 0x0000000e,
131 0x0004001c, 0x0000001d, 0x00000006, 0x0000001c, 0x0005001e, 0x0000001e, 0x0000001d, 0x00000006, 0x00000006, 0x0003001d,
132 0x0000001f, 0x0000001e, 0x0003001e, 0x00000020, 0x0000001f, 0x00040020, 0x00000021, 0x00000002, 0x00000020, 0x0004003b,
133 0x00000021, 0x00000022, 0x00000002, 0x0004002b, 0x00000014, 0x00000024, 0x00000001, 0x0004002b, 0x00000014, 0x00000029,
134 0x00000002, 0x00040020, 0x0000002c, 0x00000007, 0x00000019, 0x0003002a, 0x00000019, 0x0000002e, 0x0004002b, 0x00000014,
135 0x00000036, 0x00000006, 0x0004002b, 0x00000014, 0x0000003b, 0x00000007, 0x0004002b, 0x00000006, 0x0000003c, 0x00000002,
136 0x0004002b, 0x00000006, 0x00000048, 0x00000001, 0x00030029, 0x00000019, 0x00000050, 0x0004002b, 0x00000014, 0x00000058,
137 0x00000003, 0x0004002b, 0x00000014, 0x0000005d, 0x00000004, 0x0004002b, 0x00000014, 0x00000060, 0x00000005, 0x00050036,
138 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003b, 0x00000007, 0x00000008, 0x00000007,
139 0x0004003b, 0x00000007, 0x0000001b, 0x00000007, 0x0004003b, 0x00000007, 0x00000027, 0x00000007, 0x0004003b, 0x0000002c,
140 0x0000002d, 0x00000007, 0x0004003b, 0x00000007, 0x0000002f, 0x00000007, 0x0003003e, 0x00000008, 0x00000009, 0x000200f9,
141 0x0000000a, 0x000200f8, 0x0000000a, 0x000400f6, 0x0000000c, 0x0000000d, 0x00000000, 0x000200f9, 0x0000000e, 0x000200f8,
142 0x0000000e, 0x0004003d, 0x00000006, 0x0000000f, 0x00000008, 0x00050041, 0x00000016, 0x00000017, 0x00000013, 0x00000015,
143 0x0004003d, 0x00000006, 0x00000018, 0x00000017, 0x000500b0, 0x00000019, 0x0000001a, 0x0000000f, 0x00000018, 0x000400fa,
144 0x0000001a, 0x0000000b, 0x0000000c, 0x000200f8, 0x0000000b, 0x0004003d, 0x00000006, 0x00000023, 0x00000008, 0x00070041,
145 0x00000016, 0x00000025, 0x00000022, 0x00000015, 0x00000023, 0x00000024, 0x0004003d, 0x00000006, 0x00000026, 0x00000025,
146 0x0003003e, 0x0000001b, 0x00000026, 0x0004003d, 0x00000006, 0x00000028, 0x00000008, 0x00070041, 0x00000016, 0x0000002a,
147 0x00000022, 0x00000015, 0x00000028, 0x00000029, 0x0004003d, 0x00000006, 0x0000002b, 0x0000002a, 0x0003003e, 0x00000027,
148 0x0000002b, 0x0003003e, 0x0000002d, 0x0000002e, 0x0003003e, 0x0000002f, 0x00000009, 0x000200f9, 0x00000030, 0x000200f8,
149 0x00000030, 0x000400f6, 0x00000032, 0x00000033, 0x00000000, 0x000200f9, 0x00000034, 0x000200f8, 0x00000034, 0x0004003d,
150 0x00000006, 0x00000035, 0x0000002f, 0x00050041, 0x00000016, 0x00000037, 0x00000013, 0x00000036, 0x0004003d, 0x00000006,
151 0x00000038, 0x00000037, 0x000500b0, 0x00000019, 0x00000039, 0x00000035, 0x00000038, 0x000400fa, 0x00000039, 0x00000031,
152 0x00000032, 0x000200f8, 0x00000031, 0x0004003d, 0x00000006, 0x0000003a, 0x0000001b, 0x0004003d, 0x00000006, 0x0000003d,
153 0x0000002f, 0x00050084, 0x00000006, 0x0000003e, 0x0000003c, 0x0000003d, 0x00050080, 0x00000006, 0x0000003f, 0x0000003e,
154 0x00000009, 0x00060041, 0x00000016, 0x00000040, 0x00000013, 0x0000003b, 0x0000003f, 0x0004003d, 0x00000006, 0x00000041,
155 0x00000040, 0x000500aa, 0x00000019, 0x00000042, 0x0000003a, 0x00000041, 0x000300f7, 0x00000044, 0x00000000, 0x000400fa,
156 0x00000042, 0x00000043, 0x00000044, 0x000200f8, 0x00000043, 0x0004003d, 0x00000006, 0x00000045, 0x00000027, 0x0004003d,
157 0x00000006, 0x00000046, 0x0000002f, 0x00050084, 0x00000006, 0x00000047, 0x0000003c, 0x00000046, 0x00050080, 0x00000006,
158 0x00000049, 0x00000047, 0x00000048, 0x00060041, 0x00000016, 0x0000004a, 0x00000013, 0x0000003b, 0x00000049, 0x0004003d,
159 0x00000006, 0x0000004b, 0x0000004a, 0x000500aa, 0x00000019, 0x0000004c, 0x00000045, 0x0000004b, 0x000200f9, 0x00000044,
160 0x000200f8, 0x00000044, 0x000700f5, 0x00000019, 0x0000004d, 0x00000042, 0x00000031, 0x0000004c, 0x00000043, 0x000300f7,
161 0x0000004f, 0x00000000, 0x000400fa, 0x0000004d, 0x0000004e, 0x0000004f, 0x000200f8, 0x0000004e, 0x0003003e, 0x0000002d,
162 0x00000050, 0x000200f9, 0x00000032, 0x000200f8, 0x0000004f, 0x000200f9, 0x00000033, 0x000200f8, 0x00000033, 0x0004003d,
163 0x00000006, 0x00000052, 0x0000002f, 0x00050080, 0x00000006, 0x00000053, 0x00000052, 0x00000024, 0x0003003e, 0x0000002f,
164 0x00000053, 0x000200f9, 0x00000030, 0x000200f8, 0x00000032, 0x0004003d, 0x00000019, 0x00000054, 0x0000002d, 0x000400a8,
165 0x00000019, 0x00000055, 0x00000054, 0x000300f7, 0x00000057, 0x00000000, 0x000400fa, 0x00000055, 0x00000056, 0x00000057,
166 0x000200f8, 0x00000056, 0x00050041, 0x00000016, 0x00000059, 0x00000013, 0x00000058, 0x0004003d, 0x00000006, 0x0000005a,
167 0x00000059, 0x00050080, 0x00000006, 0x0000005b, 0x0000005a, 0x00000048, 0x00050041, 0x00000016, 0x0000005c, 0x00000013,
168 0x00000058, 0x0003003e, 0x0000005c, 0x0000005b, 0x0004003d, 0x00000006, 0x0000005e, 0x0000001b, 0x00050041, 0x00000016,
169 0x0000005f, 0x00000013, 0x0000005d, 0x0003003e, 0x0000005f, 0x0000005e, 0x0004003d, 0x00000006, 0x00000061, 0x00000027,
170 0x00050041, 0x00000016, 0x00000062, 0x00000013, 0x00000060, 0x0003003e, 0x00000062, 0x00000061, 0x0004003d, 0x00000006,
171 0x00000063, 0x00000008, 0x00050041, 0x00000016, 0x00000064, 0x00000013, 0x00000024, 0x0004003d, 0x00000006, 0x00000065,
172 0x00000064, 0x00070041, 0x00000016, 0x00000066, 0x00000022, 0x00000015, 0x00000063, 0x00000024, 0x0003003e, 0x00000066,
173 0x00000065, 0x0004003d, 0x00000006, 0x00000067, 0x00000008, 0x00050041, 0x00000016, 0x00000068, 0x00000013, 0x00000029,
174 0x0004003d, 0x00000006, 0x00000069, 0x00000068, 0x00070041, 0x00000016, 0x0000006a, 0x00000022, 0x00000015, 0x00000067,
175 0x00000029, 0x0003003e, 0x0000006a, 0x00000069, 0x000200f9, 0x00000057, 0x000200f8, 0x00000057, 0x000200f9, 0x0000000d,
176 0x000200f8, 0x0000000d, 0x0004003d, 0x00000006, 0x0000006b, 0x00000008, 0x00050080, 0x00000006, 0x0000006c, 0x0000006b,
177 0x00000024, 0x0003003e, 0x00000008, 0x0000006c, 0x000200f9, 0x0000000a, 0x000200f8, 0x0000000c, 0x000100fd, 0x00010038};
178
Karl Schultz7b024b42018-08-30 16:18:18 -0600179// Convenience function for reporting problems with setting up GPU Validation.
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700180template <typename T>
181void GpuAssisted::ReportSetupProblem(T object, const char *const specific_message) const {
182 LogError(object, "UNASSIGNED-GPU-Assisted Validation Error. ", "Detail: (%s)", specific_message);
Karl Schultz7b024b42018-08-30 16:18:18 -0600183}
184
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600185void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
186 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700187 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
188 // acceleration structure build validation will find and replace invalid acceleration structure
189 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600190 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
191 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
192 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -0700193 }
194}
195
Karl Schultz7b024b42018-08-30 16:18:18 -0600196// Turn on necessary device features.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600197void GpuAssisted::PreCallRecordCreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info,
198 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice,
199 safe_VkDeviceCreateInfo *modified_create_info) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600200 DispatchGetPhysicalDeviceFeatures(gpu, &supported_features);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600201 VkPhysicalDeviceFeatures features = {};
202 features.vertexPipelineStoresAndAtomics = true;
203 features.fragmentStoresAndAtomics = true;
204 features.shaderInt64 = true;
205 SharedPreCallRecordCreateDevice(gpu, modified_create_info, supported_features, features);
Karl Schultz7b024b42018-08-30 16:18:18 -0600206}
Karl Schultz7b024b42018-08-30 16:18:18 -0600207// Perform initializations that can be done at Create Device time.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600208void GpuAssisted::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
209 const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
210 // The state tracker sets up the device state
Tony-LunarG99b880b2019-09-26 11:19:52 -0600211 ValidationStateTracker::PostCallRecordCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice, result);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600212
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600213 ValidationObject *device_object = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
214 ValidationObject *validation_data = GetValidationObject(device_object->object_dispatch, this->container_type);
215 GpuAssisted *device_gpu_assisted = static_cast<GpuAssisted *>(validation_data);
Tony-LunarG65f9c492019-01-17 14:24:42 -0700216
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600217 if (device_gpu_assisted->phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700218 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600219 device_gpu_assisted->aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600220 return;
221 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600222
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600223 if (!device_gpu_assisted->enabled_features.core.fragmentStoresAndAtomics ||
224 !device_gpu_assisted->enabled_features.core.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700225 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600226 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
227 "GPU-Assisted Validation disabled.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600228 device_gpu_assisted->aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600229 return;
230 }
231
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700232 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
233 !device_gpu_assisted->enabled_features.core.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700234 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
235 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600236 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600237 device_gpu_assisted->shaderInt64 = device_gpu_assisted->enabled_features.core.shaderInt64;
Tony-LunarG1dce2392019-10-23 16:49:29 -0600238 device_gpu_assisted->physicalDevice = physicalDevice;
239 device_gpu_assisted->device = *pDevice;
240 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInst2MaxOutCnt + 1);
241 std::vector<VkDescriptorSetLayoutBinding> bindings;
242 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
243 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT | kShaderStageAllRayTracing,
244 NULL};
245 bindings.push_back(binding);
246 for (auto i = 1; i < 3; i++) {
247 binding.binding = i;
248 bindings.push_back(binding);
Karl Schultz7b024b42018-08-30 16:18:18 -0600249 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600250 SharedPostCallRecordCreateDevice(pCreateInfo, bindings, device_gpu_assisted, device_gpu_assisted->phys_dev_props);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600251 CreateAccelerationStructureBuildValidationState(device_gpu_assisted);
Karl Schultz7b024b42018-08-30 16:18:18 -0600252}
253
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600254void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
255 VkDeviceAddress address) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600256 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
257 // Validate against the size requested when the buffer was created
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600258 if (buffer_state) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600259 buffer_map[address] = buffer_state->createInfo.size;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600260 buffer_state->deviceAddress = address;
261 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600262}
263
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700264void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
265 VkDeviceAddress address) {
266 BUFFER_STATE *buffer_state = GetBufferState(pInfo->buffer);
267 // Validate against the size requested when the buffer was created
268 if (buffer_state) {
269 buffer_map[address] = buffer_state->createInfo.size;
270 buffer_state->deviceAddress = address;
271 }
272}
273
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600274void GpuAssisted::PreCallRecordDestroyBuffer(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600275 BUFFER_STATE *buffer_state = GetBufferState(buffer);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600276 if (buffer_state) buffer_map.erase(buffer_state->deviceAddress);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600277}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600278
Karl Schultz7b024b42018-08-30 16:18:18 -0600279// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600280void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600281 DestroyAccelerationStructureBuildValidationState();
Tony-LunarG1dce2392019-10-23 16:49:29 -0600282 SharedPreCallRecordDestroyDevice(this);
Karl Schultz7b024b42018-08-30 16:18:18 -0600283}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600284
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600285void GpuAssisted::CreateAccelerationStructureBuildValidationState(GpuAssisted *device_gpuav) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600286 if (device_gpuav->aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700287 return;
288 }
289
Tony-LunarG99b880b2019-09-26 11:19:52 -0600290 auto &as_validation_state = device_gpuav->acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700291 if (as_validation_state.initialized) {
292 return;
293 }
294
295 if (!device_extensions.vk_nv_ray_tracing) {
296 return;
297 }
298
299 // Outline:
300 // - Create valid bottom level acceleration structure which acts as replacement
301 // - Create and load vertex buffer
302 // - Create and load index buffer
303 // - Create, allocate memory for, and bind memory for acceleration structure
304 // - Query acceleration structure handle
305 // - Create command pool and command buffer
306 // - Record build acceleration structure command
307 // - Submit command buffer and wait for completion
308 // - Cleanup
309 // - Create compute pipeline for validating instance buffers
310 // - Create descriptor set layout
311 // - Create pipeline layout
312 // - Create pipeline
313 // - Cleanup
314
315 VkResult result = VK_SUCCESS;
316
317 VkBuffer vbo = VK_NULL_HANDLE;
318 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
319 if (result == VK_SUCCESS) {
320 VkBufferCreateInfo vbo_ci = {};
321 vbo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
322 vbo_ci.size = sizeof(float) * 9;
323 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
324
325 VmaAllocationCreateInfo vbo_ai = {};
326 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
327 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
328
Tony-LunarG99b880b2019-09-26 11:19:52 -0600329 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700330 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700331 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700332 }
333 }
334
335 if (result == VK_SUCCESS) {
336 uint8_t *mapped_vbo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600337 result = vmaMapMemory(device_gpuav->vmaAllocator, vbo_allocation, (void **)&mapped_vbo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700338 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700339 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700340 } else {
341 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
342 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600343 vmaUnmapMemory(device_gpuav->vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700344 }
345 }
346
347 VkBuffer ibo = VK_NULL_HANDLE;
348 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
349 if (result == VK_SUCCESS) {
350 VkBufferCreateInfo ibo_ci = {};
351 ibo_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
352 ibo_ci.size = sizeof(uint32_t) * 3;
353 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
354
355 VmaAllocationCreateInfo ibo_ai = {};
356 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
357 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
358
Tony-LunarG99b880b2019-09-26 11:19:52 -0600359 result = vmaCreateBuffer(device_gpuav->vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700360 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700361 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700362 }
363 }
364
365 if (result == VK_SUCCESS) {
366 uint8_t *mapped_ibo_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600367 result = vmaMapMemory(device_gpuav->vmaAllocator, ibo_allocation, (void **)&mapped_ibo_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700368 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700369 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700370 } else {
371 const std::vector<uint32_t> indicies = {0, 1, 2};
372 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Tony-LunarG99b880b2019-09-26 11:19:52 -0600373 vmaUnmapMemory(device_gpuav->vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700374 }
375 }
376
377 VkGeometryNV geometry = {};
378 geometry.sType = VK_STRUCTURE_TYPE_GEOMETRY_NV;
379 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
380 geometry.geometry.triangles.sType = VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV;
381 geometry.geometry.triangles.vertexData = vbo;
382 geometry.geometry.triangles.vertexOffset = 0;
383 geometry.geometry.triangles.vertexCount = 3;
384 geometry.geometry.triangles.vertexStride = 12;
385 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
386 geometry.geometry.triangles.indexData = ibo;
387 geometry.geometry.triangles.indexOffset = 0;
388 geometry.geometry.triangles.indexCount = 3;
389 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
390 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
391 geometry.geometry.triangles.transformOffset = 0;
392 geometry.geometry.aabbs = {};
393 geometry.geometry.aabbs.sType = VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV;
394
395 VkAccelerationStructureCreateInfoNV as_ci = {};
396 as_ci.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV;
397 as_ci.info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV;
398 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
399 as_ci.info.instanceCount = 0;
400 as_ci.info.geometryCount = 1;
401 as_ci.info.pGeometries = &geometry;
402 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600403 result = DispatchCreateAccelerationStructureNV(device_gpuav->device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700404 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700405 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700406 "Failed to create acceleration structure for acceleration structure build validation.");
407 }
408 }
409
410 VkMemoryRequirements2 as_mem_requirements = {};
411 if (result == VK_SUCCESS) {
412 VkAccelerationStructureMemoryRequirementsInfoNV as_mem_requirements_info = {};
413 as_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
414 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
415 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
416
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600417 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700418 }
419
420 VmaAllocationInfo as_memory_ai = {};
421 if (result == VK_SUCCESS) {
422 VmaAllocationCreateInfo as_memory_aci = {};
423 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
424
Tony-LunarG99b880b2019-09-26 11:19:52 -0600425 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
426 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700427 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700428 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700429 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
430 }
431 }
432
433 if (result == VK_SUCCESS) {
434 VkBindAccelerationStructureMemoryInfoNV as_bind_info = {};
435 as_bind_info.sType = VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV;
436 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
437 as_bind_info.memory = as_memory_ai.deviceMemory;
438 as_bind_info.memoryOffset = as_memory_ai.offset;
439
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600440 result = DispatchBindAccelerationStructureMemoryNV(device_gpuav->device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700441 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700442 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700443 "Failed to bind acceleration structure memory for acceleration structure build validation.");
444 }
445 }
446
447 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600448 result = DispatchGetAccelerationStructureHandleNV(device_gpuav->device, as_validation_state.replacement_as,
449 sizeof(uint64_t), &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700450 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700451 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700452 "Failed to get acceleration structure handle for acceleration structure build validation.");
453 }
454 }
455
456 VkMemoryRequirements2 scratch_mem_requirements = {};
457 if (result == VK_SUCCESS) {
458 VkAccelerationStructureMemoryRequirementsInfoNV scratch_mem_requirements_info = {};
459 scratch_mem_requirements_info.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV;
460 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
461 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
462
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600463 DispatchGetAccelerationStructureMemoryRequirementsNV(device_gpuav->device, &scratch_mem_requirements_info,
464 &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700465 }
466
467 VkBuffer scratch = VK_NULL_HANDLE;
468 if (result == VK_SUCCESS) {
469 VkBufferCreateInfo scratch_ci = {};
470 scratch_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
471 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
472 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
473
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600474 result = DispatchCreateBuffer(device_gpuav->device, &scratch_ci, nullptr, &scratch);
Jason Macnak83cfd582019-07-31 10:14:24 -0700475 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700476 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700477 "Failed to create scratch buffer for acceleration structure build validation.");
478 }
479 }
480
481 VmaAllocation scratch_allocation = VK_NULL_HANDLE;
482 VmaAllocationInfo scratch_allocation_info = {};
483 if (result == VK_SUCCESS) {
484 VmaAllocationCreateInfo scratch_aci = {};
485 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
486
Tony-LunarG99b880b2019-09-26 11:19:52 -0600487 result = vmaAllocateMemory(device_gpuav->vmaAllocator, &scratch_mem_requirements.memoryRequirements, &scratch_aci,
488 &scratch_allocation, &scratch_allocation_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700489 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700490 ReportSetupProblem(device_gpuav->device, "Failed to alloc scratch memory for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700491 }
492 }
493
494 if (result == VK_SUCCESS) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600495 result = DispatchBindBufferMemory(device_gpuav->device, scratch, scratch_allocation_info.deviceMemory,
496 scratch_allocation_info.offset);
Jason Macnak83cfd582019-07-31 10:14:24 -0700497 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700498 ReportSetupProblem(device_gpuav->device, "Failed to bind scratch memory for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700499 }
500 }
501
502 VkCommandPool command_pool = VK_NULL_HANDLE;
503 if (result == VK_SUCCESS) {
504 VkCommandPoolCreateInfo command_pool_ci = {};
505 command_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
506 command_pool_ci.queueFamilyIndex = 0;
507
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600508 result = DispatchCreateCommandPool(device_gpuav->device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700509 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700510 ReportSetupProblem(device_gpuav->device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700511 }
512 }
513
514 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
515
516 if (result == VK_SUCCESS) {
517 VkCommandBufferAllocateInfo command_buffer_ai = {};
518 command_buffer_ai.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
519 command_buffer_ai.commandPool = command_pool;
520 command_buffer_ai.commandBufferCount = 1;
521 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
522
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600523 result = DispatchAllocateCommandBuffers(device_gpuav->device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700524 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700525 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700526 "Failed to create command buffer for acceleration structure build validation.");
527 }
528
529 // Hook up command buffer dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600530 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700531 }
532
533 if (result == VK_SUCCESS) {
534 VkCommandBufferBeginInfo command_buffer_bi = {};
535 command_buffer_bi.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
536
537 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
538 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700539 ReportSetupProblem(device_gpuav->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) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600551 DispatchGetDeviceQueue(device_gpuav->device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700552
553 // Hook up queue dispatch
Tony-LunarG99b880b2019-09-26 11:19:52 -0600554 device_gpuav->vkSetDeviceLoaderData(device_gpuav->device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700555
556 VkSubmitInfo submit_info = {};
557 submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
558 submit_info.commandBufferCount = 1;
559 submit_info.pCommandBuffers = &command_buffer;
560 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
561 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700562 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700563 "Failed to submit command buffer for acceleration structure build validation.");
564 }
565 }
566
567 if (result == VK_SUCCESS) {
568 result = DispatchQueueWaitIdle(queue);
569 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700570 ReportSetupProblem(device_gpuav->device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700571 }
572 }
573
574 if (vbo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600575 vmaDestroyBuffer(device_gpuav->vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700576 }
577 if (ibo != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600578 vmaDestroyBuffer(device_gpuav->vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700579 }
580 if (scratch != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600581 DispatchDestroyBuffer(device_gpuav->device, scratch, nullptr);
Tony-LunarG99b880b2019-09-26 11:19:52 -0600582 vmaFreeMemory(device_gpuav->vmaAllocator, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700583 }
584 if (command_pool != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600585 DispatchDestroyCommandPool(device_gpuav->device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700586 }
587
Tony-LunarG99b880b2019-09-26 11:19:52 -0600588 if (device_gpuav->debug_desc_layout == VK_NULL_HANDLE) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700589 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700590 "Failed to find descriptor set layout for acceleration structure build validation.");
591 result = VK_INCOMPLETE;
592 }
593
594 if (result == VK_SUCCESS) {
595 VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
596 pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
597 pipeline_layout_ci.setLayoutCount = 1;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600598 pipeline_layout_ci.pSetLayouts = &device_gpuav->debug_desc_layout;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600599 result = DispatchCreatePipelineLayout(device_gpuav->device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700600 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700601 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700602 "Failed to create pipeline layout for acceleration structure build validation.");
603 }
604 }
605
606 VkShaderModule shader_module = VK_NULL_HANDLE;
607 if (result == VK_SUCCESS) {
608 VkShaderModuleCreateInfo shader_module_ci = {};
609 shader_module_ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
610 shader_module_ci.codeSize = sizeof(kComputeShaderSpirv);
611 shader_module_ci.pCode = (uint32_t *)kComputeShaderSpirv;
612
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600613 result = DispatchCreateShaderModule(device_gpuav->device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700614 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700615 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700616 "Failed to create compute shader module for acceleration structure build validation.");
617 }
618 }
619
620 if (result == VK_SUCCESS) {
621 VkPipelineShaderStageCreateInfo pipeline_stage_ci = {};
622 pipeline_stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
623 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
624 pipeline_stage_ci.module = shader_module;
625 pipeline_stage_ci.pName = "main";
626
627 VkComputePipelineCreateInfo pipeline_ci = {};
628 pipeline_ci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
629 pipeline_ci.stage = pipeline_stage_ci;
630 pipeline_ci.layout = as_validation_state.pipeline_layout;
631
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600632 result = DispatchCreateComputePipelines(device_gpuav->device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr,
633 &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700634 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700635 ReportSetupProblem(device_gpuav->device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700636 "Failed to create compute pipeline for acceleration structure build validation.");
637 }
638 }
639
640 if (shader_module != VK_NULL_HANDLE) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600641 DispatchDestroyShaderModule(device_gpuav->device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700642 }
643
644 if (result == VK_SUCCESS) {
645 as_validation_state.initialized = true;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700646 LogInfo(device_gpuav->device, "UNASSIGNED-GPU-Assisted Validation.",
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600647 "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700648 } else {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600649 device_gpuav->aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700650 }
651}
652
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600653void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600654 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700655 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
656 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
657 }
658 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
659 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
660 }
661 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
662 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
663 }
664 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600665 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700666 }
667}
668
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600669struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700670 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
671 VkPipeline pipeline = VK_NULL_HANDLE;
672 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
673 std::vector<VkDescriptorSet> descriptor_sets;
674 std::vector<std::vector<uint32_t>> dynamic_offsets;
675 uint32_t push_descriptor_set_index = 0;
676 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
677 std::vector<uint8_t> push_constants_data;
678 PushConstantRangesId push_constants_ranges;
679
680 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
681 pipeline_bind_point = bind_point;
682
683 LAST_BOUND_STATE &last_bound = cb_state->lastBound[bind_point];
684 if (last_bound.pipeline_state) {
685 pipeline = last_bound.pipeline_state->pipeline;
686 pipeline_layout = last_bound.pipeline_layout;
687 descriptor_sets.reserve(last_bound.per_set.size());
688 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
689 const auto *bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
690
691 descriptor_sets.push_back(bound_descriptor_set->GetSet());
692 if (bound_descriptor_set->IsPushDescriptor()) {
693 push_descriptor_set_index = static_cast<uint32_t>(i);
694 }
695 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
696 }
697
698 if (last_bound.push_descriptor_set) {
699 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
700 }
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500701 if (last_bound.pipeline_state->pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700702 push_constants_data = cb_state->push_constant_data;
Jeff Bolze7fc67b2019-10-04 12:29:31 -0500703 push_constants_ranges = last_bound.pipeline_state->pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700704 }
705 }
706 }
707
708 void Restore(VkCommandBuffer command_buffer) const {
709 if (pipeline != VK_NULL_HANDLE) {
710 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
711 if (!descriptor_sets.empty()) {
712 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
713 VkDescriptorSet descriptor_set = descriptor_sets[i];
714 if (descriptor_set != VK_NULL_HANDLE) {
715 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
716 static_cast<uint32_t>(i), 1, &descriptor_set,
717 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
718 }
719 }
720 }
721 if (!push_descriptor_set_writes.empty()) {
722 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
723 static_cast<uint32_t>(push_descriptor_set_writes.size()),
724 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
725 }
726 for (const auto &push_constant_range : *push_constants_ranges) {
727 if (push_constant_range.size == 0) continue;
728 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
729 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
730 }
731 }
732 }
733};
734
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600735void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
736 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
737 VkDeviceSize instanceOffset, VkBool32 update,
738 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
739 VkBuffer scratch, VkDeviceSize scratchOffset) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700740 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
741 return;
742 }
743
Tony-LunarG99b880b2019-09-26 11:19:52 -0600744 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700745 if (!as_validation_state.initialized) {
746 return;
747 }
748
749 // Empty acceleration structure is valid according to the spec.
750 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
751 return;
752 }
753
754 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
755 assert(cb_state != nullptr);
756
757 std::vector<uint64_t> current_valid_handles;
758 for (const auto &as_state_kv : accelerationStructureMap) {
759 const ACCELERATION_STRUCTURE_STATE &as_state = *as_state_kv.second;
760 if (as_state.built && as_state.create_info.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
761 current_valid_handles.push_back(as_state.opaque_handle);
762 }
763 }
764
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600765 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700766 as_validation_buffer_info.acceleration_structure = dst;
767
768 const VkDeviceSize validation_buffer_size =
769 // One uint for number of instances to validate
770 4 +
771 // Two uint for the replacement acceleration structure handle
772 8 +
773 // One uint for number of invalid handles found
774 4 +
775 // Two uint for the first invalid handle found
776 8 +
777 // One uint for the number of current valid handles
778 4 +
779 // Two uint for each current valid handle
780 (8 * current_valid_handles.size());
781
782 VkBufferCreateInfo validation_buffer_create_info = {};
783 validation_buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
784 validation_buffer_create_info.size = validation_buffer_size;
785 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
786
787 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
788 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
789
Tony-LunarG99b880b2019-09-26 11:19:52 -0600790 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
791 &as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -0700792 &as_validation_buffer_info.validation_buffer_allocation, nullptr);
793 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700794 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600795 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700796 return;
797 }
798
799 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600800 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700801 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700802 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600803 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700804 return;
805 }
806
807 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
808 mapped_validation_buffer->replacement_handle_bits_0 =
809 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
810 mapped_validation_buffer->replacement_handle_bits_1 =
811 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
812 mapped_validation_buffer->invalid_handle_found = 0;
813 mapped_validation_buffer->invalid_handle_bits_0 = 0;
814 mapped_validation_buffer->invalid_handle_bits_1 = 0;
815 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
816
817 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
818 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
819 const uint64_t current_valid_handle = current_valid_handles[i];
820
821 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
822 ++mapped_valid_handles;
823 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
824 ++mapped_valid_handles;
825 }
826
Tony-LunarG99b880b2019-09-26 11:19:52 -0600827 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700828
829 static constexpr const VkDeviceSize kInstanceSize = 64;
830 const VkDeviceSize instance_buffer_size = kInstanceSize * pInfo->instanceCount;
831
Tony-LunarG1dce2392019-10-23 16:49:29 -0600832 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
833 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700834 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700835 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600836 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700837 return;
838 }
839
840 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
841 descriptor_buffer_infos[0].buffer = instanceData;
842 descriptor_buffer_infos[0].offset = instanceOffset;
843 descriptor_buffer_infos[0].range = instance_buffer_size;
844 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.validation_buffer;
845 descriptor_buffer_infos[1].offset = 0;
846 descriptor_buffer_infos[1].range = validation_buffer_size;
847
848 VkWriteDescriptorSet descriptor_set_writes[2] = {};
849 descriptor_set_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
850 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
851 descriptor_set_writes[0].dstBinding = 0;
852 descriptor_set_writes[0].descriptorCount = 1;
853 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
854 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
855 descriptor_set_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
856 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
857 descriptor_set_writes[1].dstBinding = 1;
858 descriptor_set_writes[1].descriptorCount = 1;
859 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
860 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
861
862 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
863
864 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
865 VkMemoryBarrier memory_barrier = {};
866 memory_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
867 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
868 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
869 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
870 &memory_barrier, 0, nullptr, 0, nullptr);
871
872 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600873 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700874 restorable_state.Create(cb_state, VK_PIPELINE_BIND_POINT_COMPUTE);
875
876 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
877 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
878 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
879 &as_validation_buffer_info.descriptor_set, 0, nullptr);
880 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
881
882 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
883 // have been replaced by the validation compute shader before any builds take place.
884 VkBufferMemoryBarrier instance_buffer_barrier = {};
885 instance_buffer_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
886 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
887 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
888 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
889 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
890 instance_buffer_barrier.buffer = instanceData;
891 instance_buffer_barrier.offset = instanceOffset;
892 instance_buffer_barrier.size = instance_buffer_size;
893 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
894 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
895 nullptr);
896
897 // Restore the previous compute pipeline state.
898 restorable_state.Restore(commandBuffer);
899
900 as_validation_state.validation_buffers[commandBuffer].push_back(std::move(as_validation_buffer_info));
901}
902
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600903void GpuAssisted::ProcessAccelerationStructureBuildValidationBuffer(VkQueue queue, CMD_BUFFER_STATE *cb_node) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700904 if (cb_node == nullptr || !cb_node->hasBuildAccelerationStructureCmd) {
905 return;
906 }
907
Tony-LunarG99b880b2019-09-26 11:19:52 -0600908 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700909 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[cb_node->commandBuffer];
910 for (const auto &as_validation_buffer_info : as_validation_buffer_infos) {
911 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
912
Tony-LunarG99b880b2019-09-26 11:19:52 -0600913 VkResult result =
914 vmaMapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation, (void **)&mapped_validation_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700915 if (result == VK_SUCCESS) {
916 if (mapped_validation_buffer->invalid_handle_found > 0) {
917 uint64_t invalid_handle = 0;
918 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
919 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
920
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700921 LogError(as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
922 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
923 "handle (%" PRIu64 ")",
924 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700925 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600926 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.validation_buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700927 }
928 }
929}
930
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600931void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
932 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
933 VkResult result) {
934 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600935 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600936 for (uint32_t i = 0; i < bindInfoCount; i++) {
937 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
938 ACCELERATION_STRUCTURE_STATE *as_state = GetAccelerationStructureState(info.accelerationStructure);
939 if (as_state) {
940 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
941 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600942 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600943}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700944
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600945// Modify the pipeline layout to include our debug descriptor set and any needed padding with the dummy descriptor set.
946void GpuAssisted::PreCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
947 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
948 void *cpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600949 if (aborted) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600950 return;
951 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600952
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600953 create_pipeline_layout_api_state *cpl_state = reinterpret_cast<create_pipeline_layout_api_state *>(cpl_state_data);
954
Tony-LunarG99b880b2019-09-26 11:19:52 -0600955 if (cpl_state->modified_create_info.setLayoutCount >= adjusted_max_desc_sets) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600956 std::ostringstream strm;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600957 strm << "Pipeline Layout conflict with validation's descriptor set at slot " << desc_set_bind_index << ". "
Karl Schultz7b024b42018-08-30 16:18:18 -0600958 << "Application has too many descriptor sets in the pipeline layout to continue with gpu validation. "
959 << "Validation is not modifying the pipeline layout. "
960 << "Instrumented shaders are replaced with non-instrumented shaders.";
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700961 ReportSetupProblem(device, strm.str().c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -0600962 } else {
Tony-LunarG1dce2392019-10-23 16:49:29 -0600963 SharedPreCallRecordCreatePipelineLayout(cpl_state, this, pCreateInfo);
Karl Schultz7b024b42018-08-30 16:18:18 -0600964 }
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700965}
966
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600967void GpuAssisted::PostCallRecordCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo *pCreateInfo,
968 const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout,
969 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600970 ValidationStateTracker::PostCallRecordCreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout, result);
971
Karl Schultz7b024b42018-08-30 16:18:18 -0600972 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700973 ReportSetupProblem(device, "Unable to create pipeline layout. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600974 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600975 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600976}
977
Karl Schultz7b024b42018-08-30 16:18:18 -0600978// Free the device memory and descriptor set associated with a command buffer.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600979void GpuAssisted::ResetCommandBuffer(VkCommandBuffer commandBuffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600980 if (aborted) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600981 return;
982 }
Tony-LunarG1dce2392019-10-23 16:49:29 -0600983 auto gpuav_buffer_list = GetBufferInfo(commandBuffer);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600984 for (auto buffer_info : gpuav_buffer_list) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600985 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600986 if (buffer_info.di_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600987 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600988 }
989 if (buffer_info.bda_input_mem_block.buffer) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600990 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600991 }
Tony-LunarGdcbc2c32019-05-06 10:17:44 -0600992 if (buffer_info.desc_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600993 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Tony-LunarGdcbc2c32019-05-06 10:17:44 -0600994 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600995 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600996 command_buffer_map.erase(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700997
Tony-LunarG99b880b2019-09-26 11:19:52 -0600998 auto &as_validation_info = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700999 auto &as_validation_buffer_infos = as_validation_info.validation_buffers[commandBuffer];
1000 for (auto &as_validation_buffer_info : as_validation_buffer_infos) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001001 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.validation_buffer,
Jason Macnak83cfd582019-07-31 10:14:24 -07001002 as_validation_buffer_info.validation_buffer_allocation);
1003
1004 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001005 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool,
1006 as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -07001007 }
1008 }
1009 as_validation_info.validation_buffers.erase(commandBuffer);
Karl Schultz7b024b42018-08-30 16:18:18 -06001010}
Karl Schultz7b024b42018-08-30 16:18:18 -06001011// Just gives a warning about a possible deadlock.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001012bool GpuAssisted::PreCallValidateCmdWaitEvents(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent *pEvents,
1013 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
1014 uint32_t memoryBarrierCount, const VkMemoryBarrier *pMemoryBarriers,
1015 uint32_t bufferMemoryBarrierCount,
1016 const VkBufferMemoryBarrier *pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount,
Jeff Bolz5c801d12019-10-09 10:38:45 -05001017 const VkImageMemoryBarrier *pImageMemoryBarriers) const {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001018 if (srcStageMask & VK_PIPELINE_STAGE_HOST_BIT) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001019 ReportSetupProblem(commandBuffer,
Karl Schultz7b024b42018-08-30 16:18:18 -06001020 "CmdWaitEvents recorded with VK_PIPELINE_STAGE_HOST_BIT set. "
1021 "GPU_Assisted validation waits on queue completion. "
1022 "This wait could block the host's signaling of this event, resulting in deadlock.");
1023 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001024 return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001025}
1026
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001027void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
1028 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
1029 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
1030 if (enabled.gpu_validation_reserve_binding_slot && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
1031 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
1032 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
1033 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001034 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1035 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001036 }
1037 }
1038}
1039
1040void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
1041 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
1042 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
1043 if (enabled.gpu_validation_reserve_binding_slot && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
1044 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
1045 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
1046 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001047 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
1048 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001049 }
1050 }
1051}
1052
1053void GpuAssisted::PreCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1054 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1055 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1056 void *cgpl_state_data) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001057 std::vector<safe_VkGraphicsPipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001058 create_graphics_pipeline_api_state *cgpl_state = reinterpret_cast<create_graphics_pipeline_api_state *>(cgpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001059 SharedPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, cgpl_state->pipe_state,
1060 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001061 cgpl_state->gpu_create_infos = new_pipeline_create_infos;
1062 cgpl_state->pCreateInfos = reinterpret_cast<VkGraphicsPipelineCreateInfo *>(cgpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001063}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001064
1065void GpuAssisted::PreCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1066 const VkComputePipelineCreateInfo *pCreateInfos,
1067 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1068 void *ccpl_state_data) {
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001069 std::vector<safe_VkComputePipelineCreateInfo> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001070 auto *ccpl_state = reinterpret_cast<create_compute_pipeline_api_state *>(ccpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001071 SharedPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, ccpl_state->pipe_state,
1072 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001073 ccpl_state->gpu_create_infos = new_pipeline_create_infos;
1074 ccpl_state->pCreateInfos = reinterpret_cast<VkComputePipelineCreateInfo *>(ccpl_state->gpu_create_infos.data());
Jason Macnak67407e72019-07-11 11:05:09 -07001075}
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001076
1077void GpuAssisted::PreCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1078 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1079 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1080 void *crtpl_state_data) {
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001081 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001082 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_api_state *>(crtpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001083 SharedPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1084 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001085 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1086 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoNV *>(crtpl_state->gpu_create_infos.data());
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001087}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001088
1089void GpuAssisted::PreCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1090 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1091 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1092 void *crtpl_state_data) {
1093 std::vector<safe_VkRayTracingPipelineCreateInfoCommon> new_pipeline_create_infos;
1094 auto *crtpl_state = reinterpret_cast<create_ray_tracing_pipeline_khr_api_state *>(crtpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001095 SharedPreCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, crtpl_state->pipe_state,
1096 &new_pipeline_create_infos, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001097 crtpl_state->gpu_create_infos = new_pipeline_create_infos;
1098 crtpl_state->pCreateInfos = reinterpret_cast<VkRayTracingPipelineCreateInfoKHR *>(crtpl_state->gpu_create_infos.data());
1099}
Karl Schultz7b024b42018-08-30 16:18:18 -06001100
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001101void GpuAssisted::PostCallRecordCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1102 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1103 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1104 VkResult result, void *cgpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001105 ValidationStateTracker::PostCallRecordCreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
1106 pPipelines, result, cgpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001107 SharedPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_GRAPHICS, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001108}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001109
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001110void GpuAssisted::PostCallRecordCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1111 const VkComputePipelineCreateInfo *pCreateInfos,
1112 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1113 VkResult result, void *ccpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001114 ValidationStateTracker::PostCallRecordCreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines,
1115 result, ccpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001116 SharedPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_COMPUTE, this);
Tony-LunarGeb25bf52019-04-26 10:46:41 -06001117}
Tony-LunarG99b880b2019-09-26 11:19:52 -06001118
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001119void GpuAssisted::PostCallRecordCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1120 const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
1121 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1122 VkResult result, void *crtpl_state_data) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001123 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesNV(device, pipelineCache, count, pCreateInfos, pAllocator,
1124 pPipelines, result, crtpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001125 SharedPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, this);
Jason Macnak67407e72019-07-11 11:05:09 -07001126}
1127
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001128void GpuAssisted::PostCallRecordCreateRayTracingPipelinesKHR(VkDevice device, VkPipelineCache pipelineCache, uint32_t count,
1129 const VkRayTracingPipelineCreateInfoKHR *pCreateInfos,
1130 const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines,
1131 VkResult result, void *crtpl_state_data) {
1132 ValidationStateTracker::PostCallRecordCreateRayTracingPipelinesKHR(device, pipelineCache, count, pCreateInfos, pAllocator,
1133 pPipelines, result, crtpl_state_data);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001134 SharedPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
1135 this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001136}
1137
1138// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001139void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001140 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001141 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001142 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001143 } else {
1144 ++it;
1145 }
1146 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001147 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001148}
1149
1150// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001151bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1152 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001153 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001154 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1155
1156 // Load original shader SPIR-V
1157 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1158 new_pgm.clear();
1159 new_pgm.reserve(num_words);
1160 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1161
1162 // Call the optimizer to instrument the shader.
1163 // 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 -07001164 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Tony-LunarG2ec96bb2019-11-26 13:43:02 -07001165 const bool descriptor_indexing = IsExtEnabled(device_extensions.vk_ext_descriptor_indexing);
Karl Schultz7b024b42018-08-30 16:18:18 -06001166 using namespace spvtools;
1167 spv_target_env target_env = SPV_ENV_VULKAN_1_1;
1168 Optimizer optimizer(target_env);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001169 optimizer.RegisterPass(
Tony-LunarGab47cac2019-12-20 15:28:01 -07001170 CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing, descriptor_indexing));
Karl Schultz7b024b42018-08-30 16:18:18 -06001171 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG7e0842f2019-12-10 09:26:34 -07001172 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64)
Tony-LunarG99b880b2019-09-26 11:19:52 -06001173 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Karl Schultz7b024b42018-08-30 16:18:18 -06001174 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm);
1175 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001176 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001177 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001178 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001179 return pass;
1180}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001181// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001182void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1183 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1184 void *csm_state_data) {
1185 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1186 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001187 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001188 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1189 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001190 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001191}
1192
Karl Schultz7b024b42018-08-30 16:18:18 -06001193// Generate the part of the message describing the violation.
1194static void GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg) {
1195 using namespace spvtools;
1196 std::ostringstream strm;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001197 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001198 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001199 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1200 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001201 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001202 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001203 case kInstErrorBindlessUninit: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001204 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized. ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001205 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001206 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001207 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001208 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001209 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1210 vuid_msg = "UNASSIGNED-Device address out of bounds";
1211 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001212 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001213 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001214 vuid_msg = "UNASSIGNED-Internal Error";
1215 assert(false);
1216 } break;
1217 }
1218 msg = strm.str();
1219}
1220
Karl Schultz7b024b42018-08-30 16:18:18 -06001221// Pull together all the information from the debug record to build the error message strings,
1222// and then assemble them into a single message string.
1223// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1224// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1225// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1226// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1227//
Tony-LunarG1dce2392019-10-23 16:49:29 -06001228void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, VkPipelineBindPoint pipeline_bind_point,
1229 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001230 using namespace spvtools;
1231 const uint32_t total_words = debug_output_buffer[0];
1232 // A zero here means that the shader instrumentation didn't write anything.
1233 // If you have nothing to say, don't say it here.
1234 if (0 == total_words) {
1235 return;
1236 }
1237 // The first word in the debug output buffer is the number of words that would have
1238 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1239 // The number of words actually written by the shaders is determined by the size of the buffer
1240 // we provide via the descriptor. So, we process only the number of words that can fit in the
1241 // buffer.
1242 // Each "report" written by the shader instrumentation is considered a "record". This function
1243 // is hard-coded to process only one record because it expects the buffer to be large enough to
1244 // hold only one record. If there is a desire to process more than one record, this function needs
1245 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001246 std::string validation_message;
1247 std::string stage_message;
1248 std::string common_message;
1249 std::string filename_message;
1250 std::string source_message;
1251 std::string vuid_msg;
1252 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1253 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1254 std::vector<unsigned int> pgm;
1255 // The first record starts at this offset after the total_words.
1256 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1257 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1258 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001259 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1260 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001261 shader_module_handle = it->second.shader_module;
1262 pipeline_handle = it->second.pipeline;
1263 pgm = it->second.pgm;
1264 }
1265 GenerateValidationMessage(debug_record, validation_message, vuid_msg);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001266 SharedGenerateStageMessage(debug_record, stage_message);
1267 SharedGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1268 pipeline_bind_point, operation_index, common_message);
1269 SharedGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001270 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1271 filename_message.c_str(), source_message.c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001272 // The debug record at word kInstCommonOutSize is the number of words in the record
1273 // written by the shader. Clear the entire record plus the total_words word at the start.
Tony-LunarGab47cac2019-12-20 15:28:01 -07001274 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], (uint32_t)kInstMaxOutCnt);
Karl Schultz7b024b42018-08-30 16:18:18 -06001275 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1276}
1277
Tony-LunarG81efe392019-03-07 15:43:27 -07001278// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001279void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001280 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Tony-LunarG81efe392019-03-07 15:43:27 -07001281 uint32_t *pData;
1282 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001283 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001284 VkResult result = vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, (void **)&pData);
Tony-LunarG81efe392019-03-07 15:43:27 -07001285 if (result == VK_SUCCESS) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001286 for (auto update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001287 if (update.second->updated) pData[update.first] = 1;
1288 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001289 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001290 }
1291 }
1292 }
1293}
1294
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001295void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001296 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1297 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1298 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001299 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001300 UpdateInstrumentationBuffer(cb_node);
1301 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
1302 UpdateInstrumentationBuffer(secondaryCmdBuffer);
1303 }
1304 }
1305 }
1306}
1307
Karl Schultz58674242019-01-22 15:35:02 -07001308// Issue a memory barrier to make GPU-written data available to host.
1309// Wait for the queue to complete execution.
1310// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001311void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1312 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001313 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001314
Tony-LunarG99b880b2019-09-26 11:19:52 -06001315 if (aborted) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001316 bool buffers_present = false;
1317 // Don't QueueWaitIdle if there's nothing to process
1318 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1319 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1320 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
1321 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001322 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001323 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001324 if (GetBufferInfo(secondaryCmdBuffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd)
Jason Macnak83cfd582019-07-31 10:14:24 -07001325 buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001326 }
1327 }
1328 }
1329 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001330
Tony-LunarG1dce2392019-10-23 16:49:29 -06001331 SharedSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001332
Tony-LunarG152a88b2019-03-20 15:42:24 -06001333 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001334
Karl Schultz7b024b42018-08-30 16:18:18 -06001335 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1336 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1337 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001338 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001339 SharedProcessInstrumentationBuffer(queue, cb_node, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001340 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001341 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001342 SharedProcessInstrumentationBuffer(queue, secondaryCmdBuffer, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001343 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001344 }
1345 }
1346 }
1347}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001348
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001349void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1350 uint32_t firstVertex, uint32_t firstInstance) {
1351 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1352}
1353
1354void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1355 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
1356 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1357}
1358
1359void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1360 uint32_t stride) {
1361 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1362}
1363
1364void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1365 uint32_t count, uint32_t stride) {
1366 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1367}
1368
1369void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
1370 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1371}
1372
1373void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
1374 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1375}
1376
1377void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1378 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1379 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1380 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1381 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1382 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1383 uint32_t width, uint32_t height, uint32_t depth) {
1384 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
1385}
1386
1387void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1388 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1389 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1390 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1391 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1392 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1393 uint32_t width, uint32_t height, uint32_t depth) {
1394 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1395 cb_state->hasTraceRaysCmd = true;
1396}
1397
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001398void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1399 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1400 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1401 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1402 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1403 uint32_t height, uint32_t depth) {
1404 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1405}
1406
1407void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1408 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1409 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1410 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1411 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1412 uint32_t height, uint32_t depth) {
1413 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1414 cb_state->hasTraceRaysCmd = true;
1415}
1416
1417void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1418 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1419 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1420 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1421 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, VkBuffer buffer,
1422 VkDeviceSize offset) {
1423 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1424}
1425
1426void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1427 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1428 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1429 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1430 const VkStridedBufferRegionKHR *pCallableShaderBindingTable,
1431 VkBuffer buffer, VkDeviceSize offset) {
1432 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1433 cb_state->hasTraceRaysCmd = true;
1434}
1435
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001436void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Jason Macnak67407e72019-07-11 11:05:09 -07001437 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1438 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001439 return;
1440 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001441 VkResult result;
1442
Tony-LunarG99b880b2019-09-26 11:19:52 -06001443 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001444
1445 std::vector<VkDescriptorSet> desc_sets;
1446 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001447 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001448 assert(result == VK_SUCCESS);
1449 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001450 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001451 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001452 return;
1453 }
1454
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001455 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001456 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001457
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001458 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001459 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001460 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001461 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001462 return;
1463 }
1464
Tony-LunarG81efe392019-03-07 15:43:27 -07001465 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001466 GpuAssistedDeviceMemoryBlock output_block = {};
Tony-LunarG0e564722019-03-19 16:09:14 -06001467 VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001468 bufferInfo.size = output_buffer_size;
Tony-LunarG0e564722019-03-19 16:09:14 -06001469 bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1470 VmaAllocationCreateInfo allocInfo = {};
1471 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001472 result = vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001473 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001474 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001475 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001476 return;
1477 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001478
Tony-LunarG81efe392019-03-07 15:43:27 -07001479 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGa77cade2019-03-06 10:49:22 -07001480 uint32_t *pData;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001481 result = vmaMapMemory(vmaAllocator, output_block.allocation, (void **)&pData);
Tony-LunarG0e564722019-03-19 16:09:14 -06001482 if (result == VK_SUCCESS) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001483 memset(pData, 0, output_buffer_size);
1484 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001485 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001486
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001487 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001488 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1489 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1490 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001491 uint32_t desc_count = 1;
1492 auto const &state = cb_node->lastBound[bind_point];
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001493 uint32_t number_of_sets = (uint32_t)state.per_set.size();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001494
Tony-LunarG81efe392019-03-07 15:43:27 -07001495 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1496 // and how big each of the bindings is
Mark Lobodzinskif45e45f2019-04-19 14:15:39 -06001497 if (number_of_sets > 0 && device_extensions.vk_ext_descriptor_indexing) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001498 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1499 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001500 for (auto s : state.per_set) {
1501 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001502 if (desc && (desc->GetBindingCount() > 0)) {
1503 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001504 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1505 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001506 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1507 // blocks
1508 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1509 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001510 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1511 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1512 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001513 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001514 descriptor_count += desc->GetVariableDescriptorCount();
1515 } else {
1516 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1517 }
1518 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001519 }
1520 }
1521
Tony-LunarGa77cade2019-03-06 10:49:22 -07001522 // Note that the size of the input buffer is dependent on the maximum binding number, which
1523 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1524 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1525 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1526 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1527 uint32_t words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001528 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1529 bufferInfo.size = words_needed * 4;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001530 result =
1531 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &di_input_block.buffer, &di_input_block.allocation, nullptr);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001532 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001533 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001534 aborted = true;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001535 return;
1536 }
1537
Tony-LunarGa77cade2019-03-06 10:49:22 -07001538 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1539 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1540 // outline of the input buffer format
Tony-LunarG99b880b2019-09-26 11:19:52 -06001541 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, (void **)&pData);
Tony-LunarG76cdcac2019-05-22 16:13:12 -06001542 memset(pData, 0, static_cast<size_t>(bufferInfo.size));
Tony-LunarGa77cade2019-03-06 10:49:22 -07001543 // Pointer to a sets array that points into the sizes array
1544 uint32_t *sets_to_sizes = pData + 1;
1545 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1546 uint32_t *sizes = sets_to_sizes + number_of_sets;
1547 // Pointer to another sets array that points into the bindings array that points into the written array
1548 uint32_t *sets_to_bindings = sizes + binding_count;
1549 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1550 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1551 // Index of the next entry in the written array to be updated
1552 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001553 uint32_t bindCounter = number_of_sets + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001554 // Index of the start of the sets_to_bindings array
1555 pData[0] = number_of_sets + binding_count + 1;
1556
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001557 for (auto s : state.per_set) {
1558 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001559 if (desc && (desc->GetBindingCount() > 0)) {
1560 auto layout = desc->GetLayout();
1561 auto bindings = layout->GetSortedBindingSet();
Tony-LunarG81efe392019-03-07 15:43:27 -07001562 // For each set, fill in index of its bindings sizes in the sizes array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001563 *sets_to_sizes++ = bindCounter;
Tony-LunarG81efe392019-03-07 15:43:27 -07001564 // For each set, fill in the index of its bindings in the bindings_to_written array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001565 *sets_to_bindings++ = bindCounter + number_of_sets + binding_count;
Tony-LunarG81efe392019-03-07 15:43:27 -07001566 for (auto binding : bindings) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001567 // For each binding, fill in its size in the sizes array
Tony-LunarG7564b382019-08-21 10:11:35 -06001568 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1569 // blocks
1570 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1571 sizes[binding] = 1;
1572 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001573 sizes[binding] = desc->GetVariableDescriptorCount();
1574 } else {
1575 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
1576 }
1577 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1578 bindings_to_written[binding] = written_index;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001579
Tony-LunarG7564b382019-08-21 10:11:35 -06001580 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1581 // blocks
1582 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1583 pData[written_index++] = 1;
1584 continue;
1585 }
1586
Tony-LunarGa77cade2019-03-06 10:49:22 -07001587 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1588 // For each array element in the binding, update the written array with whether it has been written
1589 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1590 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
Tony-LunarG81efe392019-03-07 15:43:27 -07001591 if (descriptor->updated) {
1592 pData[written_index] = 1;
1593 } else if (desc->IsUpdateAfterBind(binding)) {
1594 // If it hasn't been written now and it's update after bind, put it in a list to check at QueueSubmit
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001595 di_input_block.update_at_submit[written_index] = descriptor;
Tony-LunarG81efe392019-03-07 15:43:27 -07001596 }
Tony-LunarGa77cade2019-03-06 10:49:22 -07001597 written_index++;
1598 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001599 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001600 auto last = desc->GetLayout()->GetMaxBinding();
1601 bindings_to_written += last + 1;
1602 bindCounter += last + 1;
1603 sizes += last + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001604 } else {
1605 *sets_to_sizes++ = 0;
1606 *sets_to_bindings++ = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001607 }
1608 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001609 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001610
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001611 di_input_desc_buffer_info.range = (words_needed * 4);
1612 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1613 di_input_desc_buffer_info.offset = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001614
1615 desc_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1616 desc_writes[1].dstBinding = 1;
1617 desc_writes[1].descriptorCount = 1;
1618 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001619 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001620 desc_writes[1].dstSet = desc_sets[0];
1621
1622 desc_count = 2;
Tony-LunarG0e564722019-03-19 16:09:14 -06001623 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001624
Tony-LunarG7e0842f2019-12-10 09:26:34 -07001625 if (number_of_sets > 0 && (device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
1626 buffer_map.size() && shaderInt64) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001627 // Example BDA input buffer assuming 2 buffers using BDA:
1628 // Word 0 | Index of start of buffer sizes (in this case 5)
1629 // Word 1 | 0x0000000000000000
1630 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1631 // Word 3 | Device Address of second buffer
1632 // Word 4 | 0xffffffffffffffff
1633 // Word 5 | 0 (size of pretend buffer at word 1)
1634 // Word 6 | Size in bytes of first buffer
1635 // Word 7 | Size in bytes of second buffer
1636 // Word 8 | 0 (size of pretend buffer in word 4)
1637
Tony-LunarG99b880b2019-09-26 11:19:52 -06001638 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001639 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
1640 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1641 bufferInfo.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06001642 result =
1643 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001644 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001645 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001646 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001647 return;
1648 }
1649 uint64_t *bda_data;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001650 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, (void **)&bda_data);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001651 uint32_t address_index = 1;
1652 uint32_t size_index = 3 + num_buffers;
1653 memset(bda_data, 0, static_cast<size_t>(bufferInfo.size));
1654 bda_data[0] = size_index; // Start of buffer sizes
1655 bda_data[address_index++] = 0; // NULL address
1656 bda_data[size_index++] = 0;
1657
Tony-LunarG99b880b2019-09-26 11:19:52 -06001658 for (auto const &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001659 bda_data[address_index++] = value.first;
1660 bda_data[size_index++] = value.second;
1661 }
1662 bda_data[address_index] = UINTPTR_MAX;
1663 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001664 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001665
1666 bda_input_desc_buffer_info.range = (words_needed * 8);
1667 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
1668 bda_input_desc_buffer_info.offset = 0;
1669
1670 desc_writes[desc_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1671 desc_writes[desc_count].dstBinding = 2;
1672 desc_writes[desc_count].descriptorCount = 1;
1673 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1674 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
1675 desc_writes[desc_count].dstSet = desc_sets[0];
1676 desc_count++;
1677 }
1678
Tony-LunarGb2501d22019-01-28 09:59:13 -07001679 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001680 output_desc_buffer_info.buffer = output_block.buffer;
1681 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001682
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001683 desc_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1684 desc_writes[0].descriptorCount = 1;
1685 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1686 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
1687 desc_writes[0].dstSet = desc_sets[0];
1688 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001689
andreyg25ce2622019-04-05 23:07:59 +03001690 auto iter = cb_node->lastBound.find(bind_point); // find() allows read-only access to cb_state
Tony-LunarGb2501d22019-01-28 09:59:13 -07001691 if (iter != cb_node->lastBound.end()) {
1692 auto pipeline_state = iter->second.pipeline_state;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001693 if (pipeline_state && (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index)) {
1694 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06001695 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001696 }
Tony-LunarG0e564722019-03-19 16:09:14 -06001697 // Record buffer and memory info in CB state tracking
Tony-LunarG1dce2392019-10-23 16:49:29 -06001698 GetBufferInfo(cmd_buffer).emplace_back(output_block, di_input_block, bda_input_block, desc_sets[0], desc_pool, bind_point);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001699 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001700 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001701 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
1702 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
1703 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
1704 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001705 return;
1706 }
1707}