blob: 4d185bbfb8a67808cf885bfdb830b3779565ba4c [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;
Tony-LunarGb5fae462020-03-05 12:43:25 -0700205 UtilPreCallRecordCreateDevice(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;
Tony-LunarGbb145f32020-04-27 13:41:29 -0600240 device_gpu_assisted->output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarG1dce2392019-10-23 16:49:29 -0600241 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-LunarGb5fae462020-03-05 12:43:25 -0700250 UtilPostCallRecordCreateDevice(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-LunarG588c7052020-04-23 10:47:21 -0600254void GpuAssisted::PostCallRecordGetBufferDeviceAddress(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-LunarG588c7052020-04-23 10:47:21 -0600264void GpuAssisted::PostCallRecordGetBufferDeviceAddressEXT(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
265 VkDeviceAddress address) {
266 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
267}
268
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700269void GpuAssisted::PostCallRecordGetBufferDeviceAddressKHR(VkDevice device, const VkBufferDeviceAddressInfoEXT *pInfo,
270 VkDeviceAddress address) {
Tony-LunarG588c7052020-04-23 10:47:21 -0600271 PostCallRecordGetBufferDeviceAddress(device, pInfo, address);
Tony-LunarG7e0842f2019-12-10 09:26:34 -0700272}
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-LunarGb5fae462020-03-05 12:43:25 -0700282 UtilPreCallRecordDestroyDevice(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;
Jeff Bolz95176d02020-04-01 00:36:16 -0500760 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700761 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-LunarGb5fae462020-03-05 12:43:25 -0700963 UtilPreCallRecordCreatePipelineLayout(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-LunarGb5fae462020-03-05 12:43:25 -07001059 UtilPreCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001071 UtilPreCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001083 UtilPreCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001095 UtilPreCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001107 UtilPostCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001116 UtilPostCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001125 UtilPostCallRecordPipelineCreations(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-LunarGb5fae462020-03-05 12:43:25 -07001134 UtilPostCallRecordPipelineCreations(count, pCreateInfos, pAllocator, pPipelines, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, this);
Karl Schultz7b024b42018-08-30 16:18:18 -06001135}
1136
1137// Remove all the shader trackers associated with this destroyed pipeline.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001138void GpuAssisted::PreCallRecordDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001139 for (auto it = shader_map.begin(); it != shader_map.end();) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001140 if (it->second.pipeline == pipeline) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001141 it = shader_map.erase(it);
Karl Schultz7b024b42018-08-30 16:18:18 -06001142 } else {
1143 ++it;
1144 }
1145 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001146 ValidationStateTracker::PreCallRecordDestroyPipeline(device, pipeline, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -06001147}
1148
1149// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001150bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<unsigned int> &new_pgm,
1151 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001152 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -06001153 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
1154
1155 // Load original shader SPIR-V
1156 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
1157 new_pgm.clear();
1158 new_pgm.reserve(num_words);
1159 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
1160
1161 // Call the optimizer to instrument the shader.
1162 // 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 -07001163 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Tony-LunarG2ec96bb2019-11-26 13:43:02 -07001164 const bool descriptor_indexing = IsExtEnabled(device_extensions.vk_ext_descriptor_indexing);
Karl Schultz7b024b42018-08-30 16:18:18 -06001165 using namespace spvtools;
1166 spv_target_env target_env = SPV_ENV_VULKAN_1_1;
1167 Optimizer optimizer(target_env);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001168 optimizer.RegisterPass(
Tony-LunarGab47cac2019-12-20 15:28:01 -07001169 CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing, descriptor_indexing));
Karl Schultz7b024b42018-08-30 16:18:18 -06001170 optimizer.RegisterPass(CreateAggressiveDCEPass());
Tony-LunarG7e0842f2019-12-10 09:26:34 -07001171 if ((device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) && shaderInt64)
Tony-LunarG99b880b2019-09-26 11:19:52 -06001172 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Karl Schultz7b024b42018-08-30 16:18:18 -06001173 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm);
1174 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001175 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -06001176 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001177 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -06001178 return pass;
1179}
Mark Lobodzinski01734072019-02-13 17:39:15 -07001180// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001181void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
1182 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
1183 void *csm_state_data) {
1184 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
1185 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -06001186 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001187 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
1188 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(unsigned int);
Karl Schultz7b024b42018-08-30 16:18:18 -06001189 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001190}
1191
Karl Schultz7b024b42018-08-30 16:18:18 -06001192// Generate the part of the message describing the violation.
1193static void GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg) {
1194 using namespace spvtools;
1195 std::ostringstream strm;
Tony-LunarGab47cac2019-12-20 15:28:01 -07001196 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001197 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001198 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
1199 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001200 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -06001201 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001202 case kInstErrorBindlessUninit: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001203 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized. ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -07001204 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -06001205 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001206 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001207 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001208 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
1209 vuid_msg = "UNASSIGNED-Device address out of bounds";
1210 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001211 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001212 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001213 vuid_msg = "UNASSIGNED-Internal Error";
1214 assert(false);
1215 } break;
1216 }
1217 msg = strm.str();
1218}
1219
Karl Schultz7b024b42018-08-30 16:18:18 -06001220// Pull together all the information from the debug record to build the error message strings,
1221// and then assemble them into a single message string.
1222// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1223// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1224// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1225// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1226//
Tony-LunarG1dce2392019-10-23 16:49:29 -06001227void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, VkPipelineBindPoint pipeline_bind_point,
1228 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001229 using namespace spvtools;
1230 const uint32_t total_words = debug_output_buffer[0];
1231 // A zero here means that the shader instrumentation didn't write anything.
1232 // If you have nothing to say, don't say it here.
1233 if (0 == total_words) {
1234 return;
1235 }
1236 // The first word in the debug output buffer is the number of words that would have
1237 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1238 // The number of words actually written by the shaders is determined by the size of the buffer
1239 // we provide via the descriptor. So, we process only the number of words that can fit in the
1240 // buffer.
1241 // Each "report" written by the shader instrumentation is considered a "record". This function
1242 // is hard-coded to process only one record because it expects the buffer to be large enough to
1243 // hold only one record. If there is a desire to process more than one record, this function needs
1244 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001245 std::string validation_message;
1246 std::string stage_message;
1247 std::string common_message;
1248 std::string filename_message;
1249 std::string source_message;
1250 std::string vuid_msg;
1251 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1252 VkPipeline pipeline_handle = VK_NULL_HANDLE;
1253 std::vector<unsigned int> pgm;
1254 // The first record starts at this offset after the total_words.
1255 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1256 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1257 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001258 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1259 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001260 shader_module_handle = it->second.shader_module;
1261 pipeline_handle = it->second.pipeline;
1262 pgm = it->second.pgm;
1263 }
1264 GenerateValidationMessage(debug_record, validation_message, vuid_msg);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001265 UtilGenerateStageMessage(debug_record, stage_message);
1266 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle, pipeline_bind_point,
1267 operation_index, common_message);
1268 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001269 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1270 filename_message.c_str(), source_message.c_str());
Karl Schultz7b024b42018-08-30 16:18:18 -06001271 // The debug record at word kInstCommonOutSize is the number of words in the record
1272 // written by the shader. Clear the entire record plus the total_words word at the start.
Tony-LunarGab47cac2019-12-20 15:28:01 -07001273 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], (uint32_t)kInstMaxOutCnt);
Karl Schultz7b024b42018-08-30 16:18:18 -06001274 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1275}
1276
Tony-LunarG81efe392019-03-07 15:43:27 -07001277// 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 -06001278void GpuAssisted::UpdateInstrumentationBuffer(CMD_BUFFER_STATE *cb_node) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001279 auto gpu_buffer_list = GetBufferInfo(cb_node->commandBuffer);
Tony-LunarG81efe392019-03-07 15:43:27 -07001280 uint32_t *pData;
1281 for (auto &buffer_info : gpu_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001282 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001283 VkResult result = vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, (void **)&pData);
Tony-LunarG81efe392019-03-07 15:43:27 -07001284 if (result == VK_SUCCESS) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001285 for (auto update : buffer_info.di_input_mem_block.update_at_submit) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001286 if (update.second->updated) pData[update.first] = 1;
1287 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001288 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001289 }
1290 }
1291 }
1292}
1293
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001294void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001295 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1296 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1297 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001298 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001299 UpdateInstrumentationBuffer(cb_node);
1300 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
1301 UpdateInstrumentationBuffer(secondaryCmdBuffer);
1302 }
1303 }
1304 }
1305}
1306
Karl Schultz58674242019-01-22 15:35:02 -07001307// Issue a memory barrier to make GPU-written data available to host.
1308// Wait for the queue to complete execution.
1309// Check the debug buffers for all the command buffers that were submitted.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001310void GpuAssisted::PostCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence,
1311 VkResult result) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001312 ValidationStateTracker::PostCallRecordQueueSubmit(queue, submitCount, pSubmits, fence, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001313
Tony-LunarG99b880b2019-09-26 11:19:52 -06001314 if (aborted) return;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001315 bool buffers_present = false;
1316 // Don't QueueWaitIdle if there's nothing to process
1317 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1318 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1319 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
1320 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarG1dce2392019-10-23 16:49:29 -06001321 if (GetBufferInfo(cb_node->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd) buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001322 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarG1dce2392019-10-23 16:49:29 -06001323 if (GetBufferInfo(secondaryCmdBuffer->commandBuffer).size() || cb_node->hasBuildAccelerationStructureCmd)
Jason Macnak83cfd582019-07-31 10:14:24 -07001324 buffers_present = true;
Tony-LunarG3cc795e2019-08-26 12:13:50 -06001325 }
1326 }
1327 }
1328 if (!buffers_present) return;
Karl Schultz58674242019-01-22 15:35:02 -07001329
Tony-LunarGb5fae462020-03-05 12:43:25 -07001330 UtilSubmitBarrier(queue, this);
Karl Schultz58674242019-01-22 15:35:02 -07001331
Tony-LunarG152a88b2019-03-20 15:42:24 -06001332 DispatchQueueWaitIdle(queue);
Karl Schultz58674242019-01-22 15:35:02 -07001333
Karl Schultz7b024b42018-08-30 16:18:18 -06001334 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1335 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1336 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001337 auto cb_node = GetCBState(submit->pCommandBuffers[i]);
Tony-LunarGb5fae462020-03-05 12:43:25 -07001338 UtilProcessInstrumentationBuffer(queue, cb_node, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001339 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001340 for (auto secondaryCmdBuffer : cb_node->linkedCommandBuffers) {
Tony-LunarGb5fae462020-03-05 12:43:25 -07001341 UtilProcessInstrumentationBuffer(queue, secondaryCmdBuffer, this);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001342 ProcessAccelerationStructureBuildValidationBuffer(queue, cb_node);
Karl Schultz7b024b42018-08-30 16:18:18 -06001343 }
1344 }
1345 }
1346}
Tony-LunarGb2501d22019-01-28 09:59:13 -07001347
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001348void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1349 uint32_t firstVertex, uint32_t firstInstance) {
1350 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1351}
1352
1353void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1354 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
1355 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1356}
1357
1358void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1359 uint32_t stride) {
1360 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1361}
1362
1363void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1364 uint32_t count, uint32_t stride) {
1365 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS);
1366}
1367
1368void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
1369 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1370}
1371
1372void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
1373 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE);
1374}
1375
1376void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1377 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1378 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1379 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1380 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1381 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1382 uint32_t width, uint32_t height, uint32_t depth) {
1383 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV);
1384}
1385
1386void GpuAssisted::PostCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1387 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1388 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1389 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1390 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1391 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1392 uint32_t width, uint32_t height, uint32_t depth) {
1393 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1394 cb_state->hasTraceRaysCmd = true;
1395}
1396
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001397void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1398 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1399 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1400 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1401 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1402 uint32_t height, uint32_t depth) {
1403 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1404}
1405
1406void GpuAssisted::PostCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
1407 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1408 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1409 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1410 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, uint32_t width,
1411 uint32_t height, uint32_t depth) {
1412 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1413 cb_state->hasTraceRaysCmd = true;
1414}
1415
1416void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1417 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1418 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1419 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1420 const VkStridedBufferRegionKHR *pCallableShaderBindingTable, VkBuffer buffer,
1421 VkDeviceSize offset) {
1422 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR);
1423}
1424
1425void GpuAssisted::PostCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
1426 const VkStridedBufferRegionKHR *pRaygenShaderBindingTable,
1427 const VkStridedBufferRegionKHR *pMissShaderBindingTable,
1428 const VkStridedBufferRegionKHR *pHitShaderBindingTable,
1429 const VkStridedBufferRegionKHR *pCallableShaderBindingTable,
1430 VkBuffer buffer, VkDeviceSize offset) {
1431 CMD_BUFFER_STATE *cb_state = GetCBState(commandBuffer);
1432 cb_state->hasTraceRaysCmd = true;
1433}
1434
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001435void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point) {
Jason Macnak67407e72019-07-11 11:05:09 -07001436 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
1437 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_NV) {
andreygca287f22019-04-10 00:15:33 +03001438 return;
1439 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001440 VkResult result;
1441
Tony-LunarG99b880b2019-09-26 11:19:52 -06001442 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001443
1444 std::vector<VkDescriptorSet> desc_sets;
1445 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001446 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001447 assert(result == VK_SUCCESS);
1448 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001449 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001450 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001451 return;
1452 }
1453
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001454 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001455 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001456
Mark Lobodzinskicefe42f2019-04-25 12:16:27 -06001457 auto cb_node = GetCBState(cmd_buffer);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001458 if (!cb_node) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001459 ReportSetupProblem(device, "Unrecognized command buffer");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001460 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001461 return;
1462 }
1463
Tony-LunarG81efe392019-03-07 15:43:27 -07001464 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001465 GpuAssistedDeviceMemoryBlock output_block = {};
Tony-LunarG0e564722019-03-19 16:09:14 -06001466 VkBufferCreateInfo bufferInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001467 bufferInfo.size = output_buffer_size;
Tony-LunarG0e564722019-03-19 16:09:14 -06001468 bufferInfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1469 VmaAllocationCreateInfo allocInfo = {};
1470 allocInfo.usage = VMA_MEMORY_USAGE_GPU_TO_CPU;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001471 result = vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001472 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001473 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001474 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001475 return;
1476 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001477
Tony-LunarG81efe392019-03-07 15:43:27 -07001478 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGa77cade2019-03-06 10:49:22 -07001479 uint32_t *pData;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001480 result = vmaMapMemory(vmaAllocator, output_block.allocation, (void **)&pData);
Tony-LunarG0e564722019-03-19 16:09:14 -06001481 if (result == VK_SUCCESS) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001482 memset(pData, 0, output_buffer_size);
1483 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001484 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001485
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001486 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001487 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1488 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1489 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001490 uint32_t desc_count = 1;
1491 auto const &state = cb_node->lastBound[bind_point];
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001492 uint32_t number_of_sets = (uint32_t)state.per_set.size();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001493
Tony-LunarG81efe392019-03-07 15:43:27 -07001494 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1495 // and how big each of the bindings is
Mark Lobodzinskif45e45f2019-04-19 14:15:39 -06001496 if (number_of_sets > 0 && device_extensions.vk_ext_descriptor_indexing) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001497 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1498 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001499 for (auto s : state.per_set) {
1500 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001501 if (desc && (desc->GetBindingCount() > 0)) {
1502 auto bindings = desc->GetLayout()->GetSortedBindingSet();
Tony-LunarGa77cade2019-03-06 10:49:22 -07001503 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
1504 for (auto binding : bindings) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001505 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1506 // blocks
1507 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1508 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001509 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1510 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1511 "validation");
Tony-LunarG7564b382019-08-21 10:11:35 -06001512 } else if (binding == desc->GetLayout()->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001513 descriptor_count += desc->GetVariableDescriptorCount();
1514 } else {
1515 descriptor_count += desc->GetDescriptorCountFromBinding(binding);
1516 }
1517 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001518 }
1519 }
1520
Tony-LunarGa77cade2019-03-06 10:49:22 -07001521 // Note that the size of the input buffer is dependent on the maximum binding number, which
1522 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1523 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1524 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1525 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1526 uint32_t words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001527 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1528 bufferInfo.size = words_needed * 4;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001529 result =
1530 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &di_input_block.buffer, &di_input_block.allocation, nullptr);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001531 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001532 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001533 aborted = true;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001534 return;
1535 }
1536
Tony-LunarGa77cade2019-03-06 10:49:22 -07001537 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1538 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1539 // outline of the input buffer format
Tony-LunarG99b880b2019-09-26 11:19:52 -06001540 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, (void **)&pData);
Tony-LunarG76cdcac2019-05-22 16:13:12 -06001541 memset(pData, 0, static_cast<size_t>(bufferInfo.size));
Tony-LunarGa77cade2019-03-06 10:49:22 -07001542 // Pointer to a sets array that points into the sizes array
1543 uint32_t *sets_to_sizes = pData + 1;
1544 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1545 uint32_t *sizes = sets_to_sizes + number_of_sets;
1546 // Pointer to another sets array that points into the bindings array that points into the written array
1547 uint32_t *sets_to_bindings = sizes + binding_count;
1548 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1549 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1550 // Index of the next entry in the written array to be updated
1551 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001552 uint32_t bindCounter = number_of_sets + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001553 // Index of the start of the sets_to_bindings array
1554 pData[0] = number_of_sets + binding_count + 1;
1555
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001556 for (auto s : state.per_set) {
1557 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001558 if (desc && (desc->GetBindingCount() > 0)) {
1559 auto layout = desc->GetLayout();
1560 auto bindings = layout->GetSortedBindingSet();
Tony-LunarG81efe392019-03-07 15:43:27 -07001561 // For each set, fill in index of its bindings sizes in the sizes array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001562 *sets_to_sizes++ = bindCounter;
Tony-LunarG81efe392019-03-07 15:43:27 -07001563 // For each set, fill in the index of its bindings in the bindings_to_written array
Tony-LunarGa77cade2019-03-06 10:49:22 -07001564 *sets_to_bindings++ = bindCounter + number_of_sets + binding_count;
Tony-LunarG81efe392019-03-07 15:43:27 -07001565 for (auto binding : bindings) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001566 // For each binding, fill in its size in the sizes array
Tony-LunarG7564b382019-08-21 10:11:35 -06001567 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1568 // blocks
1569 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1570 sizes[binding] = 1;
1571 } else if (binding == layout->GetMaxBinding() && desc->IsVariableDescriptorCount(binding)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001572 sizes[binding] = desc->GetVariableDescriptorCount();
1573 } else {
1574 sizes[binding] = desc->GetDescriptorCountFromBinding(binding);
1575 }
1576 // Fill in the starting index for this binding in the written array in the bindings_to_written array
1577 bindings_to_written[binding] = written_index;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001578
Tony-LunarG7564b382019-08-21 10:11:35 -06001579 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1580 // blocks
1581 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == desc->GetLayout()->GetTypeFromBinding(binding)) {
1582 pData[written_index++] = 1;
1583 continue;
1584 }
1585
Tony-LunarGa77cade2019-03-06 10:49:22 -07001586 auto index_range = desc->GetGlobalIndexRangeFromBinding(binding, true);
1587 // For each array element in the binding, update the written array with whether it has been written
1588 for (uint32_t i = index_range.start; i < index_range.end; ++i) {
1589 auto *descriptor = desc->GetDescriptorFromGlobalIndex(i);
Tony-LunarG81efe392019-03-07 15:43:27 -07001590 if (descriptor->updated) {
1591 pData[written_index] = 1;
1592 } else if (desc->IsUpdateAfterBind(binding)) {
1593 // 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 -06001594 di_input_block.update_at_submit[written_index] = descriptor;
Tony-LunarG81efe392019-03-07 15:43:27 -07001595 }
Tony-LunarGa77cade2019-03-06 10:49:22 -07001596 written_index++;
1597 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001598 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001599 auto last = desc->GetLayout()->GetMaxBinding();
1600 bindings_to_written += last + 1;
1601 bindCounter += last + 1;
1602 sizes += last + 1;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001603 } else {
1604 *sets_to_sizes++ = 0;
1605 *sets_to_bindings++ = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001606 }
1607 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001608 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001609
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001610 di_input_desc_buffer_info.range = (words_needed * 4);
1611 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1612 di_input_desc_buffer_info.offset = 0;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001613
1614 desc_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1615 desc_writes[1].dstBinding = 1;
1616 desc_writes[1].descriptorCount = 1;
1617 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001618 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001619 desc_writes[1].dstSet = desc_sets[0];
1620
1621 desc_count = 2;
Tony-LunarG0e564722019-03-19 16:09:14 -06001622 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001623
Tony-LunarG7e0842f2019-12-10 09:26:34 -07001624 if (number_of_sets > 0 && (device_extensions.vk_ext_buffer_device_address || device_extensions.vk_khr_buffer_device_address) &&
1625 buffer_map.size() && shaderInt64) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001626 // Example BDA input buffer assuming 2 buffers using BDA:
1627 // Word 0 | Index of start of buffer sizes (in this case 5)
1628 // Word 1 | 0x0000000000000000
1629 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1630 // Word 3 | Device Address of second buffer
1631 // Word 4 | 0xffffffffffffffff
1632 // Word 5 | 0 (size of pretend buffer at word 1)
1633 // Word 6 | Size in bytes of first buffer
1634 // Word 7 | Size in bytes of second buffer
1635 // Word 8 | 0 (size of pretend buffer in word 4)
1636
Tony-LunarG99b880b2019-09-26 11:19:52 -06001637 uint32_t num_buffers = static_cast<uint32_t>(buffer_map.size());
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001638 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
1639 allocInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
1640 bufferInfo.size = words_needed * 8; // 64 bit words
Tony-LunarG99b880b2019-09-26 11:19:52 -06001641 result =
1642 vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocInfo, &bda_input_block.buffer, &bda_input_block.allocation, nullptr);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001643 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001644 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001645 aborted = true;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001646 return;
1647 }
1648 uint64_t *bda_data;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001649 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, (void **)&bda_data);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001650 uint32_t address_index = 1;
1651 uint32_t size_index = 3 + num_buffers;
1652 memset(bda_data, 0, static_cast<size_t>(bufferInfo.size));
1653 bda_data[0] = size_index; // Start of buffer sizes
1654 bda_data[address_index++] = 0; // NULL address
1655 bda_data[size_index++] = 0;
1656
Tony-LunarG99b880b2019-09-26 11:19:52 -06001657 for (auto const &value : buffer_map) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001658 bda_data[address_index++] = value.first;
1659 bda_data[size_index++] = value.second;
1660 }
1661 bda_data[address_index] = UINTPTR_MAX;
1662 bda_data[size_index] = 0;
Tony-LunarG99b880b2019-09-26 11:19:52 -06001663 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001664
1665 bda_input_desc_buffer_info.range = (words_needed * 8);
1666 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
1667 bda_input_desc_buffer_info.offset = 0;
1668
1669 desc_writes[desc_count].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1670 desc_writes[desc_count].dstBinding = 2;
1671 desc_writes[desc_count].descriptorCount = 1;
1672 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1673 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
1674 desc_writes[desc_count].dstSet = desc_sets[0];
1675 desc_count++;
1676 }
1677
Tony-LunarGb2501d22019-01-28 09:59:13 -07001678 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001679 output_desc_buffer_info.buffer = output_block.buffer;
1680 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001681
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001682 desc_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1683 desc_writes[0].descriptorCount = 1;
1684 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1685 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
1686 desc_writes[0].dstSet = desc_sets[0];
1687 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001688
andreyg25ce2622019-04-05 23:07:59 +03001689 auto iter = cb_node->lastBound.find(bind_point); // find() allows read-only access to cb_state
Tony-LunarGb2501d22019-01-28 09:59:13 -07001690 if (iter != cb_node->lastBound.end()) {
1691 auto pipeline_state = iter->second.pipeline_state;
Jeff Bolze7fc67b2019-10-04 12:29:31 -05001692 if (pipeline_state && (pipeline_state->pipeline_layout->set_layouts.size() <= desc_set_bind_index)) {
1693 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_state->pipeline_layout->layout, desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06001694 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001695 }
Tony-LunarG0e564722019-03-19 16:09:14 -06001696 // Record buffer and memory info in CB state tracking
Tony-LunarG1dce2392019-10-23 16:49:29 -06001697 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 -07001698 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001699 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001700 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
1701 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
1702 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
1703 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001704 return;
1705 }
1706}