blob: ea8c166bb6b160d5690aa4ff3b0a4ff6e2e4eb6a [file] [log] [blame]
Jeremy Gebben4d51c552022-01-06 21:27:15 -07001/* Copyright (c) 2018-2022 The Khronos Group Inc.
2 * Copyright (c) 2018-2022 Valve Corporation
3 * Copyright (c) 2018-2022 LunarG, Inc.
Karl Schultz7b024b42018-08-30 16:18:18 -06004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060017 * Author: Karl Schultz <karl@lunarg.com>
18 * Author: Tony Barbour <tony@lunarg.com>
Karl Schultz7b024b42018-08-30 16:18:18 -060019 */
20
Tony-LunarGc28e28a2020-08-14 10:37:48 -060021#include <climits>
Tony-LunarGa3ec16c2021-04-06 12:19:57 -060022#include <cmath>
Mark Lobodzinskib56bbb92019-02-18 11:49:59 -070023#include "gpu_validation.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060024#include "spirv-tools/optimizer.hpp"
25#include "spirv-tools/instrument.hpp"
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060026#include "layer_chassis_dispatch.h"
Tony-LunarG7de10e82020-11-24 11:31:55 -070027#include "gpu_vuids.h"
Jeremy Gebben159b3cc2021-06-03 09:09:03 -060028#include "buffer_state.h"
29#include "cmd_buffer_state.h"
30#include "render_pass_state.h"
sjfrickebecf0722022-08-05 16:15:46 +090031// Generated shaders
32#include "gpu_shaders/gpu_shaders_constants.h"
33#include "gpu_pre_draw_vert.h"
34#include "gpu_as_inspection_comp.h"
Karl Schultz7b024b42018-08-30 16:18:18 -060035
Jason Macnak83cfd582019-07-31 10:14:24 -070036// Keep in sync with the GLSL shader below.
37struct GpuAccelerationStructureBuildValidationBuffer {
38 uint32_t instances_to_validate;
39 uint32_t replacement_handle_bits_0;
40 uint32_t replacement_handle_bits_1;
41 uint32_t invalid_handle_found;
42 uint32_t invalid_handle_bits_0;
43 uint32_t invalid_handle_bits_1;
44 uint32_t valid_handles_count;
45};
46
Tony-LunarG5c38b182020-06-10 16:15:32 -060047bool GpuAssisted::CheckForDescriptorIndexing(DeviceFeatures enabled_features) const {
48 bool result =
49 (IsExtEnabled(device_extensions.vk_ext_descriptor_indexing) &&
50 (enabled_features.core12.descriptorIndexing || enabled_features.core12.shaderInputAttachmentArrayDynamicIndexing ||
51 enabled_features.core12.shaderUniformTexelBufferArrayDynamicIndexing ||
52 enabled_features.core12.shaderStorageTexelBufferArrayDynamicIndexing ||
53 enabled_features.core12.shaderUniformBufferArrayNonUniformIndexing ||
54 enabled_features.core12.shaderSampledImageArrayNonUniformIndexing ||
55 enabled_features.core12.shaderStorageBufferArrayNonUniformIndexing ||
56 enabled_features.core12.shaderStorageImageArrayNonUniformIndexing ||
57 enabled_features.core12.shaderInputAttachmentArrayNonUniformIndexing ||
58 enabled_features.core12.shaderUniformTexelBufferArrayNonUniformIndexing ||
59 enabled_features.core12.shaderStorageTexelBufferArrayNonUniformIndexing ||
60 enabled_features.core12.descriptorBindingUniformBufferUpdateAfterBind ||
61 enabled_features.core12.descriptorBindingSampledImageUpdateAfterBind ||
62 enabled_features.core12.descriptorBindingStorageImageUpdateAfterBind ||
63 enabled_features.core12.descriptorBindingStorageBufferUpdateAfterBind ||
64 enabled_features.core12.descriptorBindingUniformTexelBufferUpdateAfterBind ||
65 enabled_features.core12.descriptorBindingStorageTexelBufferUpdateAfterBind ||
66 enabled_features.core12.descriptorBindingUpdateUnusedWhilePending ||
67 enabled_features.core12.descriptorBindingPartiallyBound ||
68 enabled_features.core12.descriptorBindingVariableDescriptorCount || enabled_features.core12.runtimeDescriptorArray));
69 return result;
70}
71
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060072void GpuAssisted::PreCallRecordCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
73 const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer, void *cb_state_data) {
Jason Macnak83cfd582019-07-31 10:14:24 -070074 // Ray tracing acceleration structure instance buffers also need the storage buffer usage as
75 // acceleration structure build validation will find and replace invalid acceleration structure
76 // handles inside of a compute shader.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -060077 create_buffer_api_state *cb_state = reinterpret_cast<create_buffer_api_state *>(cb_state_data);
78 if (cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_RAY_TRACING_BIT_NV) {
79 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
Jason Macnak83cfd582019-07-31 10:14:24 -070080 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -060081
82 // Validating DrawIndirectCount countBuffer will require validation shader to bind the count buffer as a storage buffer
Tony-LunarG3723a3a2021-05-04 14:52:39 -060083 if (validate_draw_indirect && cb_state && cb_state->modified_create_info.usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -060084 cb_state->modified_create_info.usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
85 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -060086 ValidationStateTracker::PreCallRecordCreateBuffer(device, pCreateInfo, pAllocator, pBuffer, cb_state_data);
Jason Macnak83cfd582019-07-31 10:14:24 -070087}
Karl Schultz7b024b42018-08-30 16:18:18 -060088// Perform initializations that can be done at Create Device time.
Jeremy Gebben36a3b832022-03-23 10:54:18 -060089void GpuAssisted::CreateDevice(const VkDeviceCreateInfo *pCreateInfo) {
Jeremy Gebben33717862022-03-28 15:53:56 -060090 // GpuAssistedBase::CreateDevice will set up bindings
91 VkDescriptorSetLayoutBinding binding = {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1,
92 VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT |
93 VK_SHADER_STAGE_MESH_BIT_NV | VK_SHADER_STAGE_TASK_BIT_NV |
94 kShaderStageAllRayTracing,
95 NULL};
96 bindings_.push_back(binding);
97 for (auto i = 1; i < 3; i++) {
98 binding.binding = i;
99 bindings_.push_back(binding);
100 }
101 GpuAssistedBase::CreateDevice(pCreateInfo);
Mark Lobodzinski5dc3dcd2019-04-23 14:26:28 -0600102
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600103 if (enabled_features.core.robustBufferAccess || enabled_features.robustness2_features.robustBufferAccess2) {
104 buffer_oob_enabled = false;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700105 } else {
Tony-LunarGbcfeccf2022-04-19 09:14:35 -0600106 buffer_oob_enabled = GpuGetOption("khronos_validation.gpuav_buffer_oob", true);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700107 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600108
Tony-LunarGbcfeccf2022-04-19 09:14:35 -0600109 bool validate_descriptor_indexing = GpuGetOption("khronos_validation.gpuav_descriptor_indexing", true);
110 validate_draw_indirect = GpuGetOption("khronos_validation.validate_draw_indirect", true);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600111
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600112 if (phys_dev_props.apiVersion < VK_API_VERSION_1_1) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700113 ReportSetupProblem(device, "GPU-Assisted validation requires Vulkan 1.1 or later. GPU-Assisted Validation disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600114 aborted = true;
Karl Schultz7b024b42018-08-30 16:18:18 -0600115 return;
116 }
Tony-LunarG2ab9ede2019-05-10 14:34:31 -0600117
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600118 DispatchGetPhysicalDeviceFeatures(physical_device, &supported_features);
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600119 if (!supported_features.fragmentStoresAndAtomics || !supported_features.vertexPipelineStoresAndAtomics) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700120 ReportSetupProblem(device,
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600121 "GPU-Assisted validation requires fragmentStoresAndAtomics and vertexPipelineStoresAndAtomics. "
122 "GPU-Assisted Validation disabled.");
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600123 aborted = true;
Tony-LunarG7c668ab2019-08-28 16:13:01 -0600124 return;
125 }
126
sfricke-samsung45996a42021-09-16 13:45:27 -0700127 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
128 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Tony-LunarG04dc83c2020-07-07 13:53:02 -0600129 !supported_features.shaderInt64) {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700130 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
131 "shaderInt64 feature is not available. No buffer device address checking will be attempted");
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600132 }
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600133 shaderInt64 = supported_features.shaderInt64;
134 output_buffer_size = sizeof(uint32_t) * (spvtools::kInstMaxOutCnt + 1);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600135 if (validate_descriptor_indexing) {
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600136 descriptor_indexing = CheckForDescriptorIndexing(enabled_features);
Tony-LunarGaef435b2021-10-14 14:49:06 -0600137 }
Tony-LunarG3b1c19f2022-05-02 14:11:06 -0600138 bool use_linear_output_pool = GpuGetOption("khronos_validation.vma_linear_output", true);
Tony-LunarG20d18a72022-04-19 11:01:47 -0600139 if (use_linear_output_pool) {
140 auto output_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
141 output_buffer_create_info.size = output_buffer_size;
142 output_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
143 VmaAllocationCreateInfo alloc_create_info = {};
144 alloc_create_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
145 uint32_t mem_type_index;
146 vmaFindMemoryTypeIndexForBufferInfo(vmaAllocator, &output_buffer_create_info, &alloc_create_info, &mem_type_index);
147 VmaPoolCreateInfo pool_create_info = {};
148 pool_create_info.memoryTypeIndex = mem_type_index;
149 pool_create_info.blockSize = 0;
150 pool_create_info.maxBlockCount = 0;
151 pool_create_info.flags = VMA_POOL_CREATE_LINEAR_ALGORITHM_BIT;
152 VkResult result = vmaCreatePool(vmaAllocator, &pool_create_info, &output_buffer_pool);
153 if (result != VK_SUCCESS) {
154 ReportSetupProblem(device, "Unable to create VMA memory pool");
155 }
156 }
157
Jeremy Gebben36a3b832022-03-23 10:54:18 -0600158 CreateAccelerationStructureBuildValidationState();
Karl Schultz7b024b42018-08-30 16:18:18 -0600159}
160
sjfricke43b340c2022-08-04 22:18:38 +0900161void GpuAssistedPreDrawValidationState::Destroy(VkDevice device) {
162 if (globals_created) {
163 DispatchDestroyShaderModule(device, shader_module, nullptr);
164 DispatchDestroyDescriptorSetLayout(device, ds_layout, nullptr);
165 DispatchDestroyPipelineLayout(device, pipeline_layout, nullptr);
166 auto to_destroy = renderpass_to_pipeline.snapshot();
167 for (auto &entry: to_destroy) {
168 DispatchDestroyPipeline(device, entry.second, nullptr);
169 renderpass_to_pipeline.erase(entry.first);
170 }
171 globals_created = false;
172 }
173}
174
Karl Schultz7b024b42018-08-30 16:18:18 -0600175// Clean up device-related resources
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600176void GpuAssisted::PreCallRecordDestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600177 DestroyAccelerationStructureBuildValidationState();
sjfricke43b340c2022-08-04 22:18:38 +0900178 pre_draw_validation_state.Destroy(device);
Tony-LunarG20d18a72022-04-19 11:01:47 -0600179 if (output_buffer_pool) {
180 vmaDestroyPool(vmaAllocator, output_buffer_pool);
181 }
Jeremy Gebben33717862022-03-28 15:53:56 -0600182 GpuAssistedBase::PreCallRecordDestroyDevice(device, pAllocator);
Karl Schultz7b024b42018-08-30 16:18:18 -0600183}
Tony-LunarG1dce2392019-10-23 16:49:29 -0600184
Jeremy Gebben21782012022-03-15 16:23:27 -0600185void GpuAssisted::CreateAccelerationStructureBuildValidationState() {
186 if (aborted) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700187 return;
188 }
189
Jeremy Gebben21782012022-03-15 16:23:27 -0600190 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700191 if (as_validation_state.initialized) {
192 return;
193 }
194
sfricke-samsung45996a42021-09-16 13:45:27 -0700195 if (!IsExtEnabled(device_extensions.vk_nv_ray_tracing)) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700196 return;
197 }
198
199 // Outline:
200 // - Create valid bottom level acceleration structure which acts as replacement
201 // - Create and load vertex buffer
202 // - Create and load index buffer
203 // - Create, allocate memory for, and bind memory for acceleration structure
204 // - Query acceleration structure handle
205 // - Create command pool and command buffer
206 // - Record build acceleration structure command
207 // - Submit command buffer and wait for completion
208 // - Cleanup
209 // - Create compute pipeline for validating instance buffers
210 // - Create descriptor set layout
211 // - Create pipeline layout
212 // - Create pipeline
213 // - Cleanup
214
215 VkResult result = VK_SUCCESS;
216
217 VkBuffer vbo = VK_NULL_HANDLE;
218 VmaAllocation vbo_allocation = VK_NULL_HANDLE;
219 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600220 auto vbo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700221 vbo_ci.size = sizeof(float) * 9;
222 vbo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
223
224 VmaAllocationCreateInfo vbo_ai = {};
225 vbo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
226 vbo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
227
Jeremy Gebben21782012022-03-15 16:23:27 -0600228 result = vmaCreateBuffer(vmaAllocator, &vbo_ci, &vbo_ai, &vbo, &vbo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700229 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700230 ReportSetupProblem(device, "Failed to create vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700231 }
232 }
233
234 if (result == VK_SUCCESS) {
235 uint8_t *mapped_vbo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600236 result = vmaMapMemory(vmaAllocator, vbo_allocation, reinterpret_cast<void **>(&mapped_vbo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700237 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700238 ReportSetupProblem(device, "Failed to map vertex buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700239 } else {
240 const std::vector<float> vertices = {1.0f, 0.0f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f};
241 std::memcpy(mapped_vbo_buffer, (uint8_t *)vertices.data(), sizeof(float) * vertices.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600242 vmaUnmapMemory(vmaAllocator, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700243 }
244 }
245
246 VkBuffer ibo = VK_NULL_HANDLE;
247 VmaAllocation ibo_allocation = VK_NULL_HANDLE;
248 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600249 auto ibo_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700250 ibo_ci.size = sizeof(uint32_t) * 3;
251 ibo_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
252
253 VmaAllocationCreateInfo ibo_ai = {};
254 ibo_ai.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
255 ibo_ai.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
256
Jeremy Gebben21782012022-03-15 16:23:27 -0600257 result = vmaCreateBuffer(vmaAllocator, &ibo_ci, &ibo_ai, &ibo, &ibo_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700258 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700259 ReportSetupProblem(device, "Failed to create index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700260 }
261 }
262
263 if (result == VK_SUCCESS) {
264 uint8_t *mapped_ibo_buffer = nullptr;
Jeremy Gebben21782012022-03-15 16:23:27 -0600265 result = vmaMapMemory(vmaAllocator, ibo_allocation, reinterpret_cast<void **>(&mapped_ibo_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700266 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700267 ReportSetupProblem(device, "Failed to map index buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700268 } else {
269 const std::vector<uint32_t> indicies = {0, 1, 2};
270 std::memcpy(mapped_ibo_buffer, (uint8_t *)indicies.data(), sizeof(uint32_t) * indicies.size());
Jeremy Gebben21782012022-03-15 16:23:27 -0600271 vmaUnmapMemory(vmaAllocator, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700272 }
273 }
274
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600275 auto geometry = LvlInitStruct<VkGeometryNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700276 geometry.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_NV;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600277 geometry.geometry.triangles = LvlInitStruct<VkGeometryTrianglesNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700278 geometry.geometry.triangles.vertexData = vbo;
279 geometry.geometry.triangles.vertexOffset = 0;
280 geometry.geometry.triangles.vertexCount = 3;
281 geometry.geometry.triangles.vertexStride = 12;
282 geometry.geometry.triangles.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT;
283 geometry.geometry.triangles.indexData = ibo;
284 geometry.geometry.triangles.indexOffset = 0;
285 geometry.geometry.triangles.indexCount = 3;
286 geometry.geometry.triangles.indexType = VK_INDEX_TYPE_UINT32;
287 geometry.geometry.triangles.transformData = VK_NULL_HANDLE;
288 geometry.geometry.triangles.transformOffset = 0;
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600289 geometry.geometry.aabbs = LvlInitStruct<VkGeometryAABBNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700290
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600291 auto as_ci = LvlInitStruct<VkAccelerationStructureCreateInfoNV>();
292 as_ci.info = LvlInitStruct<VkAccelerationStructureInfoNV>();
Tony-LunarG80fecea2022-06-28 10:05:21 -0600293 as_ci.info.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700294 as_ci.info.instanceCount = 0;
295 as_ci.info.geometryCount = 1;
296 as_ci.info.pGeometries = &geometry;
297 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600298 result = DispatchCreateAccelerationStructureNV(device, &as_ci, nullptr, &as_validation_state.replacement_as);
Jason Macnak83cfd582019-07-31 10:14:24 -0700299 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600300 ReportSetupProblem(device, "Failed to create acceleration structure for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700301 }
302 }
303
304 VkMemoryRequirements2 as_mem_requirements = {};
305 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600306 auto as_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700307 as_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV;
308 as_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
309
Jeremy Gebben21782012022-03-15 16:23:27 -0600310 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &as_mem_requirements_info, &as_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700311 }
312
313 VmaAllocationInfo as_memory_ai = {};
314 if (result == VK_SUCCESS) {
315 VmaAllocationCreateInfo as_memory_aci = {};
316 as_memory_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
317
Jeremy Gebben21782012022-03-15 16:23:27 -0600318 result = vmaAllocateMemory(vmaAllocator, &as_mem_requirements.memoryRequirements, &as_memory_aci,
Tony-LunarG99b880b2019-09-26 11:19:52 -0600319 &as_validation_state.replacement_as_allocation, &as_memory_ai);
Jason Macnak83cfd582019-07-31 10:14:24 -0700320 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600321 ReportSetupProblem(device,
Jason Macnak83cfd582019-07-31 10:14:24 -0700322 "Failed to alloc acceleration structure memory for acceleration structure build validation.");
323 }
324 }
325
326 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600327 auto as_bind_info = LvlInitStruct<VkBindAccelerationStructureMemoryInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700328 as_bind_info.accelerationStructure = as_validation_state.replacement_as;
329 as_bind_info.memory = as_memory_ai.deviceMemory;
330 as_bind_info.memoryOffset = as_memory_ai.offset;
331
Jeremy Gebben21782012022-03-15 16:23:27 -0600332 result = DispatchBindAccelerationStructureMemoryNV(device, 1, &as_bind_info);
Jason Macnak83cfd582019-07-31 10:14:24 -0700333 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600334 ReportSetupProblem(device, "Failed to bind acceleration structure memory for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700335 }
336 }
337
338 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600339 result = DispatchGetAccelerationStructureHandleNV(device, as_validation_state.replacement_as, sizeof(uint64_t),
340 &as_validation_state.replacement_as_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700341 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600342 ReportSetupProblem(device, "Failed to get acceleration structure handle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700343 }
344 }
345
346 VkMemoryRequirements2 scratch_mem_requirements = {};
347 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600348 auto scratch_mem_requirements_info = LvlInitStruct<VkAccelerationStructureMemoryRequirementsInfoNV>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700349 scratch_mem_requirements_info.type = VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV;
350 scratch_mem_requirements_info.accelerationStructure = as_validation_state.replacement_as;
351
Jeremy Gebben21782012022-03-15 16:23:27 -0600352 DispatchGetAccelerationStructureMemoryRequirementsNV(device, &scratch_mem_requirements_info, &scratch_mem_requirements);
Jason Macnak83cfd582019-07-31 10:14:24 -0700353 }
354
355 VkBuffer scratch = VK_NULL_HANDLE;
Tony-LunarG18900282020-05-20 12:34:33 -0600356 VmaAllocation scratch_allocation = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700357 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600358 auto scratch_ci = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700359 scratch_ci.size = scratch_mem_requirements.memoryRequirements.size;
360 scratch_ci.usage = VK_BUFFER_USAGE_RAY_TRACING_BIT_NV;
Jason Macnak83cfd582019-07-31 10:14:24 -0700361 VmaAllocationCreateInfo scratch_aci = {};
362 scratch_aci.usage = VMA_MEMORY_USAGE_GPU_ONLY;
363
Jeremy Gebben21782012022-03-15 16:23:27 -0600364 result = vmaCreateBuffer(vmaAllocator, &scratch_ci, &scratch_aci, &scratch, &scratch_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700365 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600366 ReportSetupProblem(device, "Failed to create scratch buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700367 }
368 }
369
370 VkCommandPool command_pool = VK_NULL_HANDLE;
371 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600372 auto command_pool_ci = LvlInitStruct<VkCommandPoolCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700373 command_pool_ci.queueFamilyIndex = 0;
374
Jeremy Gebben21782012022-03-15 16:23:27 -0600375 result = DispatchCreateCommandPool(device, &command_pool_ci, nullptr, &command_pool);
Jason Macnak83cfd582019-07-31 10:14:24 -0700376 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600377 ReportSetupProblem(device, "Failed to create command pool for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700378 }
379 }
380
381 VkCommandBuffer command_buffer = VK_NULL_HANDLE;
382
383 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600384 auto command_buffer_ai = LvlInitStruct<VkCommandBufferAllocateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700385 command_buffer_ai.commandPool = command_pool;
386 command_buffer_ai.commandBufferCount = 1;
387 command_buffer_ai.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
388
Jeremy Gebben21782012022-03-15 16:23:27 -0600389 result = DispatchAllocateCommandBuffers(device, &command_buffer_ai, &command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700390 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600391 ReportSetupProblem(device, "Failed to create command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700392 }
393
394 // Hook up command buffer dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600395 vkSetDeviceLoaderData(device, command_buffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700396 }
397
398 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600399 auto command_buffer_bi = LvlInitStruct<VkCommandBufferBeginInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700400
401 result = DispatchBeginCommandBuffer(command_buffer, &command_buffer_bi);
402 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600403 ReportSetupProblem(device, "Failed to begin command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700404 }
405 }
406
407 if (result == VK_SUCCESS) {
408 DispatchCmdBuildAccelerationStructureNV(command_buffer, &as_ci.info, VK_NULL_HANDLE, 0, VK_FALSE,
409 as_validation_state.replacement_as, VK_NULL_HANDLE, scratch, 0);
410 DispatchEndCommandBuffer(command_buffer);
411 }
412
413 VkQueue queue = VK_NULL_HANDLE;
414 if (result == VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600415 DispatchGetDeviceQueue(device, 0, 0, &queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700416
417 // Hook up queue dispatch
Jeremy Gebben21782012022-03-15 16:23:27 -0600418 vkSetDeviceLoaderData(device, queue);
Jason Macnak83cfd582019-07-31 10:14:24 -0700419
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600420 auto submit_info = LvlInitStruct<VkSubmitInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700421 submit_info.commandBufferCount = 1;
422 submit_info.pCommandBuffers = &command_buffer;
423 result = DispatchQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
424 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600425 ReportSetupProblem(device, "Failed to submit command buffer for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700426 }
427 }
428
429 if (result == VK_SUCCESS) {
430 result = DispatchQueueWaitIdle(queue);
431 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600432 ReportSetupProblem(device, "Failed to wait for queue idle for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700433 }
434 }
435
436 if (vbo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600437 vmaDestroyBuffer(vmaAllocator, vbo, vbo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700438 }
439 if (ibo != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600440 vmaDestroyBuffer(vmaAllocator, ibo, ibo_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700441 }
442 if (scratch != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600443 vmaDestroyBuffer(vmaAllocator, scratch, scratch_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700444 }
445 if (command_pool != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600446 DispatchDestroyCommandPool(device, command_pool, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700447 }
448
Jeremy Gebben21782012022-03-15 16:23:27 -0600449 if (debug_desc_layout == VK_NULL_HANDLE) {
450 ReportSetupProblem(device, "Failed to find descriptor set layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700451 result = VK_INCOMPLETE;
452 }
453
454 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600455 auto pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700456 pipeline_layout_ci.setLayoutCount = 1;
Jeremy Gebben21782012022-03-15 16:23:27 -0600457 pipeline_layout_ci.pSetLayouts = &debug_desc_layout;
458 result = DispatchCreatePipelineLayout(device, &pipeline_layout_ci, 0, &as_validation_state.pipeline_layout);
Jason Macnak83cfd582019-07-31 10:14:24 -0700459 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600460 ReportSetupProblem(device, "Failed to create pipeline layout for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700461 }
462 }
463
464 VkShaderModule shader_module = VK_NULL_HANDLE;
465 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600466 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
sjfrickebecf0722022-08-05 16:15:46 +0900467 shader_module_ci.codeSize = sizeof(gpu_as_inspection_comp);
468 shader_module_ci.pCode = gpu_as_inspection_comp;
Jason Macnak83cfd582019-07-31 10:14:24 -0700469
Jeremy Gebben21782012022-03-15 16:23:27 -0600470 result = DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &shader_module);
Jason Macnak83cfd582019-07-31 10:14:24 -0700471 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600472 ReportSetupProblem(device, "Failed to create compute shader module for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700473 }
474 }
475
476 if (result == VK_SUCCESS) {
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600477 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700478 pipeline_stage_ci.stage = VK_SHADER_STAGE_COMPUTE_BIT;
479 pipeline_stage_ci.module = shader_module;
480 pipeline_stage_ci.pName = "main";
481
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600482 auto pipeline_ci = LvlInitStruct<VkComputePipelineCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700483 pipeline_ci.stage = pipeline_stage_ci;
484 pipeline_ci.layout = as_validation_state.pipeline_layout;
485
Jeremy Gebben21782012022-03-15 16:23:27 -0600486 result = DispatchCreateComputePipelines(device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr, &as_validation_state.pipeline);
Jason Macnak83cfd582019-07-31 10:14:24 -0700487 if (result != VK_SUCCESS) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600488 ReportSetupProblem(device, "Failed to create compute pipeline for acceleration structure build validation.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700489 }
490 }
491
492 if (shader_module != VK_NULL_HANDLE) {
Jeremy Gebben21782012022-03-15 16:23:27 -0600493 DispatchDestroyShaderModule(device, shader_module, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700494 }
495
496 if (result == VK_SUCCESS) {
497 as_validation_state.initialized = true;
Jeremy Gebben21782012022-03-15 16:23:27 -0600498 LogInfo(device, "UNASSIGNED-GPU-Assisted Validation.", "Acceleration Structure Building GPU Validation Enabled.");
Jason Macnak83cfd582019-07-31 10:14:24 -0700499 } else {
Jeremy Gebben21782012022-03-15 16:23:27 -0600500 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700501 }
502}
503
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600504void GpuAssisted::DestroyAccelerationStructureBuildValidationState() {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600505 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700506 if (as_validation_state.pipeline != VK_NULL_HANDLE) {
507 DispatchDestroyPipeline(device, as_validation_state.pipeline, nullptr);
508 }
509 if (as_validation_state.pipeline_layout != VK_NULL_HANDLE) {
510 DispatchDestroyPipelineLayout(device, as_validation_state.pipeline_layout, nullptr);
511 }
512 if (as_validation_state.replacement_as != VK_NULL_HANDLE) {
513 DispatchDestroyAccelerationStructureNV(device, as_validation_state.replacement_as, nullptr);
514 }
515 if (as_validation_state.replacement_as_allocation != VK_NULL_HANDLE) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600516 vmaFreeMemory(vmaAllocator, as_validation_state.replacement_as_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700517 }
518}
519
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600520struct GPUAV_RESTORABLE_PIPELINE_STATE {
Jason Macnak83cfd582019-07-31 10:14:24 -0700521 VkPipelineBindPoint pipeline_bind_point = VK_PIPELINE_BIND_POINT_MAX_ENUM;
522 VkPipeline pipeline = VK_NULL_HANDLE;
523 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
524 std::vector<VkDescriptorSet> descriptor_sets;
525 std::vector<std::vector<uint32_t>> dynamic_offsets;
526 uint32_t push_descriptor_set_index = 0;
527 std::vector<safe_VkWriteDescriptorSet> push_descriptor_set_writes;
528 std::vector<uint8_t> push_constants_data;
529 PushConstantRangesId push_constants_ranges;
530
531 void Create(CMD_BUFFER_STATE *cb_state, VkPipelineBindPoint bind_point) {
532 pipeline_bind_point = bind_point;
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600533 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
Jason Macnak83cfd582019-07-31 10:14:24 -0700534
locke-lunargb8d7a7a2020-10-25 16:01:52 -0600535 LAST_BOUND_STATE &last_bound = cb_state->lastBound[lv_bind_point];
Jason Macnak83cfd582019-07-31 10:14:24 -0700536 if (last_bound.pipeline_state) {
Jeremy Gebben14b0d1a2021-05-15 20:15:41 -0600537 pipeline = last_bound.pipeline_state->pipeline();
Jason Macnak83cfd582019-07-31 10:14:24 -0700538 pipeline_layout = last_bound.pipeline_layout;
539 descriptor_sets.reserve(last_bound.per_set.size());
540 for (std::size_t i = 0; i < last_bound.per_set.size(); i++) {
Jeremy Gebben4d51c552022-01-06 21:27:15 -0700541 const auto &bound_descriptor_set = last_bound.per_set[i].bound_descriptor_set;
ziga-lunarge0b552b2021-09-05 21:39:57 +0200542 if (bound_descriptor_set) {
543 descriptor_sets.push_back(bound_descriptor_set->GetSet());
544 if (bound_descriptor_set->IsPushDescriptor()) {
545 push_descriptor_set_index = static_cast<uint32_t>(i);
546 }
547 dynamic_offsets.push_back(last_bound.per_set[i].dynamicOffsets);
Jason Macnak83cfd582019-07-31 10:14:24 -0700548 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700549 }
550
551 if (last_bound.push_descriptor_set) {
552 push_descriptor_set_writes = last_bound.push_descriptor_set->GetWrites();
553 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700554 const auto &pipeline_layout = last_bound.pipeline_state->PipelineLayoutState();
555 if (pipeline_layout->push_constant_ranges == cb_state->push_constant_data_ranges) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700556 push_constants_data = cb_state->push_constant_data;
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -0700557 push_constants_ranges = pipeline_layout->push_constant_ranges;
Jason Macnak83cfd582019-07-31 10:14:24 -0700558 }
559 }
560 }
561
562 void Restore(VkCommandBuffer command_buffer) const {
563 if (pipeline != VK_NULL_HANDLE) {
564 DispatchCmdBindPipeline(command_buffer, pipeline_bind_point, pipeline);
565 if (!descriptor_sets.empty()) {
566 for (std::size_t i = 0; i < descriptor_sets.size(); i++) {
567 VkDescriptorSet descriptor_set = descriptor_sets[i];
568 if (descriptor_set != VK_NULL_HANDLE) {
569 DispatchCmdBindDescriptorSets(command_buffer, pipeline_bind_point, pipeline_layout,
570 static_cast<uint32_t>(i), 1, &descriptor_set,
571 static_cast<uint32_t>(dynamic_offsets[i].size()), dynamic_offsets[i].data());
572 }
573 }
574 }
575 if (!push_descriptor_set_writes.empty()) {
576 DispatchCmdPushDescriptorSetKHR(command_buffer, pipeline_bind_point, pipeline_layout, push_descriptor_set_index,
577 static_cast<uint32_t>(push_descriptor_set_writes.size()),
578 reinterpret_cast<const VkWriteDescriptorSet *>(push_descriptor_set_writes.data()));
579 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600580 if (!push_constants_data.empty()) {
581 for (const auto &push_constant_range : *push_constants_ranges) {
582 if (push_constant_range.size == 0) continue;
583 DispatchCmdPushConstants(command_buffer, pipeline_layout, push_constant_range.stageFlags,
584 push_constant_range.offset, push_constant_range.size, push_constants_data.data());
585 }
Jason Macnak83cfd582019-07-31 10:14:24 -0700586 }
587 }
588 }
589};
590
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600591void GpuAssisted::PreCallRecordCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,
592 const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData,
593 VkDeviceSize instanceOffset, VkBool32 update,
594 VkAccelerationStructureNV dst, VkAccelerationStructureNV src,
595 VkBuffer scratch, VkDeviceSize scratchOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600596 ValidationStateTracker::PreCallRecordCmdBuildAccelerationStructureNV(commandBuffer, pInfo, instanceData, instanceOffset, update,
597 dst, src, scratch, scratchOffset);
Jason Macnak83cfd582019-07-31 10:14:24 -0700598 if (pInfo == nullptr || pInfo->type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV) {
599 return;
600 }
601
Tony-LunarG99b880b2019-09-26 11:19:52 -0600602 auto &as_validation_state = acceleration_structure_validation_state;
Jason Macnak83cfd582019-07-31 10:14:24 -0700603 if (!as_validation_state.initialized) {
604 return;
605 }
606
607 // Empty acceleration structure is valid according to the spec.
608 if (pInfo->instanceCount == 0 || instanceData == VK_NULL_HANDLE) {
609 return;
610 }
611
Jeremy Gebben04697b02022-03-23 16:18:12 -0600612 auto cb_state = GetWrite<gpuav_state::CommandBuffer>(commandBuffer);
Jason Macnak83cfd582019-07-31 10:14:24 -0700613 assert(cb_state != nullptr);
614
615 std::vector<uint64_t> current_valid_handles;
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600616 ForEach<ACCELERATION_STRUCTURE_STATE>([&current_valid_handles](const ACCELERATION_STRUCTURE_STATE &as_state) {
Jeff Bolz95176d02020-04-01 00:36:16 -0500617 if (as_state.built && as_state.create_infoNV.info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700618 current_valid_handles.push_back(as_state.opaque_handle);
619 }
Jeremy Gebbenb7bfbd02021-11-01 15:17:50 -0600620 });
Jason Macnak83cfd582019-07-31 10:14:24 -0700621
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600622 GpuAssistedAccelerationStructureBuildValidationBufferInfo as_validation_buffer_info = {};
Jason Macnak83cfd582019-07-31 10:14:24 -0700623 as_validation_buffer_info.acceleration_structure = dst;
624
625 const VkDeviceSize validation_buffer_size =
626 // One uint for number of instances to validate
627 4 +
628 // Two uint for the replacement acceleration structure handle
629 8 +
630 // One uint for number of invalid handles found
631 4 +
632 // Two uint for the first invalid handle found
633 8 +
634 // One uint for the number of current valid handles
635 4 +
636 // Two uint for each current valid handle
637 (8 * current_valid_handles.size());
638
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600639 auto validation_buffer_create_info = LvlInitStruct<VkBufferCreateInfo>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700640 validation_buffer_create_info.size = validation_buffer_size;
641 validation_buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
642
643 VmaAllocationCreateInfo validation_buffer_alloc_info = {};
644 validation_buffer_alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
645
Tony-LunarG99b880b2019-09-26 11:19:52 -0600646 VkResult result = vmaCreateBuffer(vmaAllocator, &validation_buffer_create_info, &validation_buffer_alloc_info,
sjfricke43b340c2022-08-04 22:18:38 +0900647 &as_validation_buffer_info.buffer, &as_validation_buffer_info.buffer_allocation, nullptr);
Jason Macnak83cfd582019-07-31 10:14:24 -0700648 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700649 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600650 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700651 return;
652 }
653
654 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
sjfricke43b340c2022-08-04 22:18:38 +0900655 result = vmaMapMemory(vmaAllocator, as_validation_buffer_info.buffer_allocation,
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700656 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700657 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700658 ReportSetupProblem(device, "Unable to allocate device memory for acceleration structure build val buffer.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600659 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700660 return;
661 }
662
663 mapped_validation_buffer->instances_to_validate = pInfo->instanceCount;
664 mapped_validation_buffer->replacement_handle_bits_0 =
665 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[0];
666 mapped_validation_buffer->replacement_handle_bits_1 =
667 reinterpret_cast<const uint32_t *>(&as_validation_state.replacement_as_handle)[1];
668 mapped_validation_buffer->invalid_handle_found = 0;
669 mapped_validation_buffer->invalid_handle_bits_0 = 0;
670 mapped_validation_buffer->invalid_handle_bits_1 = 0;
671 mapped_validation_buffer->valid_handles_count = static_cast<uint32_t>(current_valid_handles.size());
672
673 uint32_t *mapped_valid_handles = reinterpret_cast<uint32_t *>(&mapped_validation_buffer[1]);
674 for (std::size_t i = 0; i < current_valid_handles.size(); i++) {
675 const uint64_t current_valid_handle = current_valid_handles[i];
676
677 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[0];
678 ++mapped_valid_handles;
679 *mapped_valid_handles = reinterpret_cast<const uint32_t *>(&current_valid_handle)[1];
680 ++mapped_valid_handles;
681 }
682
sjfricke43b340c2022-08-04 22:18:38 +0900683 vmaUnmapMemory(vmaAllocator, as_validation_buffer_info.buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700684
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700685 static constexpr const VkDeviceSize k_instance_size = 64;
686 const VkDeviceSize instance_buffer_size = k_instance_size * pInfo->instanceCount;
Jason Macnak83cfd582019-07-31 10:14:24 -0700687
Tony-LunarG1dce2392019-10-23 16:49:29 -0600688 result = desc_set_manager->GetDescriptorSet(&as_validation_buffer_info.descriptor_pool, debug_desc_layout,
689 &as_validation_buffer_info.descriptor_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700690 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700691 ReportSetupProblem(device, "Unable to get descriptor set for acceleration structure build.");
Tony-LunarG99b880b2019-09-26 11:19:52 -0600692 aborted = true;
Jason Macnak83cfd582019-07-31 10:14:24 -0700693 return;
694 }
695
696 VkDescriptorBufferInfo descriptor_buffer_infos[2] = {};
697 descriptor_buffer_infos[0].buffer = instanceData;
698 descriptor_buffer_infos[0].offset = instanceOffset;
699 descriptor_buffer_infos[0].range = instance_buffer_size;
sjfricke43b340c2022-08-04 22:18:38 +0900700 descriptor_buffer_infos[1].buffer = as_validation_buffer_info.buffer;
Jason Macnak83cfd582019-07-31 10:14:24 -0700701 descriptor_buffer_infos[1].offset = 0;
702 descriptor_buffer_infos[1].range = validation_buffer_size;
703
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600704 VkWriteDescriptorSet descriptor_set_writes[2] = {
705 LvlInitStruct<VkWriteDescriptorSet>(),
706 LvlInitStruct<VkWriteDescriptorSet>(),
707 };
Jason Macnak83cfd582019-07-31 10:14:24 -0700708 descriptor_set_writes[0].dstSet = as_validation_buffer_info.descriptor_set;
709 descriptor_set_writes[0].dstBinding = 0;
710 descriptor_set_writes[0].descriptorCount = 1;
711 descriptor_set_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
712 descriptor_set_writes[0].pBufferInfo = &descriptor_buffer_infos[0];
Jason Macnak83cfd582019-07-31 10:14:24 -0700713 descriptor_set_writes[1].dstSet = as_validation_buffer_info.descriptor_set;
714 descriptor_set_writes[1].dstBinding = 1;
715 descriptor_set_writes[1].descriptorCount = 1;
716 descriptor_set_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
717 descriptor_set_writes[1].pBufferInfo = &descriptor_buffer_infos[1];
718
719 DispatchUpdateDescriptorSets(device, 2, descriptor_set_writes, 0, nullptr);
720
721 // Issue a memory barrier to make sure anything writing to the instance buffer has finished.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600722 auto memory_barrier = LvlInitStruct<VkMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700723 memory_barrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
724 memory_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
725 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1,
726 &memory_barrier, 0, nullptr, 0, nullptr);
727
728 // Save a copy of the compute pipeline state that needs to be restored.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600729 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -0600730 restorable_state.Create(cb_state.get(), VK_PIPELINE_BIND_POINT_COMPUTE);
Jason Macnak83cfd582019-07-31 10:14:24 -0700731
732 // Switch to and launch the validation compute shader to find, replace, and report invalid acceleration structure handles.
733 DispatchCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline);
734 DispatchCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, as_validation_state.pipeline_layout, 0, 1,
735 &as_validation_buffer_info.descriptor_set, 0, nullptr);
736 DispatchCmdDispatch(commandBuffer, 1, 1, 1);
737
738 // Issue a buffer memory barrier to make sure that any invalid bottom level acceleration structure handles
739 // have been replaced by the validation compute shader before any builds take place.
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -0600740 auto instance_buffer_barrier = LvlInitStruct<VkBufferMemoryBarrier>();
Jason Macnak83cfd582019-07-31 10:14:24 -0700741 instance_buffer_barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
742 instance_buffer_barrier.dstAccessMask = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV;
743 instance_buffer_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
744 instance_buffer_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
745 instance_buffer_barrier.buffer = instanceData;
746 instance_buffer_barrier.offset = instanceOffset;
747 instance_buffer_barrier.size = instance_buffer_size;
748 DispatchCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
749 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV, 0, 0, nullptr, 1, &instance_buffer_barrier, 0,
750 nullptr);
751
752 // Restore the previous compute pipeline state.
753 restorable_state.Restore(commandBuffer);
754
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600755 cb_state->as_validation_buffers.emplace_back(std::move(as_validation_buffer_info));
Jason Macnak83cfd582019-07-31 10:14:24 -0700756}
757
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600758void gpuav_state::CommandBuffer::ProcessAccelerationStructure(VkQueue queue) {
sjfricke52defd42022-08-08 16:37:46 +0900759 if (!has_build_as_cmd) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700760 return;
761 }
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600762 auto *device_state = static_cast<GpuAssisted *>(dev_data);
763 for (const auto &as_validation_buffer_info : as_validation_buffers) {
Jason Macnak83cfd582019-07-31 10:14:24 -0700764 GpuAccelerationStructureBuildValidationBuffer *mapped_validation_buffer = nullptr;
765
sjfricke43b340c2022-08-04 22:18:38 +0900766 VkResult result = vmaMapMemory(device_state->vmaAllocator, as_validation_buffer_info.buffer_allocation,
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700767 reinterpret_cast<void **>(&mapped_validation_buffer));
Jason Macnak83cfd582019-07-31 10:14:24 -0700768 if (result == VK_SUCCESS) {
769 if (mapped_validation_buffer->invalid_handle_found > 0) {
770 uint64_t invalid_handle = 0;
771 reinterpret_cast<uint32_t *>(&invalid_handle)[0] = mapped_validation_buffer->invalid_handle_bits_0;
772 reinterpret_cast<uint32_t *>(&invalid_handle)[1] = mapped_validation_buffer->invalid_handle_bits_1;
773
Jeremy Gebben5ca80b32022-04-11 10:58:39 -0600774 device_state->LogError(
775 as_validation_buffer_info.acceleration_structure, "UNASSIGNED-AccelerationStructure",
776 "Attempted to build top level acceleration structure using invalid bottom level acceleration structure "
777 "handle (%" PRIu64 ")",
778 invalid_handle);
Jason Macnak83cfd582019-07-31 10:14:24 -0700779 }
sjfricke43b340c2022-08-04 22:18:38 +0900780 vmaUnmapMemory(device_state->vmaAllocator, as_validation_buffer_info.buffer_allocation);
Jason Macnak83cfd582019-07-31 10:14:24 -0700781 }
782 }
783}
784
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600785void GpuAssisted::PostCallRecordBindAccelerationStructureMemoryNV(VkDevice device, uint32_t bindInfoCount,
786 const VkBindAccelerationStructureMemoryInfoNV *pBindInfos,
787 VkResult result) {
788 if (VK_SUCCESS != result) return;
Tony-LunarG99b880b2019-09-26 11:19:52 -0600789 ValidationStateTracker::PostCallRecordBindAccelerationStructureMemoryNV(device, bindInfoCount, pBindInfos, result);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600790 for (uint32_t i = 0; i < bindInfoCount; i++) {
791 const VkBindAccelerationStructureMemoryInfoNV &info = pBindInfos[i];
Jeremy Gebbenb20a8242021-11-05 15:14:43 -0600792 auto as_state = Get<ACCELERATION_STRUCTURE_STATE>(info.accelerationStructure);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600793 if (as_state) {
794 DispatchGetAccelerationStructureHandleNV(device, info.accelerationStructure, 8, &as_state->opaque_handle);
795 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600796 }
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600797}
Mark Lobodzinskiff7d8002019-02-13 13:01:26 -0700798
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600799// Free the device memory and descriptor set(s) associated with a command buffer.
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600800void GpuAssisted::DestroyBuffer(GpuAssistedBufferInfo &buffer_info) {
801 vmaDestroyBuffer(vmaAllocator, buffer_info.output_mem_block.buffer, buffer_info.output_mem_block.allocation);
802 if (buffer_info.di_input_mem_block.buffer) {
803 vmaDestroyBuffer(vmaAllocator, buffer_info.di_input_mem_block.buffer, buffer_info.di_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600804 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600805 if (buffer_info.bda_input_mem_block.buffer) {
806 vmaDestroyBuffer(vmaAllocator, buffer_info.bda_input_mem_block.buffer, buffer_info.bda_input_mem_block.allocation);
Karl Schultz7b024b42018-08-30 16:18:18 -0600807 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600808 if (buffer_info.desc_set != VK_NULL_HANDLE) {
809 desc_set_manager->PutBackDescriptorSet(buffer_info.desc_pool, buffer_info.desc_set);
Jason Macnak83cfd582019-07-31 10:14:24 -0700810 }
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600811 if (buffer_info.pre_draw_resources.desc_set != VK_NULL_HANDLE) {
812 desc_set_manager->PutBackDescriptorSet(buffer_info.pre_draw_resources.desc_pool, buffer_info.pre_draw_resources.desc_set);
813 }
Karl Schultz7b024b42018-08-30 16:18:18 -0600814}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600815
816void GpuAssisted::DestroyBuffer(GpuAssistedAccelerationStructureBuildValidationBufferInfo &as_validation_buffer_info) {
sjfricke43b340c2022-08-04 22:18:38 +0900817 vmaDestroyBuffer(vmaAllocator, as_validation_buffer_info.buffer, as_validation_buffer_info.buffer_allocation);
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -0600818
819 if (as_validation_buffer_info.descriptor_set != VK_NULL_HANDLE) {
820 desc_set_manager->PutBackDescriptorSet(as_validation_buffer_info.descriptor_pool, as_validation_buffer_info.descriptor_set);
821 }
822}
823
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600824void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
825 VkPhysicalDeviceProperties *pPhysicalDeviceProperties) {
826 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -0600827 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600828 if (pPhysicalDeviceProperties->limits.maxBoundDescriptorSets > 1) {
829 pPhysicalDeviceProperties->limits.maxBoundDescriptorSets -= 1;
830 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700831 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
832 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600833 }
834 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600835 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties(physicalDevice, pPhysicalDeviceProperties);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600836}
837
838void GpuAssisted::PostCallRecordGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
839 VkPhysicalDeviceProperties2 *pPhysicalDeviceProperties2) {
840 // There is an implicit layer that can cause this call to return 0 for maxBoundDescriptorSets - Ignore such calls
Mark Lobodzinski90eea5b2020-05-15 12:54:00 -0600841 if (enabled[gpu_validation_reserve_binding_slot] && pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 0) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600842 if (pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets > 1) {
843 pPhysicalDeviceProperties2->properties.limits.maxBoundDescriptorSets -= 1;
844 } else {
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -0700845 LogWarning(physicalDevice, "UNASSIGNED-GPU-Assisted Validation Setup Error.",
846 "Unable to reserve descriptor binding slot on a device with only one slot.");
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600847 }
848 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600849 ValidationStateTracker::PostCallRecordGetPhysicalDeviceProperties2(physicalDevice, pPhysicalDeviceProperties2);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600850}
851
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600852void GpuAssisted::PreCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
853 const VkAllocationCallbacks *pAllocator) {
Jeremy Gebbenbba39212022-03-29 16:39:06 -0600854 auto pipeline = pre_draw_validation_state.renderpass_to_pipeline.pop(renderPass);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600855 if (pipeline != pre_draw_validation_state.renderpass_to_pipeline.end()) {
856 DispatchDestroyPipeline(device, pipeline->second, nullptr);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600857 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600858 ValidationStateTracker::PreCallRecordDestroyRenderPass(device, renderPass, pAllocator);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600859}
860
Karl Schultz7b024b42018-08-30 16:18:18 -0600861// Call the SPIR-V Optimizer to run the instrumentation pass on the shader.
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800862bool GpuAssisted::InstrumentShader(const VkShaderModuleCreateInfo *pCreateInfo, std::vector<uint32_t> &new_pgm,
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600863 uint32_t *unique_shader_id) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600864 if (aborted) return false;
Karl Schultz7b024b42018-08-30 16:18:18 -0600865 if (pCreateInfo->pCode[0] != spv::MagicNumber) return false;
866
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700867 const spvtools::MessageConsumer gpu_console_message_consumer =
Tony-LunarG79641702020-07-13 15:43:05 -0600868 [this](spv_message_level_t level, const char *, const spv_position_t &position, const char *message) -> void {
869 switch (level) {
870 case SPV_MSG_FATAL:
871 case SPV_MSG_INTERNAL_ERROR:
872 case SPV_MSG_ERROR:
873 this->LogError(this->device, "UNASSIGNED-GPU-Assisted", "Error during shader instrumentation: line %zu: %s",
874 position.index, message);
875 break;
876 default:
877 break;
878 }
879 };
880
Karl Schultz7b024b42018-08-30 16:18:18 -0600881 // Load original shader SPIR-V
882 uint32_t num_words = static_cast<uint32_t>(pCreateInfo->codeSize / 4);
883 new_pgm.clear();
884 new_pgm.reserve(num_words);
885 new_pgm.insert(new_pgm.end(), &pCreateInfo->pCode[0], &pCreateInfo->pCode[num_words]);
886
887 // Call the optimizer to instrument the shader.
888 // 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 -0700889 // If descriptor indexing is enabled, enable length checks and updated descriptor checks
Karl Schultz7b024b42018-08-30 16:18:18 -0600890 using namespace spvtools;
sfricke-samsung45996a42021-09-16 13:45:27 -0700891 spv_target_env target_env = PickSpirvEnv(api_version, IsExtEnabled(device_extensions.vk_khr_spirv_1_4));
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600892 spvtools::ValidatorOptions val_options;
893 AdjustValidatorOptions(device_extensions, enabled_features, val_options);
894 spvtools::OptimizerOptions opt_options;
895 opt_options.set_run_validator(true);
896 opt_options.set_validator_options(val_options);
Karl Schultz7b024b42018-08-30 16:18:18 -0600897 Optimizer optimizer(target_env);
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700898 optimizer.SetMessageConsumer(gpu_console_message_consumer);
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600899 optimizer.RegisterPass(CreateInstBindlessCheckPass(desc_set_bind_index, unique_shader_module_id, descriptor_indexing,
Tony-LunarGe8632e42020-11-18 17:03:12 -0700900 descriptor_indexing, buffer_oob_enabled, buffer_oob_enabled));
Tony-LunarG57400d42021-10-14 11:18:43 -0600901 // Call CreateAggressiveDCEPass with preserve_interface == true
902 optimizer.RegisterPass(CreateAggressiveDCEPass(true));
sfricke-samsung45996a42021-09-16 13:45:27 -0700903 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
904 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
905 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
Tony-LunarG99b880b2019-09-26 11:19:52 -0600906 optimizer.RegisterPass(CreateInstBuffAddrCheckPass(desc_set_bind_index, unique_shader_module_id));
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -0700907 }
Tony-LunarGf29f77f2020-08-26 15:48:00 -0600908 bool pass = optimizer.Run(new_pgm.data(), new_pgm.size(), &new_pgm, opt_options);
Karl Schultz7b024b42018-08-30 16:18:18 -0600909 if (!pass) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -0700910 ReportSetupProblem(device, "Failure to instrument shader. Proceeding with non-instrumented shader.");
Karl Schultz7b024b42018-08-30 16:18:18 -0600911 }
Tony-LunarG99b880b2019-09-26 11:19:52 -0600912 *unique_shader_id = unique_shader_module_id++;
Karl Schultz7b024b42018-08-30 16:18:18 -0600913 return pass;
914}
Mark Lobodzinski01734072019-02-13 17:39:15 -0700915// Create the instrumented shader data to provide to the driver.
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600916void GpuAssisted::PreCallRecordCreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
917 const VkAllocationCallbacks *pAllocator, VkShaderModule *pShaderModule,
918 void *csm_state_data) {
919 create_shader_module_api_state *csm_state = reinterpret_cast<create_shader_module_api_state *>(csm_state_data);
920 bool pass = InstrumentShader(pCreateInfo, csm_state->instrumented_pgm, &csm_state->unique_shader_id);
Karl Schultz7b024b42018-08-30 16:18:18 -0600921 if (pass) {
Tony-LunarG2ba1cb32019-09-25 15:16:11 -0600922 csm_state->instrumented_create_info.pCode = csm_state->instrumented_pgm.data();
sfricke-samsung7fac88a2022-01-26 11:44:22 -0800923 csm_state->instrumented_create_info.codeSize = csm_state->instrumented_pgm.size() * sizeof(uint32_t);
Karl Schultz7b024b42018-08-30 16:18:18 -0600924 }
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -0600925 ValidationStateTracker::PreCallRecordCreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule, csm_state_data);
Karl Schultz7b024b42018-08-30 16:18:18 -0600926}
Tony-LunarG20678ff2021-05-07 14:56:26 -0600927
Karl Schultz7b024b42018-08-30 16:18:18 -0600928// Generate the part of the message describing the violation.
Tony-LunarG1a7c9f92021-04-29 16:04:42 -0600929bool GenerateValidationMessage(const uint32_t *debug_record, std::string &msg, std::string &vuid_msg, GpuAssistedBufferInfo buf_info, GpuAssisted *gpu_assisted) {
Karl Schultz7b024b42018-08-30 16:18:18 -0600930 using namespace spvtools;
931 std::ostringstream strm;
Tony-LunarG63f82e02021-04-12 16:13:48 -0600932 bool return_code = true;
sjfricke125f74d2022-08-08 18:27:25 +0900933 static_assert(
934 spvtools::kInstErrorMax == _kInstErrorMax,
935 "If this asserts then SPIRV-Tools was updated with a new instrument.hpp and kInstErrorMax was updated. This needs to be "
936 "changed in GPU-AV so that the GLSL gpu_shaders can read the constants.");
937 static_assert(spvtools::kInstValidationOutError == _kInstValidationOutError,
938 "If this asserts then SPIRV-Tools was updated with a new instrument.hpp and kInstValidationOutError was updated. "
939 "This needs to be changed in GPU-AV so that the GLSL gpu_shaders can read the constants.");
Tony-LunarGab47cac2019-12-20 15:28:01 -0700940 switch (debug_record[kInstValidationOutError]) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600941 case kInstErrorBindlessBounds: {
Tony-LunarGab47cac2019-12-20 15:28:01 -0700942 strm << "Index of " << debug_record[kInstBindlessBoundsOutDescIndex] << " used to index descriptor array of length "
943 << debug_record[kInstBindlessBoundsOutDescBound] << ". ";
Tony-LunarGc1d657d2019-02-22 14:55:19 -0700944 vuid_msg = "UNASSIGNED-Descriptor index out of bounds";
Karl Schultz7b024b42018-08-30 16:18:18 -0600945 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600946 case kInstErrorBindlessUninit: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600947 strm << "Descriptor index " << debug_record[kInstBindlessUninitOutDescIndex] << " is uninitialized.";
Tony-LunarGc1d657d2019-02-22 14:55:19 -0700948 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Karl Schultz7b024b42018-08-30 16:18:18 -0600949 } break;
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600950 case kInstErrorBuffAddrUnallocRef: {
Tony-LunarGab47cac2019-12-20 15:28:01 -0700951 uint64_t *ptr = (uint64_t *)&debug_record[kInstBuffAddrUnallocOutDescPtrLo];
Tony-LunarG8eb5a002019-07-25 16:49:00 -0600952 strm << "Device address 0x" << std::hex << *ptr << " access out of bounds. ";
953 vuid_msg = "UNASSIGNED-Device address out of bounds";
954 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -0700955 case kInstErrorBuffOOBUniform:
956 case kInstErrorBuffOOBStorage: {
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600957 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
958 if (size == 0) {
959 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
960 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
961 } else {
962 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
963 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
Tony-LunarG7de10e82020-11-24 11:31:55 -0700964 << " and highest byte accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -0600965 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -0700966 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniform)
967 vuid_msg = vuid.uniform_access_oob;
968 else
969 vuid_msg = vuid.storage_access_oob;
Tony-LunarGc28e28a2020-08-14 10:37:48 -0600970 }
971 } break;
Tony-LunarG7de10e82020-11-24 11:31:55 -0700972 case kInstErrorBuffOOBUniformTexel:
973 case kInstErrorBuffOOBStorageTexel: {
974 auto size = debug_record[kInstBindlessBuffOOBOutBuffSize];
975 if (size == 0) {
976 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex] << " is uninitialized.";
977 vuid_msg = "UNASSIGNED-Descriptor uninitialized";
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600978 } else {
Tony-LunarG7de10e82020-11-24 11:31:55 -0700979 strm << "Descriptor index " << debug_record[kInstBindlessBuffOOBOutDescIndex]
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600980 << " access out of bounds. Descriptor size is " << debug_record[kInstBindlessBuffOOBOutBuffSize]
981 << " texels and highest texel accessed was " << debug_record[kInstBindlessBuffOOBOutBuffOff];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -0600982 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
Tony-LunarG7de10e82020-11-24 11:31:55 -0700983 if (debug_record[kInstValidationOutError] == kInstErrorBuffOOBUniformTexel)
984 vuid_msg = vuid.uniform_access_oob;
985 else
986 vuid_msg = vuid.storage_access_oob;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -0600987 }
Tony-LunarG63f82e02021-04-12 16:13:48 -0600988 } break;
sjfricke125f74d2022-08-08 18:27:25 +0900989 case _kInstErrorPreDrawValidate: {
Tim Van Patten38bdcdd2021-05-14 16:41:00 -0600990 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand))
sjfricke125f74d2022-08-08 18:27:25 +0900991 if (debug_record[_kPreDrawValidateSubError] == pre_draw_count_exceeds_bufsize_error) {
992 uint32_t count = debug_record[_kPreDrawValidateSubError + 1];
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -0600993 uint32_t stride = buf_info.pre_draw_resources.stride;
994 uint32_t offset = static_cast<uint32_t>(buf_info.pre_draw_resources.offset);
995 uint32_t draw_size = (stride * (count - 1) + offset + sizeof(VkDrawIndexedIndirectCommand));
996 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
997 strm << "Indirect draw count of " << count << " would exceed buffer size " << buf_info.pre_draw_resources.buf_size
998 << " of buffer " << buf_info.pre_draw_resources.buffer << " stride = " << stride << " offset = " << offset
999 << " (stride * (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) = " << draw_size;
Tony-LunarG64aeaf72021-04-14 11:13:35 -06001000 if (count == 1) {
1001 vuid_msg = vuid.count_exceeds_bufsize_1;
1002 } else {
1003 vuid_msg = vuid.count_exceeds_bufsize;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001004 }
sjfricke125f74d2022-08-08 18:27:25 +09001005 } else if (debug_record[_kPreDrawValidateSubError] == pre_draw_count_exceeds_limit_error) {
1006 uint32_t count = debug_record[_kPreDrawValidateSubError + 1];
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001007 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1008 strm << "Indirect draw count of " << count << " would exceed maxDrawIndirectCount limit of "
1009 << gpu_assisted->phys_dev_props.limits.maxDrawIndirectCount;
1010 vuid_msg = vuid.count_exceeds_device_limit;
sjfricke125f74d2022-08-08 18:27:25 +09001011 } else if (debug_record[_kPreDrawValidateSubError] == pre_draw_first_instance_error) {
1012 uint32_t index = debug_record[_kPreDrawValidateSubError + 1];
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001013 const GpuVuid vuid = GetGpuVuid(buf_info.cmd_type);
1014 strm << "The drawIndirectFirstInstance feature is not enabled, but the firstInstance member of the "
1015 "VkDrawIndirectCommand structure at index "
1016 << index << " is not zero";
1017 vuid_msg = vuid.first_instance_not_zero;
Tony-LunarG63f82e02021-04-12 16:13:48 -06001018 }
1019 return_code = false;
1020 } break;
Karl Schultz7b024b42018-08-30 16:18:18 -06001021 default: {
Tony-LunarGab47cac2019-12-20 15:28:01 -07001022 strm << "Internal Error (unexpected error type = " << debug_record[kInstValidationOutError] << "). ";
Karl Schultz7b024b42018-08-30 16:18:18 -06001023 vuid_msg = "UNASSIGNED-Internal Error";
1024 assert(false);
1025 } break;
1026 }
1027 msg = strm.str();
Tony-LunarG63f82e02021-04-12 16:13:48 -06001028 return return_code;
Karl Schultz7b024b42018-08-30 16:18:18 -06001029}
1030
Karl Schultz7b024b42018-08-30 16:18:18 -06001031// Pull together all the information from the debug record to build the error message strings,
1032// and then assemble them into a single message string.
1033// Retrieve the shader program referenced by the unique shader ID provided in the debug record.
1034// We had to keep a copy of the shader program with the same lifecycle as the pipeline to make
1035// sure it is available when the pipeline is submitted. (The ShaderModule tracking object also
1036// keeps a copy, but it can be destroyed after the pipeline is created and before it is submitted.)
1037//
Tony-LunarG7de10e82020-11-24 11:31:55 -07001038void GpuAssisted::AnalyzeAndGenerateMessages(VkCommandBuffer command_buffer, VkQueue queue, GpuAssistedBufferInfo &buffer_info,
Tony-LunarG1dce2392019-10-23 16:49:29 -06001039 uint32_t operation_index, uint32_t *const debug_output_buffer) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001040 using namespace spvtools;
1041 const uint32_t total_words = debug_output_buffer[0];
1042 // A zero here means that the shader instrumentation didn't write anything.
1043 // If you have nothing to say, don't say it here.
1044 if (0 == total_words) {
1045 return;
1046 }
1047 // The first word in the debug output buffer is the number of words that would have
1048 // been written by the shader instrumentation, if there was enough room in the buffer we provided.
1049 // The number of words actually written by the shaders is determined by the size of the buffer
1050 // we provide via the descriptor. So, we process only the number of words that can fit in the
1051 // buffer.
1052 // Each "report" written by the shader instrumentation is considered a "record". This function
1053 // is hard-coded to process only one record because it expects the buffer to be large enough to
1054 // hold only one record. If there is a desire to process more than one record, this function needs
1055 // to be modified to loop over records and the buffer size increased.
Karl Schultz7b024b42018-08-30 16:18:18 -06001056 std::string validation_message;
1057 std::string stage_message;
1058 std::string common_message;
1059 std::string filename_message;
1060 std::string source_message;
1061 std::string vuid_msg;
1062 VkShaderModule shader_module_handle = VK_NULL_HANDLE;
1063 VkPipeline pipeline_handle = VK_NULL_HANDLE;
sfricke-samsung7fac88a2022-01-26 11:44:22 -08001064 std::vector<uint32_t> pgm;
Karl Schultz7b024b42018-08-30 16:18:18 -06001065 // The first record starts at this offset after the total_words.
1066 const uint32_t *debug_record = &debug_output_buffer[kDebugOutputDataOffset];
1067 // Lookup the VkShaderModule handle and SPIR-V code used to create the shader, using the unique shader ID value returned
1068 // by the instrumented shader.
Tony-LunarG99b880b2019-09-26 11:19:52 -06001069 auto it = shader_map.find(debug_record[kInstCommonOutShaderId]);
1070 if (it != shader_map.end()) {
Karl Schultz7b024b42018-08-30 16:18:18 -06001071 shader_module_handle = it->second.shader_module;
1072 pipeline_handle = it->second.pipeline;
1073 pgm = it->second.pgm;
1074 }
Tony-LunarG1a7c9f92021-04-29 16:04:42 -06001075 bool gen_full_message = GenerateValidationMessage(debug_record, validation_message, vuid_msg, buffer_info, this);
Tony-LunarG63f82e02021-04-12 16:13:48 -06001076 if (gen_full_message) {
1077 UtilGenerateStageMessage(debug_record, stage_message);
1078 UtilGenerateCommonMessage(report_data, command_buffer, debug_record, shader_module_handle, pipeline_handle,
1079 buffer_info.pipeline_bind_point, operation_index, common_message);
1080 UtilGenerateSourceMessages(pgm, debug_record, false, filename_message, source_message);
1081 LogError(queue, vuid_msg.c_str(), "%s %s %s %s%s", validation_message.c_str(), common_message.c_str(), stage_message.c_str(),
1082 filename_message.c_str(), source_message.c_str());
1083 }
1084 else {
1085 LogError(queue, vuid_msg.c_str(), "%s", validation_message.c_str());
1086 }
Karl Schultz7b024b42018-08-30 16:18:18 -06001087 // The debug record at word kInstCommonOutSize is the number of words in the record
1088 // written by the shader. Clear the entire record plus the total_words word at the start.
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001089 const uint32_t words_to_clear = 1 + std::min(debug_record[kInstCommonOutSize], static_cast<uint32_t>(kInstMaxOutCnt));
Karl Schultz7b024b42018-08-30 16:18:18 -06001090 memset(debug_output_buffer, 0, sizeof(uint32_t) * words_to_clear);
1091}
1092
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001093// For the given command buffer, map its debug data buffers and read their contents for analysis.
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001094void gpuav_state::CommandBuffer::Process(VkQueue queue) {
1095 auto *device_state = static_cast<GpuAssisted *>(dev_data);
sjfricke52defd42022-08-08 16:37:46 +09001096 if (has_draw_cmd || has_trace_rays_cmd || has_dispatch_cmd) {
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001097 auto &gpu_buffer_list = gpuav_buffer_list;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001098 uint32_t draw_index = 0;
1099 uint32_t compute_index = 0;
1100 uint32_t ray_trace_index = 0;
1101
1102 for (auto &buffer_info : gpu_buffer_list) {
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001103 char *data;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001104
1105 uint32_t operation_index = 0;
1106 if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
1107 operation_index = draw_index;
sjfricke9a209802022-08-03 17:57:40 +09001108 draw_index++;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001109 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) {
1110 operation_index = compute_index;
sjfricke9a209802022-08-03 17:57:40 +09001111 compute_index++;
sjfricke62366d32022-08-01 21:04:10 +09001112 } else if (buffer_info.pipeline_bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) {
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001113 operation_index = ray_trace_index;
sjfricke9a209802022-08-03 17:57:40 +09001114 ray_trace_index++;
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001115 } else {
1116 assert(false);
1117 }
1118
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001119 VkResult result = vmaMapMemory(device_state->vmaAllocator, buffer_info.output_mem_block.allocation, (void **)&data);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001120 if (result == VK_SUCCESS) {
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001121 device_state->AnalyzeAndGenerateMessages(commandBuffer(), queue, buffer_info, operation_index, (uint32_t *)data);
1122 vmaUnmapMemory(device_state->vmaAllocator, buffer_info.output_mem_block.allocation);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001123 }
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001124 }
1125 }
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06001126 ProcessAccelerationStructure(queue);
Jeremy Gebbenfcfc33c2022-03-28 15:31:29 -06001127}
1128
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001129void GpuAssisted::SetBindingState(uint32_t *data, uint32_t index, const cvdescriptorset::DescriptorBinding *binding) {
1130 switch (binding->descriptor_class) {
1131 case cvdescriptorset::DescriptorClass::GeneralBuffer: {
1132 auto buffer_binding = static_cast<const cvdescriptorset::BufferBinding *>(binding);
1133 for (uint32_t di = 0; di < buffer_binding->count; di++) {
1134 const auto &desc = buffer_binding->descriptors[di];
1135 if (!buffer_binding->updated[di]) {
1136 data[index++] = 0;
1137 continue;
1138 }
1139 auto buffer = desc.GetBuffer();
1140 if (buffer == VK_NULL_HANDLE) {
1141 data[index++] = UINT_MAX;
1142 } else {
1143 auto buffer_state = desc.GetBufferState();
1144 data[index++] = static_cast<uint32_t>(buffer_state->createInfo.size);
1145 }
1146 }
1147 break;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001148 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001149 case cvdescriptorset::DescriptorClass::TexelBuffer: {
1150 auto texel_binding = static_cast<const cvdescriptorset::TexelBinding *>(binding);
1151 for (uint32_t di = 0; di < texel_binding->count; di++) {
1152 const auto &desc = texel_binding->descriptors[di];
1153 if (!texel_binding->updated[di]) {
1154 data[index++] = 0;
1155 continue;
1156 }
1157 auto buffer_view = desc.GetBufferView();
1158 if (buffer_view == VK_NULL_HANDLE) {
1159 data[index++] = UINT_MAX;
1160 } else {
1161 auto buffer_view_state = desc.GetBufferViewState();
1162 data[index++] = static_cast<uint32_t>(buffer_view_state->buffer_state->createInfo.size);
1163 }
1164 }
1165 break;
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001166 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001167 case cvdescriptorset::DescriptorClass::Mutable: {
1168 auto mutable_binding = static_cast<const cvdescriptorset::MutableBinding *>(binding);
1169 for (uint32_t di = 0; di < mutable_binding->count; di++) {
1170 const auto &desc = mutable_binding->descriptors[di];
1171 if (!mutable_binding->updated[di]) {
1172 data[index++] = 0;
1173 continue;
1174 }
Jeremy Gebbenc08f6502022-07-15 09:55:06 -06001175 switch (desc.ActiveType()) {
1176 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1177 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1178 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1179 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1180 data[index++] = static_cast<uint32_t>(desc.GetBufferSize());
1181 break;
1182 default:
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001183 data[index++] = 1;
Jeremy Gebbenc08f6502022-07-15 09:55:06 -06001184 break;
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001185 }
1186 }
1187 break;
ziga7a255fb2021-11-20 21:17:07 +01001188 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001189 default: {
1190 for (uint32_t i = 0; i < binding->count; i++, index++) {
1191 data[index] = static_cast<uint32_t>(binding->updated[i]);
1192 }
1193 break;
1194 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001195 }
1196}
1197
Tony-LunarG81efe392019-03-07 15:43:27 -07001198// For the given command buffer, map its debug data buffers and update the status of any update after bind descriptors
Jeremy Gebben135550d2022-03-21 07:15:07 -06001199void GpuAssisted::UpdateInstrumentationBuffer(gpuav_state::CommandBuffer *cb_node) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001200 uint32_t *data;
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001201 for (auto &buffer_info : cb_node->gpuav_buffer_list) {
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001202 if (buffer_info.di_input_mem_block.update_at_submit.size() > 0) {
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001203 VkResult result =
1204 vmaMapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation, reinterpret_cast<void **>(&data));
Tony-LunarG81efe392019-03-07 15:43:27 -07001205 if (result == VK_SUCCESS) {
John Zulauf79f06582021-02-27 18:38:39 -07001206 for (const auto &update : buffer_info.di_input_mem_block.update_at_submit) {
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001207 SetBindingState(data, update.first, update.second);
Tony-LunarG81efe392019-03-07 15:43:27 -07001208 }
Tony-LunarG99b880b2019-09-26 11:19:52 -06001209 vmaUnmapMemory(vmaAllocator, buffer_info.di_input_mem_block.allocation);
Tony-LunarG81efe392019-03-07 15:43:27 -07001210 }
1211 }
1212 }
1213}
1214
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001215void GpuAssisted::PreRecordCommandBuffer(VkCommandBuffer command_buffer) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001216 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(command_buffer);
Jeremy Gebben9f537102021-10-05 16:37:12 -06001217 UpdateInstrumentationBuffer(cb_node.get());
John Zulauf79f06582021-02-27 18:38:39 -07001218 for (auto *secondary_cmd_buffer : cb_node->linkedCommandBuffers) {
Jeremy Gebben04697b02022-03-23 16:18:12 -06001219 auto guard = secondary_cmd_buffer->WriteLock();
Jeremy Gebben135550d2022-03-21 07:15:07 -06001220 UpdateInstrumentationBuffer(static_cast<gpuav_state::CommandBuffer *>(secondary_cmd_buffer));
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001221 }
1222}
1223
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001224void GpuAssisted::PreCallRecordQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001225 ValidationStateTracker::PreCallRecordQueueSubmit(queue, submitCount, pSubmits, fence);
Tony-LunarG81efe392019-03-07 15:43:27 -07001226 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1227 const VkSubmitInfo *submit = &pSubmits[submit_idx];
1228 for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001229 PreRecordCommandBuffer(submit->pCommandBuffers[i]);
Tony-LunarG81efe392019-03-07 15:43:27 -07001230 }
1231 }
1232}
Tony-LunarG26fe2842021-11-16 14:07:59 -07001233
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001234void GpuAssisted::PreCallRecordQueueSubmit2KHR(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2KHR *pSubmits,
1235 VkFence fence) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001236 ValidationStateTracker::PreCallRecordQueueSubmit2KHR(queue, submitCount, pSubmits, fence);
Jeremy Gebbena3705f42021-01-19 16:47:43 -07001237 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1238 const VkSubmitInfo2KHR *submit = &pSubmits[submit_idx];
1239 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1240 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1241 }
1242 }
1243}
1244
Tony-LunarG26fe2842021-11-16 14:07:59 -07001245void GpuAssisted::PreCallRecordQueueSubmit2(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2 *pSubmits, VkFence fence) {
1246 for (uint32_t submit_idx = 0; submit_idx < submitCount; submit_idx++) {
1247 const VkSubmitInfo2 *submit = &pSubmits[submit_idx];
1248 for (uint32_t i = 0; i < submit->commandBufferInfoCount; i++) {
1249 PreRecordCommandBuffer(submit->pCommandBufferInfos[i].commandBuffer);
1250 }
1251 }
1252}
1253
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001254void GpuAssisted::PreCallRecordCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
1255 uint32_t firstVertex, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001256 ValidationStateTracker::PreCallRecordCmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001257 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAW);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001258}
1259
Tony-LunarG745150c2021-07-02 15:07:31 -06001260void GpuAssisted::PreCallRecordCmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1261 const VkMultiDrawInfoEXT *pVertexInfo, uint32_t instanceCount,
1262 uint32_t firstInstance, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001263 ValidationStateTracker::PreCallRecordCmdDrawMultiEXT(commandBuffer, drawCount, pVertexInfo, instanceCount, firstInstance,
1264 stride);
Tony-LunarG745150c2021-07-02 15:07:31 -06001265 for (uint32_t i = 0; i < drawCount; i++) {
1266 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIEXT);
1267 }
1268}
1269
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001270void GpuAssisted::PreCallRecordCmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount,
1271 uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001272 ValidationStateTracker::PreCallRecordCmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
1273 firstInstance);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001274 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXED);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001275}
1276
Tony-LunarG745150c2021-07-02 15:07:31 -06001277void GpuAssisted::PreCallRecordCmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
1278 const VkMultiDrawIndexedInfoEXT *pIndexInfo, uint32_t instanceCount,
1279 uint32_t firstInstance, uint32_t stride, const int32_t *pVertexOffset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001280 ValidationStateTracker::PreCallRecordCmdDrawMultiIndexedEXT(commandBuffer, drawCount, pIndexInfo, instanceCount, firstInstance,
1281 stride, pVertexOffset);
Tony-LunarG745150c2021-07-02 15:07:31 -06001282 for (uint32_t i = 0; i < drawCount; i++) {
1283 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMULTIINDEXEDEXT);
1284 }
1285}
1286
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001287void GpuAssisted::PreCallRecordCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count,
1288 uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001289 ValidationStateTracker::PreCallRecordCmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001290 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1291 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001292}
1293
1294void GpuAssisted::PreCallRecordCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1295 uint32_t count, uint32_t stride) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001296 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001297 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, count, stride, 0, 0};
1298 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECT, &cdi_state);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001299}
1300
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001301void GpuAssisted::PreCallRecordCmdDrawIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1302 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
1303 uint32_t stride) {
1304 ValidationStateTracker::PreCallRecordCmdDrawIndirectCountKHR(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1305 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001306 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001307 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001308}
1309
1310void GpuAssisted::PreCallRecordCmdDrawIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1311 VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001312
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001313 uint32_t stride) {
1314 ValidationStateTracker::PreCallRecordCmdDrawIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1315 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001316 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1317 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001318}
1319
Tony-LunarG54176fb2020-12-02 10:47:22 -07001320void GpuAssisted::PreCallRecordCmdDrawIndirectByteCountEXT(VkCommandBuffer commandBuffer, uint32_t instanceCount,
1321 uint32_t firstInstance, VkBuffer counterBuffer,
1322 VkDeviceSize counterBufferOffset, uint32_t counterOffset,
1323 uint32_t vertexStride) {
1324 ValidationStateTracker::PreCallRecordCmdDrawIndirectByteCountEXT(commandBuffer, instanceCount, firstInstance, counterBuffer,
1325 counterBufferOffset, counterOffset, vertexStride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001326 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDIRECTBYTECOUNTEXT);
Tony-LunarG54176fb2020-12-02 10:47:22 -07001327}
1328
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001329void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCountKHR(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1330 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1331 uint32_t maxDrawCount, uint32_t stride) {
1332 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCountKHR(commandBuffer, buffer, offset, countBuffer,
1333 countBufferOffset, maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001334 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
sfricke-samsung85584a72021-09-30 21:43:38 -07001335 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNTKHR, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001336}
1337
1338void GpuAssisted::PreCallRecordCmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1339 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1340 uint32_t maxDrawCount, uint32_t stride) {
1341 ValidationStateTracker::PreCallRecordCmdDrawIndexedIndirectCount(commandBuffer, buffer, offset, countBuffer, countBufferOffset,
1342 maxDrawCount, stride);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001343 GpuAssistedCmdDrawIndirectState cdi_state = {buffer, offset, 0, stride, countBuffer, countBufferOffset};
1344 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWINDEXEDINDIRECTCOUNT, &cdi_state);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001345}
1346
1347void GpuAssisted::PreCallRecordCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask) {
1348 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksNV(commandBuffer, taskCount, firstTask);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001349 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001350}
1351
1352void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1353 uint32_t drawCount, uint32_t stride) {
1354 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectNV(commandBuffer, buffer, offset, drawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001355 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001356}
1357
1358void GpuAssisted::PreCallRecordCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
1359 VkBuffer countBuffer, VkDeviceSize countBufferOffset,
1360 uint32_t maxDrawCount, uint32_t stride) {
1361 ValidationStateTracker::PreCallRecordCmdDrawMeshTasksIndirectCountNV(commandBuffer, buffer, offset, countBuffer,
1362 countBufferOffset, maxDrawCount, stride);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001363 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, CMD_DRAWMESHTASKSINDIRECTCOUNTNV);
Tony-LunarG2fb8ff02020-06-11 12:45:07 -06001364}
1365
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001366void GpuAssisted::PreCallRecordCmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001367 ValidationStateTracker::PreCallRecordCmdDispatch(commandBuffer, x, y, z);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001368 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCH);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001369}
1370
1371void GpuAssisted::PreCallRecordCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001372 ValidationStateTracker::PreCallRecordCmdDispatchIndirect(commandBuffer, buffer, offset);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001373 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHINDIRECT);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001374}
1375
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001376void GpuAssisted::PreCallRecordCmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1377 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1378 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001379 ValidationStateTracker::PreCallRecordCmdDispatchBase(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1380 groupCountY, groupCountZ);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001381 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASE);
Tony-LunarGd13f9b52020-09-08 15:45:45 -06001382}
1383
Tony-LunarG52c8c602020-09-10 16:29:56 -06001384void GpuAssisted::PreCallRecordCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY,
1385 uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY,
1386 uint32_t groupCountZ) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001387 ValidationStateTracker::PreCallRecordCmdDispatchBaseKHR(commandBuffer, baseGroupX, baseGroupY, baseGroupZ, groupCountX,
1388 groupCountY, groupCountZ);
sfricke-samsung85584a72021-09-30 21:43:38 -07001389 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, CMD_DISPATCHBASEKHR);
Tony-LunarG52c8c602020-09-10 16:29:56 -06001390}
1391
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001392void GpuAssisted::PreCallRecordCmdTraceRaysNV(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer,
1393 VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer,
1394 VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride,
1395 VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset,
1396 VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer,
1397 VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride,
1398 uint32_t width, uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001399 ValidationStateTracker::PreCallRecordCmdTraceRaysNV(
1400 commandBuffer, raygenShaderBindingTableBuffer, raygenShaderBindingOffset, missShaderBindingTableBuffer,
1401 missShaderBindingOffset, missShaderBindingStride, hitShaderBindingTableBuffer, hitShaderBindingOffset,
1402 hitShaderBindingStride, callableShaderBindingTableBuffer, callableShaderBindingOffset, callableShaderBindingStride, width,
1403 height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001404 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_NV, CMD_TRACERAYSNV);
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001405}
1406
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001407void GpuAssisted::PreCallRecordCmdTraceRaysKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001408 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1409 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1410 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1411 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable, uint32_t width,
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001412 uint32_t height, uint32_t depth) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001413 ValidationStateTracker::PreCallRecordCmdTraceRaysKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1414 pHitShaderBindingTable, pCallableShaderBindingTable, width, height, depth);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001415 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001416}
1417
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001418
1419void GpuAssisted::PreCallRecordCmdTraceRaysIndirectKHR(VkCommandBuffer commandBuffer,
sourav parmarcd5fb182020-07-17 12:58:44 -07001420 const VkStridedDeviceAddressRegionKHR *pRaygenShaderBindingTable,
1421 const VkStridedDeviceAddressRegionKHR *pMissShaderBindingTable,
1422 const VkStridedDeviceAddressRegionKHR *pHitShaderBindingTable,
1423 const VkStridedDeviceAddressRegionKHR *pCallableShaderBindingTable,
Shannon McPherson54e1f892020-11-27 11:04:19 -07001424 VkDeviceAddress indirectDeviceAddress) {
Tony-LunarG9dc7d4a2021-11-04 13:25:59 -06001425 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirectKHR(commandBuffer, pRaygenShaderBindingTable, pMissShaderBindingTable,
1426 pHitShaderBindingTable, pCallableShaderBindingTable,
1427 indirectDeviceAddress);
Tony-LunarG7de10e82020-11-24 11:31:55 -07001428 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECTKHR);
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001429}
1430
sfricke-samsungf91881c2022-03-31 01:12:00 -05001431void GpuAssisted::PreCallRecordCmdTraceRaysIndirect2KHR(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress) {
1432 ValidationStateTracker::PreCallRecordCmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress);
1433 AllocateValidationResources(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, CMD_TRACERAYSINDIRECT2KHR);
1434}
1435
sjfricke43b340c2022-08-04 22:18:38 +09001436// This function will add the returned VkPipeline handle to another object incharge of destroying it. Caller does NOT have to
1437// destroy it
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001438VkPipeline GpuAssisted::GetValidationPipeline(VkRenderPass render_pass) {
1439 VkPipeline pipeline = VK_NULL_HANDLE;
1440 //NOTE: for dynamic rendering, render_pass will be VK_NULL_HANDLE but we'll use that as a map
1441 //key anyways;
1442 auto pipeentry = pre_draw_validation_state.renderpass_to_pipeline.find(render_pass);
1443 if (pipeentry != pre_draw_validation_state.renderpass_to_pipeline.end()) {
1444 pipeline = pipeentry->second;
1445 }
1446 if (pipeline != VK_NULL_HANDLE) {
1447 return pipeline;
1448 }
1449 auto pipeline_stage_ci = LvlInitStruct<VkPipelineShaderStageCreateInfo>();
1450 pipeline_stage_ci.stage = VK_SHADER_STAGE_VERTEX_BIT;
sjfricke43b340c2022-08-04 22:18:38 +09001451 pipeline_stage_ci.module = pre_draw_validation_state.shader_module;
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001452 pipeline_stage_ci.pName = "main";
1453
sjfricke43b340c2022-08-04 22:18:38 +09001454 auto pipeline_ci = LvlInitStruct<VkGraphicsPipelineCreateInfo>();
1455 auto vertex_input_state = LvlInitStruct<VkPipelineVertexInputStateCreateInfo>();
1456 auto input_assembly_state = LvlInitStruct<VkPipelineInputAssemblyStateCreateInfo>();
1457 input_assembly_state.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1458 auto rasterization_state = LvlInitStruct<VkPipelineRasterizationStateCreateInfo>();
1459 rasterization_state.rasterizerDiscardEnable = VK_TRUE;
1460 auto color_blend_state = LvlInitStruct<VkPipelineColorBlendStateCreateInfo>();
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001461
sjfricke43b340c2022-08-04 22:18:38 +09001462 pipeline_ci.pVertexInputState = &vertex_input_state;
1463 pipeline_ci.pInputAssemblyState = &input_assembly_state;
1464 pipeline_ci.pRasterizationState = &rasterization_state;
1465 pipeline_ci.pColorBlendState = &color_blend_state;
1466 pipeline_ci.renderPass = render_pass;
1467 pipeline_ci.layout = pre_draw_validation_state.pipeline_layout;
1468 pipeline_ci.stageCount = 1;
1469 pipeline_ci.pStages = &pipeline_stage_ci;
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001470
sjfricke43b340c2022-08-04 22:18:38 +09001471 VkResult result = DispatchCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_ci, nullptr, &pipeline);
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001472 if (result != VK_SUCCESS) {
1473 ReportSetupProblem(device, "Unable to create graphics pipeline. Aborting GPU-AV");
1474 aborted = true;
1475 return VK_NULL_HANDLE;
1476 }
1477
1478 pre_draw_validation_state.renderpass_to_pipeline.insert(render_pass, pipeline);
1479 return pipeline;
1480}
Jeff Bolz443c2ca2020-03-19 12:11:51 -05001481
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001482void GpuAssisted::AllocatePreDrawValidationResources(GpuAssistedDeviceMemoryBlock output_block,
1483 GpuAssistedPreDrawResources &resources, const LAST_BOUND_STATE &state,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001484 VkPipeline *pPipeline, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001485 VkResult result;
1486 if (!pre_draw_validation_state.globals_created) {
1487 auto shader_module_ci = LvlInitStruct<VkShaderModuleCreateInfo>();
sjfrickebecf0722022-08-05 16:15:46 +09001488 shader_module_ci.codeSize = sizeof(gpu_pre_draw_vert);
1489 shader_module_ci.pCode = gpu_pre_draw_vert;
sjfricke43b340c2022-08-04 22:18:38 +09001490 result = DispatchCreateShaderModule(device, &shader_module_ci, nullptr, &pre_draw_validation_state.shader_module);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001491 if (result != VK_SUCCESS) {
1492 ReportSetupProblem(device, "Unable to create shader module. Aborting GPU-AV");
1493 aborted = true;
1494 return;
1495 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001496
sjfricke43b340c2022-08-04 22:18:38 +09001497 std::vector<VkDescriptorSetLayoutBinding> bindings = {
1498 {0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, // output buffer
1499 {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT, nullptr}, // count/draws buffer
1500 };
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001501
sjfrickee9b39372022-05-22 13:02:17 +09001502 VkDescriptorSetLayoutCreateInfo ds_layout_ci = LvlInitStruct<VkDescriptorSetLayoutCreateInfo>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001503 ds_layout_ci.bindingCount = static_cast<uint32_t>(bindings.size());
1504 ds_layout_ci.pBindings = bindings.data();
sjfricke43b340c2022-08-04 22:18:38 +09001505 result = DispatchCreateDescriptorSetLayout(device, &ds_layout_ci, nullptr, &pre_draw_validation_state.ds_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001506 if (result != VK_SUCCESS) {
1507 ReportSetupProblem(device, "Unable to create descriptor set layout. Aborting GPU-AV");
1508 aborted = true;
1509 return;
1510 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001511
sjfricke43b340c2022-08-04 22:18:38 +09001512 VkPushConstantRange push_constant_range = {};
1513 push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
1514 push_constant_range.offset = 0;
1515 push_constant_range.size = resources.push_constant_words * sizeof(uint32_t);
1516 VkPipelineLayoutCreateInfo pipeline_layout_ci = LvlInitStruct<VkPipelineLayoutCreateInfo>();
1517 pipeline_layout_ci.pushConstantRangeCount = 1;
1518 pipeline_layout_ci.pPushConstantRanges = &push_constant_range;
1519 pipeline_layout_ci.setLayoutCount = 1;
1520 pipeline_layout_ci.pSetLayouts = &pre_draw_validation_state.ds_layout;
1521 result = DispatchCreatePipelineLayout(device, &pipeline_layout_ci, nullptr, &pre_draw_validation_state.pipeline_layout);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001522 if (result != VK_SUCCESS) {
1523 ReportSetupProblem(device, "Unable to create pipeline layout. Aborting GPU-AV");
1524 aborted = true;
1525 return;
1526 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001527
1528 pre_draw_validation_state.globals_created = true;
1529 }
Tony-LunarG463bae32022-02-25 09:31:17 -07001530
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001531 VkRenderPass render_pass = state.pipeline_state->RenderPassState()->renderPass();
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001532 *pPipeline = GetValidationPipeline(render_pass);
1533 if (*pPipeline == VK_NULL_HANDLE) {
sjfricke43b340c2022-08-04 22:18:38 +09001534 ReportSetupProblem(device, "Could not find or create a pipeline. Aborting GPU-AV");
1535 aborted = true;
Jeremy Gebbenbba39212022-03-29 16:39:06 -06001536 return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001537 }
1538
sjfricke43b340c2022-08-04 22:18:38 +09001539 result = desc_set_manager->GetDescriptorSet(&resources.desc_pool, pre_draw_validation_state.ds_layout, &resources.desc_set);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001540 if (result != VK_SUCCESS) {
1541 ReportSetupProblem(device, "Unable to allocate descriptor set. Aborting GPU-AV");
1542 aborted = true;
1543 return;
1544 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001545
sjfricke43b340c2022-08-04 22:18:38 +09001546 const uint32_t buffer_count = 2;
1547 VkDescriptorBufferInfo buffer_infos[buffer_count] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001548 // Error output buffer
1549 buffer_infos[0].buffer = output_block.buffer;
1550 buffer_infos[0].offset = 0;
1551 buffer_infos[0].range = VK_WHOLE_SIZE;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001552 if (cdi_state->count_buffer) {
1553 // Count buffer
1554 buffer_infos[1].buffer = cdi_state->count_buffer;
1555 } else {
1556 // Draw Buffer
1557 buffer_infos[1].buffer = cdi_state->buffer;
1558 }
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001559 buffer_infos[1].offset = 0;
1560 buffer_infos[1].range = VK_WHOLE_SIZE;
1561
sjfricke43b340c2022-08-04 22:18:38 +09001562 VkWriteDescriptorSet desc_writes[buffer_count] = {};
1563 for (uint32_t i = 0; i < buffer_count; i++) {
sjfrickee9b39372022-05-22 13:02:17 +09001564 desc_writes[i] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001565 desc_writes[i].dstBinding = i;
1566 desc_writes[i].descriptorCount = 1;
1567 desc_writes[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1568 desc_writes[i].pBufferInfo = &buffer_infos[i];
1569 desc_writes[i].dstSet = resources.desc_set;
1570 }
sjfricke43b340c2022-08-04 22:18:38 +09001571 DispatchUpdateDescriptorSets(device, buffer_count, desc_writes, 0, NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001572}
1573
Tony-LunarG7de10e82020-11-24 11:31:55 -07001574void GpuAssisted::AllocateValidationResources(const VkCommandBuffer cmd_buffer, const VkPipelineBindPoint bind_point,
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001575 CMD_TYPE cmd_type, const GpuAssistedCmdDrawIndirectState *cdi_state) {
Jason Macnak67407e72019-07-11 11:05:09 -07001576 if (bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS && bind_point != VK_PIPELINE_BIND_POINT_COMPUTE &&
sjfricke62366d32022-08-01 21:04:10 +09001577 bind_point != VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) {
andreygca287f22019-04-10 00:15:33 +03001578 return;
1579 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001580 VkResult result;
1581
Tony-LunarG99b880b2019-09-26 11:19:52 -06001582 if (aborted) return;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001583
Jeremy Gebben04697b02022-03-23 16:18:12 -06001584 auto cb_node = GetWrite<gpuav_state::CommandBuffer>(cmd_buffer);
Nathaniel Cesariobcb79682022-03-31 21:13:52 -06001585 if (!cb_node) {
1586 ReportSetupProblem(device, "Unrecognized command buffer");
1587 aborted = true;
1588 return;
1589 }
1590 const auto lv_bind_point = ConvertToLvlBindPoint(bind_point);
1591 auto const &state = cb_node->lastBound[lv_bind_point];
1592 const auto *pipeline_state = state.pipeline_state;
1593
1594 // TODO (ncesario) remove once VK_EXT_graphics_pipeline_library support is added for GPU-AV
1595 if (pipeline_state->IsGraphicsLibrary()) {
1596 ReportSetupProblem(device, "GPU-AV does not currently support VK_EXT_graphics_pipeline_library");
1597 aborted = true;
1598 return;
1599 }
1600
Tony-LunarGb2501d22019-01-28 09:59:13 -07001601 std::vector<VkDescriptorSet> desc_sets;
1602 VkDescriptorPool desc_pool = VK_NULL_HANDLE;
Tony-LunarG1dce2392019-10-23 16:49:29 -06001603 result = desc_set_manager->GetDescriptorSets(1, &desc_pool, debug_desc_layout, &desc_sets);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001604 assert(result == VK_SUCCESS);
1605 if (result != VK_SUCCESS) {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001606 ReportSetupProblem(device, "Unable to allocate descriptor sets. Device could become unstable.");
Tony-LunarG99b880b2019-09-26 11:19:52 -06001607 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001608 return;
1609 }
1610
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001611 VkDescriptorBufferInfo output_desc_buffer_info = {};
Tony-LunarG99b880b2019-09-26 11:19:52 -06001612 output_desc_buffer_info.range = output_buffer_size;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001613
Tony-LunarG81efe392019-03-07 15:43:27 -07001614 // Allocate memory for the output block that the gpu will use to return any error information
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001615 GpuAssistedDeviceMemoryBlock output_block = {};
sjfrickee9b39372022-05-22 13:02:17 +09001616 VkBufferCreateInfo buffer_info = LvlInitStruct<VkBufferCreateInfo>();
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001617 buffer_info.size = output_buffer_size;
1618 buffer_info.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
1619 VmaAllocationCreateInfo alloc_info = {};
Tony-LunarGef497962022-04-19 08:48:52 -06001620 alloc_info.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001621 alloc_info.pool = output_buffer_pool;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001622 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &output_block.buffer, &output_block.allocation, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001623 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001624 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001625 aborted = true;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001626 return;
1627 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001628
Tony-LunarG81efe392019-03-07 15:43:27 -07001629 // Clear the output block to zeros so that only error information from the gpu will be present
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001630 uint32_t *data_ptr;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001631 result = vmaMapMemory(vmaAllocator, output_block.allocation, reinterpret_cast<void **>(&data_ptr));
Tony-LunarG0e564722019-03-19 16:09:14 -06001632 if (result == VK_SUCCESS) {
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001633 memset(data_ptr, 0, output_buffer_size);
Tony-LunarG99b880b2019-09-26 11:19:52 -06001634 vmaUnmapMemory(vmaAllocator, output_block.allocation);
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001635 }
Tony-LunarG81efe392019-03-07 15:43:27 -07001636
Tony-LunarG2ba1cb32019-09-25 15:16:11 -06001637 GpuAssistedDeviceMemoryBlock di_input_block = {}, bda_input_block = {};
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001638 VkDescriptorBufferInfo di_input_desc_buffer_info = {};
1639 VkDescriptorBufferInfo bda_input_desc_buffer_info = {};
1640 VkWriteDescriptorSet desc_writes[3] = {};
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001641 GpuAssistedPreDrawResources pre_draw_resources = {};
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001642 uint32_t desc_count = 1;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001643 uint32_t number_of_sets = static_cast<uint32_t>(state.per_set.size());
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001644
sfricke-samsung85584a72021-09-30 21:43:38 -07001645 if (validate_draw_indirect && ((cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR ||
1646 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) ||
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001647 ((cmd_type == CMD_DRAWINDIRECT || cmd_type == CMD_DRAWINDEXEDINDIRECT) &&
1648 !(enabled_features.core.drawIndirectFirstInstance)))) {
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001649 // Insert a draw that can examine some device memory right before the draw we're validating (Pre Draw Validation)
Tony-LunarG20678ff2021-05-07 14:56:26 -06001650 //
1651 // NOTE that this validation does not attempt to abort invalid api calls as most other validation does. A crash
1652 // or DEVICE_LOST resulting from the invalid call will prevent preceeding validation errors from being reported.
1653
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001654 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001655 assert(cdi_state != NULL);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001656 VkPipeline validation_pipeline;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001657 AllocatePreDrawValidationResources(output_block, pre_draw_resources, state, &validation_pipeline, cdi_state);
Tony-LunarG2c6d57f2021-04-13 10:07:15 -06001658 if (aborted) return;
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001659
1660 // Save current graphics pipeline state
1661 GPUAV_RESTORABLE_PIPELINE_STATE restorable_state;
Jeremy Gebben9f537102021-10-05 16:37:12 -06001662 restorable_state.Create(cb_node.get(), VK_PIPELINE_BIND_POINT_GRAPHICS);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001663
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001664 // Save parameters for error message
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001665 pre_draw_resources.buffer = cdi_state->buffer;
1666 pre_draw_resources.offset = cdi_state->offset;
1667 pre_draw_resources.stride = cdi_state->stride;
1668
sjfricke43b340c2022-08-04 22:18:38 +09001669 uint32_t push_constants[pre_draw_resources.push_constant_words] = {};
sfricke-samsung85584a72021-09-30 21:43:38 -07001670 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT ||
1671 cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR) {
sjfricke43b340c2022-08-04 22:18:38 +09001672 // Validate count buffer
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001673 if (cdi_state->count_buffer_offset > std::numeric_limits<uint32_t>::max()) {
1674 ReportSetupProblem(device,
1675 "Count buffer offset is larger than can be contained in an unsigned int. Aborting GPU-AV");
1676 aborted = true;
1677 return;
1678 }
1679
1680 // Buffer size must be >= (stride * (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand))
1681 uint32_t struct_size;
sfricke-samsung85584a72021-09-30 21:43:38 -07001682 if (cmd_type == CMD_DRAWINDIRECTCOUNT || cmd_type == CMD_DRAWINDIRECTCOUNTKHR) {
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001683 struct_size = sizeof(VkDrawIndirectCommand);
1684 } else {
sfricke-samsung85584a72021-09-30 21:43:38 -07001685 assert(cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNT || cmd_type == CMD_DRAWINDEXEDINDIRECTCOUNTKHR);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001686 struct_size = sizeof(VkDrawIndexedIndirectCommand);
1687 }
Jeremy Gebbenb20a8242021-11-05 15:14:43 -06001688 auto buffer_state = Get<BUFFER_STATE>(cdi_state->buffer);
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001689 uint32_t max_count;
1690 uint64_t bufsize = buffer_state->createInfo.size;
1691 uint64_t first_command_bytes = struct_size + cdi_state->offset;
1692 if (first_command_bytes > bufsize) {
1693 max_count = 0;
1694 } else {
1695 max_count = 1 + static_cast<uint32_t>(std::floor(((bufsize - first_command_bytes) / cdi_state->stride)));
1696 }
1697 pre_draw_resources.buf_size = buffer_state->createInfo.size;
1698
1699 assert(phys_dev_props.limits.maxDrawIndirectCount > 0);
sjfricke43b340c2022-08-04 22:18:38 +09001700 push_constants[0] = phys_dev_props.limits.maxDrawIndirectCount;
1701 push_constants[1] = max_count;
1702 push_constants[2] = static_cast<uint32_t>((cdi_state->count_buffer_offset / sizeof(uint32_t)));
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001703 } else {
sjfricke43b340c2022-08-04 22:18:38 +09001704 // Validate buffer for firstInstance check instead of count buffer check
1705 push_constants[0] = 0;
1706 push_constants[1] = cdi_state->draw_count;
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001707 if (cmd_type == CMD_DRAWINDIRECT) {
sjfricke43b340c2022-08-04 22:18:38 +09001708 push_constants[2] = static_cast<uint32_t>(
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001709 ((cdi_state->offset + offsetof(struct VkDrawIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1710 } else {
1711 assert(cmd_type == CMD_DRAWINDEXEDINDIRECT);
sjfricke43b340c2022-08-04 22:18:38 +09001712 push_constants[2] = static_cast<uint32_t>(
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001713 ((cdi_state->offset + offsetof(struct VkDrawIndexedIndirectCommand, firstInstance)) / sizeof(uint32_t)));
1714 }
sjfricke43b340c2022-08-04 22:18:38 +09001715 push_constants[3] = (cdi_state->stride / sizeof(uint32_t));
Tony-LunarG3723a3a2021-05-04 14:52:39 -06001716 }
Tony-LunarGf0d4e2b2021-04-14 11:52:28 -06001717
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001718 // Insert diagnostic draw
1719 DispatchCmdBindPipeline(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, validation_pipeline);
sjfricke43b340c2022-08-04 22:18:38 +09001720 DispatchCmdPushConstants(cmd_buffer, pre_draw_validation_state.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
1721 sizeof(push_constants), push_constants);
1722 DispatchCmdBindDescriptorSets(cmd_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pre_draw_validation_state.pipeline_layout, 0, 1,
1723 &pre_draw_resources.desc_set, 0, nullptr);
Tony-LunarGa3ec16c2021-04-06 12:19:57 -06001724 DispatchCmdDraw(cmd_buffer, 3, 1, 0, 0);
1725
1726 // Restore the previous graphics pipeline state.
1727 restorable_state.Restore(cmd_buffer);
1728 }
1729
Tony-LunarGe29097a2020-12-03 10:59:19 -07001730 bool has_buffers = false;
Tony-LunarG81efe392019-03-07 15:43:27 -07001731 // Figure out how much memory we need for the input block based on how many sets and bindings there are
1732 // and how big each of the bindings is
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001733 if (number_of_sets > 0 && (descriptor_indexing || buffer_oob_enabled)) {
Tony-LunarG81efe392019-03-07 15:43:27 -07001734 uint32_t descriptor_count = 0; // Number of descriptors, including all array elements
1735 uint32_t binding_count = 0; // Number of bindings based on the max binding number used
John Zulauf79f06582021-02-27 18:38:39 -07001736 for (const auto &s : state.per_set) {
Jeff Bolzb1fc0732019-08-11 20:16:49 -05001737 auto desc = s.bound_descriptor_set;
Tony-LunarGd9224b12019-09-11 11:43:04 -06001738 if (desc && (desc->GetBindingCount() > 0)) {
Tony-LunarGa77cade2019-03-06 10:49:22 -07001739 binding_count += desc->GetLayout()->GetMaxBinding() + 1;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001740 for (const auto &binding : *desc) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001741 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline uniform
1742 // blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001743 if (binding->type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
Tony-LunarG7564b382019-08-21 10:11:35 -06001744 descriptor_count++;
Mark Lobodzinskiafa7cb82020-01-29 16:49:36 -07001745 LogWarning(device, "UNASSIGNED-GPU-Assisted Validation Warning",
1746 "VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT descriptors will not be validated by GPU assisted "
1747 "validation");
Tony-LunarGa77cade2019-03-06 10:49:22 -07001748 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001749 descriptor_count += binding->count;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001750 }
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001751 if (!has_buffers && (binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
1752 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC ||
1753 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
1754 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
1755 binding->type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
1756 binding->type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001757 has_buffers = true;
Tony-LunarGa77cade2019-03-06 10:49:22 -07001758 }
Tony-LunarGc28e28a2020-08-14 10:37:48 -06001759 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001760 }
1761 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001762
Tony-LunarGe29097a2020-12-03 10:59:19 -07001763 if (descriptor_indexing || has_buffers) {
1764 // Note that the size of the input buffer is dependent on the maximum binding number, which
1765 // can be very large. This is because for (set = s, binding = b, index = i), the validation
1766 // code is going to dereference Input[ i + Input[ b + Input[ s + Input[ Input[0] ] ] ] ] to
1767 // see if descriptors have been written. In gpu_validation.md, we note this and advise
1768 // using densely packed bindings as a best practice when using gpu-av with descriptor indexing
1769 uint32_t words_needed;
1770 if (descriptor_indexing) {
1771 words_needed = 1 + (number_of_sets * 2) + (binding_count * 2) + descriptor_count;
1772 } else {
1773 words_needed = 1 + number_of_sets + binding_count + descriptor_count;
1774 }
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001775 buffer_info.size = words_needed * 4;
Tony-LunarG20d18a72022-04-19 11:01:47 -06001776 alloc_info.pool = VK_NULL_HANDLE;
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001777 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &di_input_block.buffer, &di_input_block.allocation,
1778 nullptr);
Tony-LunarGe29097a2020-12-03 10:59:19 -07001779 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001780 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Tony-LunarGe29097a2020-12-03 10:59:19 -07001781 aborted = true;
1782 return;
1783 }
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001784
Tony-LunarGe29097a2020-12-03 10:59:19 -07001785 // Populate input buffer first with the sizes of every descriptor in every set, then with whether
1786 // each element of each descriptor has been written or not. See gpu_validation.md for a more thourough
1787 // outline of the input buffer format
Nathaniel Cesarioce9b4812020-12-17 08:55:28 -07001788 result = vmaMapMemory(vmaAllocator, di_input_block.allocation, reinterpret_cast<void **>(&data_ptr));
1789 memset(data_ptr, 0, static_cast<size_t>(buffer_info.size));
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001790
Tony-LunarGe29097a2020-12-03 10:59:19 -07001791 // Descriptor indexing needs the number of descriptors at each binding.
1792 if (descriptor_indexing) {
1793 // Pointer to a sets array that points into the sizes array
1794 uint32_t *sets_to_sizes = data_ptr + 1;
1795 // Pointer to the sizes array that contains the array size of the descriptor at each binding
1796 uint32_t *sizes = sets_to_sizes + number_of_sets;
1797 // Pointer to another sets array that points into the bindings array that points into the written array
1798 uint32_t *sets_to_bindings = sizes + binding_count;
1799 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1800 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1801 // Index of the next entry in the written array to be updated
1802 uint32_t written_index = 1 + (number_of_sets * 2) + (binding_count * 2);
1803 uint32_t bind_counter = number_of_sets + 1;
1804 // Index of the start of the sets_to_bindings array
1805 data_ptr[0] = number_of_sets + binding_count + 1;
1806
John Zulauf79f06582021-02-27 18:38:39 -07001807 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001808 auto desc = s.bound_descriptor_set;
1809 if (desc && (desc->GetBindingCount() > 0)) {
1810 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07001811 // For each set, fill in index of its bindings sizes in the sizes array
1812 *sets_to_sizes++ = bind_counter;
1813 // For each set, fill in the index of its bindings in the bindings_to_written array
1814 *sets_to_bindings++ = bind_counter + number_of_sets + binding_count;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001815 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001816 // For each binding, fill in its size in the sizes array
1817 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1818 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001819 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
1820 sizes[binding->binding] = 1;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001821 } else {
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001822 sizes[binding->binding] = binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001823 }
1824 // Fill in the starting index for this binding in the written array in the bindings_to_written array
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001825 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001826
1827 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1828 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001829 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001830 data_ptr[written_index++] = UINT_MAX;
1831 continue;
1832 }
1833
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001834 if ((binding->binding_flags & VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT) != 0) {
1835 di_input_block.update_at_submit[written_index] = binding.get();
1836 } else {
1837 SetBindingState(data_ptr, written_index, binding.get());
Tony-LunarGe29097a2020-12-03 10:59:19 -07001838 }
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001839 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001840 }
1841 auto last = desc->GetLayout()->GetMaxBinding();
1842 bindings_to_written += last + 1;
1843 bind_counter += last + 1;
1844 sizes += last + 1;
1845 } else {
1846 *sets_to_sizes++ = 0;
1847 *sets_to_bindings++ = 0;
1848 }
1849 }
1850 } else {
1851 // If no descriptor indexing, we don't need number of descriptors at each binding, so
1852 // no sets_to_sizes or sizes arrays, just sets_to_bindings, bindings_to_written and written_index
1853
1854 // Pointer to sets array that points into the bindings array that points into the written array
1855 uint32_t *sets_to_bindings = data_ptr + 1;
1856 // Pointer to the bindings array that points at the start of the writes in the writes array for each binding
1857 uint32_t *bindings_to_written = sets_to_bindings + number_of_sets;
1858 // Index of the next entry in the written array to be updated
1859 uint32_t written_index = 1 + number_of_sets + binding_count;
1860 uint32_t bind_counter = number_of_sets + 1;
1861 data_ptr[0] = 1;
1862
John Zulauf79f06582021-02-27 18:38:39 -07001863 for (const auto &s : state.per_set) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001864 auto desc = s.bound_descriptor_set;
1865 if (desc && (desc->GetBindingCount() > 0)) {
1866 auto layout = desc->GetLayout();
Tony-LunarGe29097a2020-12-03 10:59:19 -07001867 *sets_to_bindings++ = bind_counter;
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001868 for (auto &binding : *desc) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001869 // Fill in the starting index for this binding in the written array in the bindings_to_written array
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001870 bindings_to_written[binding->binding] = written_index;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001871
1872 // Shader instrumentation is tracking inline uniform blocks as scalers. Don't try to validate inline
1873 // uniform blocks
Jeremy Gebben1b9fdb82022-06-15 15:31:32 -06001874 if (VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT == binding->type) {
Tony-LunarGe29097a2020-12-03 10:59:19 -07001875 data_ptr[written_index++] = UINT_MAX;
1876 continue;
1877 }
1878
Jeremy Gebbenf4816f72022-07-15 08:56:06 -06001879 // note that VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT is part of descriptor indexing
1880 SetBindingState(data_ptr, written_index, binding.get());
1881 written_index += binding->count;
Tony-LunarGe29097a2020-12-03 10:59:19 -07001882 }
1883 auto last = desc->GetLayout()->GetMaxBinding();
1884 bindings_to_written += last + 1;
1885 bind_counter += last + 1;
1886 } else {
1887 *sets_to_bindings++ = 0;
1888 }
1889 }
1890 }
1891 vmaUnmapMemory(vmaAllocator, di_input_block.allocation);
1892
1893 di_input_desc_buffer_info.range = (words_needed * 4);
1894 di_input_desc_buffer_info.buffer = di_input_block.buffer;
1895 di_input_desc_buffer_info.offset = 0;
1896
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06001897 desc_writes[1] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarGe29097a2020-12-03 10:59:19 -07001898 desc_writes[1].dstBinding = 1;
1899 desc_writes[1].descriptorCount = 1;
1900 desc_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1901 desc_writes[1].pBufferInfo = &di_input_desc_buffer_info;
1902 desc_writes[1].dstSet = desc_sets[0];
1903
1904 desc_count = 2;
1905 }
Tony-LunarG0e564722019-03-19 16:09:14 -06001906 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001907
sfricke-samsung45996a42021-09-16 13:45:27 -07001908 if ((IsExtEnabled(device_extensions.vk_ext_buffer_device_address) ||
1909 IsExtEnabled(device_extensions.vk_khr_buffer_device_address)) &&
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06001910 shaderInt64 && enabled_features.core12.bufferDeviceAddress) {
1911 auto address_ranges = GetBufferAddressRanges();
1912 if (address_ranges.size() > 0) {
1913 // Example BDA input buffer assuming 2 buffers using BDA:
1914 // Word 0 | Index of start of buffer sizes (in this case 5)
1915 // Word 1 | 0x0000000000000000
1916 // Word 2 | Device Address of first buffer (Addresses sorted in ascending order)
1917 // Word 3 | Device Address of second buffer
1918 // Word 4 | 0xffffffffffffffff
1919 // Word 5 | 0 (size of pretend buffer at word 1)
1920 // Word 6 | Size in bytes of first buffer
1921 // Word 7 | Size in bytes of second buffer
1922 // Word 8 | 0 (size of pretend buffer in word 4)
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001923
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06001924 uint32_t num_buffers = static_cast<uint32_t>(address_ranges.size());
1925 uint32_t words_needed = (num_buffers + 3) + (num_buffers + 2);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06001926 buffer_info.size = words_needed * 8; // 64 bit words
Tony-LunarG20d18a72022-04-19 11:01:47 -06001927 alloc_info.pool = VK_NULL_HANDLE;
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06001928 result = vmaCreateBuffer(vmaAllocator, &buffer_info, &alloc_info, &bda_input_block.buffer, &bda_input_block.allocation,
1929 nullptr);
1930 if (result != VK_SUCCESS) {
Tony-LunarGa2aa78b2022-04-19 08:41:38 -06001931 ReportSetupProblem(device, "Unable to allocate device memory. Device could become unstable.", true);
Jeremy Gebbenb0171bb2022-03-18 13:46:13 -06001932 aborted = true;
1933 return;
1934 }
1935 uint64_t *bda_data;
1936 result = vmaMapMemory(vmaAllocator, bda_input_block.allocation, reinterpret_cast<void **>(&bda_data));
1937 uint32_t address_index = 1;
1938 uint32_t size_index = 3 + num_buffers;
1939 memset(bda_data, 0, static_cast<size_t>(buffer_info.size));
1940 bda_data[0] = size_index; // Start of buffer sizes
1941 bda_data[address_index++] = 0; // NULL address
1942 bda_data[size_index++] = 0;
1943
1944 for (const auto &range : address_ranges) {
1945 bda_data[address_index++] = range.begin;
1946 bda_data[size_index++] = range.end - range.begin;
1947 }
1948 bda_data[address_index] = UINTPTR_MAX;
1949 bda_data[size_index] = 0;
1950 vmaUnmapMemory(vmaAllocator, bda_input_block.allocation);
1951
1952 bda_input_desc_buffer_info.range = (words_needed * 8);
1953 bda_input_desc_buffer_info.buffer = bda_input_block.buffer;
1954 bda_input_desc_buffer_info.offset = 0;
1955
1956 desc_writes[desc_count] = LvlInitStruct<VkWriteDescriptorSet>();
1957 desc_writes[desc_count].dstBinding = 2;
1958 desc_writes[desc_count].descriptorCount = 1;
1959 desc_writes[desc_count].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1960 desc_writes[desc_count].pBufferInfo = &bda_input_desc_buffer_info;
1961 desc_writes[desc_count].dstSet = desc_sets[0];
1962 desc_count++;
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001963 }
Tony-LunarG8eb5a002019-07-25 16:49:00 -06001964 }
1965
Tony-LunarGb2501d22019-01-28 09:59:13 -07001966 // Write the descriptor
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001967 output_desc_buffer_info.buffer = output_block.buffer;
1968 output_desc_buffer_info.offset = 0;
Tony-LunarGb2501d22019-01-28 09:59:13 -07001969
Nathaniel Cesariofc6291e2021-04-06 00:22:15 -06001970 desc_writes[0] = LvlInitStruct<VkWriteDescriptorSet>();
Tony-LunarG1b2e0c32019-02-07 17:13:27 -07001971 desc_writes[0].descriptorCount = 1;
1972 desc_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
1973 desc_writes[0].pBufferInfo = &output_desc_buffer_info;
1974 desc_writes[0].dstSet = desc_sets[0];
1975 DispatchUpdateDescriptorSets(device, desc_count, desc_writes, 0, NULL);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001976
locke-lunargb8d7a7a2020-10-25 16:01:52 -06001977 if (pipeline_state) {
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001978 const auto &pipeline_layout = pipeline_state->PipelineLayoutState();
1979 if ((pipeline_layout->set_layouts.size() <= desc_set_bind_index) && !pipeline_layout->Destroyed()) {
1980 DispatchCmdBindDescriptorSets(cmd_buffer, bind_point, pipeline_layout->layout(), desc_set_bind_index, 1,
Tony-LunarG99b880b2019-09-26 11:19:52 -06001981 desc_sets.data(), 0, nullptr);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001982 }
Nathaniel Cesario3fd4f762022-02-16 16:07:06 -07001983 if (pipeline_layout->Destroyed()) {
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001984 ReportSetupProblem(device, "Pipeline layout has been destroyed, aborting GPU-AV");
1985 aborted = true;
1986 } else {
1987 // Record buffer and memory info in CB state tracking
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06001988 cb_node->gpuav_buffer_list.emplace_back(output_block, di_input_block, bda_input_block, pre_draw_resources, desc_sets[0],
1989 desc_pool, bind_point, cmd_type);
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001990 }
Tony-LunarGb2501d22019-01-28 09:59:13 -07001991 } else {
Mark Lobodzinskia8151b02020-02-27 13:38:08 -07001992 ReportSetupProblem(device, "Unable to find pipeline state");
Tony-LunarG9de6e5f2020-06-22 13:02:48 -06001993 aborted = true;
1994 }
1995 if (aborted) {
Tony-LunarG99b880b2019-09-26 11:19:52 -06001996 vmaDestroyBuffer(vmaAllocator, di_input_block.buffer, di_input_block.allocation);
1997 vmaDestroyBuffer(vmaAllocator, bda_input_block.buffer, bda_input_block.allocation);
1998 vmaDestroyBuffer(vmaAllocator, output_block.buffer, output_block.allocation);
Tony-LunarGb2501d22019-01-28 09:59:13 -07001999 return;
2000 }
2001}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002002
2003std::shared_ptr<CMD_BUFFER_STATE> GpuAssisted::CreateCmdBufferState(VkCommandBuffer cb,
2004 const VkCommandBufferAllocateInfo *pCreateInfo,
Jeremy Gebbencd7fa282021-10-27 10:25:32 -06002005 const COMMAND_POOL_STATE *pool) {
Jeremy Gebben135550d2022-03-21 07:15:07 -06002006 return std::static_pointer_cast<CMD_BUFFER_STATE>(std::make_shared<gpuav_state::CommandBuffer>(this, cb, pCreateInfo, pool));
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002007}
2008
Jeremy Gebben135550d2022-03-21 07:15:07 -06002009gpuav_state::CommandBuffer::CommandBuffer(GpuAssisted *ga, VkCommandBuffer cb, const VkCommandBufferAllocateInfo *pCreateInfo,
2010 const COMMAND_POOL_STATE *pool)
Jeremy Gebben5ca80b32022-04-11 10:58:39 -06002011 : gpu_utils_state::CommandBuffer(ga, cb, pCreateInfo, pool) {}
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002012
Jeremy Gebben135550d2022-03-21 07:15:07 -06002013void gpuav_state::CommandBuffer::Reset() {
Jeremy Gebbenf6bb4bb2021-08-11 15:41:09 -06002014 CMD_BUFFER_STATE::Reset();
2015 auto gpuav = static_cast<GpuAssisted *>(dev_data);
2016 // Free the device memory and descriptor set(s) associated with a command buffer.
2017 if (gpuav->aborted) {
2018 return;
2019 }
2020 for (auto &buffer_info : gpuav_buffer_list) {
2021 gpuav->DestroyBuffer(buffer_info);
2022 }
2023 gpuav_buffer_list.clear();
2024
2025 for (auto &as_validation_buffer_info : as_validation_buffers) {
2026 gpuav->DestroyBuffer(as_validation_buffer_info);
2027 }
2028 as_validation_buffers.clear();
2029}