From 078b4fc6d672e054b1e46e2bad7c4b26acf8ab0e Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Thu, 10 Oct 2024 10:21:19 +0200 Subject: [PATCH 01/18] Add AccelerationStructure meta-commands on replay-side --- framework/decode/api_decoder.h | 18 +++-- framework/decode/metadata_consumer_base.h | 19 ++++- framework/decode/vulkan_decoder_base.cpp | 76 +++++++++++++++++++ framework/decode/vulkan_decoder_base.h | 6 ++ .../decode/vulkan_replay_consumer_base.cpp | 69 +++++++++++++++++ .../decode/vulkan_replay_consumer_base.h | 33 +++++--- 6 files changed, 204 insertions(+), 17 deletions(-) diff --git a/framework/decode/api_decoder.h b/framework/decode/api_decoder.h index 6fc22d846a..2a969209e3 100644 --- a/framework/decode/api_decoder.h +++ b/framework/decode/api_decoder.h @@ -186,19 +186,25 @@ class ApiDecoder std::vector& geometry_descs, const uint8_t* build_inputs_data) = 0; - virtual void DispatchGetDxgiAdapterInfo(const format::DxgiAdapterInfoCommandHeader& adapter_info_header){}; + virtual void DispatchGetDxgiAdapterInfo(const format::DxgiAdapterInfoCommandHeader& adapter_info_header) {}; - virtual void DispatchGetDx12RuntimeInfo(const format::Dx12RuntimeInfoCommandHeader& runtime_info_header){}; + virtual void DispatchGetDx12RuntimeInfo(const format::Dx12RuntimeInfoCommandHeader& runtime_info_header) {}; - virtual void SetCurrentBlockIndex(uint64_t block_index){}; + virtual void SetCurrentBlockIndex(uint64_t block_index) {}; - virtual void SetCurrentApiCallId(format::ApiCallId api_call_id){}; + virtual void SetCurrentApiCallId(format::ApiCallId api_call_id) {}; virtual void DispatchSetTlasToBlasDependencyCommand(format::HandleId tlas, - const std::vector& blases){}; + const std::vector& blases) {}; virtual void DispatchSetEnvironmentVariablesCommand(format::SetEnvironmentVariablesCommand& header, - const char* env_string){}; + const char* env_string) {}; + + virtual void DispatchVulkanAccelerationStructuresBuildMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) {}; + + virtual void DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) {}; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/decode/metadata_consumer_base.h b/framework/decode/metadata_consumer_base.h index c3d950414f..07760fac8f 100644 --- a/framework/decode/metadata_consumer_base.h +++ b/framework/decode/metadata_consumer_base.h @@ -26,6 +26,7 @@ #include "util/defines.h" #include "format/format.h" +#include "generated/generated_vulkan_struct_decoders.h" GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(decode) @@ -107,8 +108,24 @@ class MetadataConsumerBase virtual void SetCurrentBlockIndex(uint64_t block_index) {} + virtual void ProcessBuildVulkanAccelerationStructuresMetaCommand( + format::HandleId device_id, + uint32_t info_count, + StructPointerDecoder* geometry_infos, + StructPointerDecoder* range_infos, + std::vector>& instance_buffers_data) + {} + + virtual void ProcessCopyVulkanAccelerationStructuresMetaCommand( + format::HandleId device_id, StructPointerDecoder* copy_infos) + {} + + virtual void ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( + format::HandleId device_id, VkQueryType query_type, format::HandleId acceleration_structure_id) + {} + protected: - uint64_t block_index_; + uint64_t block_index_ = 0; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/decode/vulkan_decoder_base.cpp b/framework/decode/vulkan_decoder_base.cpp index 93f60b68b1..506d3a7640 100644 --- a/framework/decode/vulkan_decoder_base.cpp +++ b/framework/decode/vulkan_decoder_base.cpp @@ -568,5 +568,81 @@ void VulkanDecoderBase::SetCurrentBlockIndex(uint64_t block_index) } } +void VulkanDecoderBase::DispatchVulkanAccelerationStructuresBuildMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) +{ + + format::HandleId device_id; + StructPointerDecoder pInfos; + StructPointerDecoder ppRangeInfos; + + std::size_t bytes_read = ValueDecoder::DecodeHandleIdValue(parameter_buffer, buffer_size, &device_id); + bytes_read += pInfos.Decode(parameter_buffer + bytes_read, buffer_size - bytes_read); + bytes_read += ppRangeInfos.Decode(parameter_buffer + bytes_read, buffer_size - bytes_read); + + std::vector> instance_buffers; + if (bytes_read < buffer_size) + { + for (uint32_t i = 0; i < pInfos.GetLength(); ++i) + { + if (pInfos.GetPointer()[i].type != VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) + { + continue; + } + + uint32_t geometry_count = pInfos.GetPointer()[i].geometryCount; + for (uint32_t g = 0; g < geometry_count; ++g) + { + instance_buffers.emplace_back(ppRangeInfos.GetPointer()[g]->primitiveCount); + util::platform::MemoryCopy(instance_buffers.back().data(), + instance_buffers.back().size() * sizeof(VkAccelerationStructureInstanceKHR), + parameter_buffer + bytes_read, + instance_buffers.back().size() * sizeof(VkAccelerationStructureInstanceKHR)); + bytes_read += instance_buffers.back().size() * sizeof(VkAccelerationStructureInstanceKHR); + } + } + } + + for (auto consumer : consumers_) + { + consumer->ProcessBuildVulkanAccelerationStructuresMetaCommand( + device_id, pInfos.GetLength(), &pInfos, &ppRangeInfos, instance_buffers); + } +} + +void VulkanDecoderBase::DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) +{ + format::HandleId device_id; + StructPointerDecoder pInfos; + + std::size_t bytes_read = ValueDecoder::DecodeHandleIdValue(parameter_buffer, buffer_size, &device_id); + pInfos.Decode(parameter_buffer + bytes_read, buffer_size - bytes_read); + + for (auto consumer : consumers_) + { + consumer->ProcessCopyVulkanAccelerationStructuresMetaCommand(device_id, &pInfos); + } +} + +//void VulkanDecoderBase::DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, +// size_t buffer_size) +//{ +// format::HandleId device_id; +// VkQueryType query_type; +// format::HandleId acceleration_structure_id; +// +// std::size_t bytes_read = ValueDecoder::DecodeHandleIdValue(parameter_buffer, sizeof(format::HandleId), &device_id); +// bytes_read += ValueDecoder::DecodeEnumValue(parameter_buffer + bytes_read, sizeof(VkQueryType), &query_type); +// bytes_read += ValueDecoder::DecodeHandleIdValue( +// parameter_buffer + bytes_read, sizeof(format::HandleId), &acceleration_structure_id); +// +// for (auto consumer : consumers_) +// { +// consumer->ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( +// device_id, query_type, acceleration_structure_id); +// } +//} + GFXRECON_END_NAMESPACE(decode) GFXRECON_END_NAMESPACE(gfxrecon) diff --git a/framework/decode/vulkan_decoder_base.h b/framework/decode/vulkan_decoder_base.h index ddaa8bd2b8..7b4bbd8519 100644 --- a/framework/decode/vulkan_decoder_base.h +++ b/framework/decode/vulkan_decoder_base.h @@ -200,6 +200,12 @@ class VulkanDecoderBase : public ApiDecoder virtual void SetCurrentBlockIndex(uint64_t block_index) override; + void DispatchVulkanAccelerationStructuresBuildMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) override; + + void DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) override; + protected: const std::vector& GetConsumers() const { return consumers_; } diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index cad7059ce3..3a18f6d5fb 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -9363,6 +9363,75 @@ void VulkanReplayConsumerBase::Process_vkCreateRayTracingPipelinesKHR( } } +void VulkanReplayConsumerBase::ProcessCopyVulkanAccelerationStructuresMetaCommand( + format::HandleId device, StructPointerDecoder* copy_infos) +{ + DeviceInfo* device_info = GetObjectInfoTable().GetDeviceInfo(device); + GFXRECON_ASSERT(device_info != nullptr); + + auto allocator = device_info->allocator.get(); + GFXRECON_ASSERT(allocator != nullptr); + + if (allocator->SupportsOpaqueDeviceAddresses() || !loading_trim_state_) + { + return; + } + + MapStructArrayHandles(copy_infos->GetMetaStructPointer(), copy_infos->GetLength(), GetObjectInfoTable()); + + // TODO: implement + // acceleration_structure_builders_[device]->ProcessCopyVulkanAccelerationStructuresMetaCommand( + // copy_infos->GetLength(), copy_infos->GetPointer()); +} + +void VulkanReplayConsumerBase::ProcessBuildVulkanAccelerationStructuresMetaCommand( + format::HandleId device, + uint32_t info_count, + StructPointerDecoder* pInfos, + StructPointerDecoder* ppRangeInfos, + std::vector>& instance_buffers_data) +{ + DeviceInfo* device_info = GetObjectInfoTable().GetDeviceInfo(device); + GFXRECON_ASSERT(device_info != nullptr); + + auto allocator = device_info->allocator.get(); + GFXRECON_ASSERT(allocator != nullptr); + + // TODO: really questioning "SupportsOpaqueDeviceAddresses" condition + if (allocator->SupportsOpaqueDeviceAddresses() || !loading_trim_state_) + { + return; + } + + MapStructArrayHandles(pInfos->GetMetaStructPointer(), pInfos->GetLength(), GetObjectInfoTable()); + + // TODO: implement + // acceleration_structure_builders_[device]->ProcessBuildVulkanAccelerationStructuresMetaCommand( + // info_count, pInfos->GetPointer(), ppRangeInfos->GetPointer(), instance_buffers_data); +} + +void VulkanReplayConsumerBase::ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( + format::HandleId device_id, VkQueryType query_type, format::HandleId acceleration_structure_id) +{ + DeviceInfo* device_info = GetObjectInfoTable().GetDeviceInfo(device_id); + GFXRECON_ASSERT(device_info != nullptr); + + auto allocator = device_info->allocator.get(); + GFXRECON_ASSERT(allocator != nullptr); + + if (allocator->SupportsOpaqueDeviceAddresses() || !loading_trim_state_) + { + return; + } + + VkAccelerationStructureKHR acceleration_structure = MapHandle( + acceleration_structure_id, &VulkanObjectInfoTable::GetAccelerationStructureKHRInfo); + + // TODO: implement + // acceleration_structure_builders_[device_id]->ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( + // query_type, acceleration_structure); +} + void VulkanReplayConsumerBase::OverrideUpdateDescriptorSets( PFN_vkUpdateDescriptorSets func, const DeviceInfo* device_info, diff --git a/framework/decode/vulkan_replay_consumer_base.h b/framework/decode/vulkan_replay_consumer_base.h index a5cb4712d8..8a92b3bb5e 100644 --- a/framework/decode/vulkan_replay_consumer_base.h +++ b/framework/decode/vulkan_replay_consumer_base.h @@ -189,16 +189,29 @@ class VulkanReplayConsumerBase : public VulkanConsumer format::HandleId commandBuffer, StructPointerDecoder* pPushDescriptorSetWithTemplateInfo) override; - virtual void Process_vkCreateRayTracingPipelinesKHR( - const ApiCallInfo& call_info, - VkResult returnValue, - format::HandleId device, - format::HandleId deferredOperation, - format::HandleId pipelineCache, - uint32_t createInfoCount, - StructPointerDecoder* pCreateInfos, - StructPointerDecoder* pAllocator, - HandlePointerDecoder* pPipelines) override; + void Process_vkCreateRayTracingPipelinesKHR( + const ApiCallInfo& call_info, + VkResult returnValue, + format::HandleId device, + format::HandleId deferredOperation, + format::HandleId pipelineCache, + uint32_t createInfoCount, + StructPointerDecoder* pCreateInfos, + StructPointerDecoder* pAllocator, + HandlePointerDecoder* pPipelines) override; + + void ProcessBuildVulkanAccelerationStructuresMetaCommand( + format::HandleId device, + uint32_t info_count, + StructPointerDecoder* pInfos, + StructPointerDecoder* ppRangeInfos, + std::vector>& instance_buffers_data) override; + + void ProcessCopyVulkanAccelerationStructuresMetaCommand( + format::HandleId device, StructPointerDecoder* copy_infos) override; + + void ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( + format::HandleId device_id, VkQueryType query_type, format::HandleId acceleration_structure_id) override; template void AllowCompileDuringPipelineCreation(uint32_t create_info_count, const T* create_infos) From bbb7bda06243c76c43225d813d30883e28015114 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 11:18:40 +0200 Subject: [PATCH 02/18] many additions here, WIP --- android/framework/encode/CMakeLists.txt | 2 + framework/encode/CMakeLists.txt | 2 + framework/encode/vulkan_capture_manager.cpp | 9 +- .../encode/vulkan_device_address_tracker.cpp | 104 ++++++++ .../encode/vulkan_device_address_tracker.h | 109 +++++++++ framework/encode/vulkan_handle_wrappers.h | 58 ++++- framework/encode/vulkan_state_tracker.cpp | 223 +++++++++++++++--- framework/encode/vulkan_state_tracker.h | 19 +- 8 files changed, 487 insertions(+), 39 deletions(-) create mode 100644 framework/encode/vulkan_device_address_tracker.cpp create mode 100644 framework/encode/vulkan_device_address_tracker.h diff --git a/android/framework/encode/CMakeLists.txt b/android/framework/encode/CMakeLists.txt index 987df0d34d..79a48ca260 100644 --- a/android/framework/encode/CMakeLists.txt +++ b/android/framework/encode/CMakeLists.txt @@ -26,6 +26,8 @@ target_sources(gfxrecon_encode ${GFXRECON_SOURCE_DIR}/framework/encode/struct_pointer_encoder.h ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_capture_manager.h ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_capture_manager.cpp + ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_device_address_tracker.h + ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_device_address_tracker.cpp ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_handle_wrappers.h ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_handle_wrapper_util.h ${GFXRECON_SOURCE_DIR}/framework/encode/vulkan_handle_wrapper_util.cpp diff --git a/framework/encode/CMakeLists.txt b/framework/encode/CMakeLists.txt index 8e9e2eb0fd..c615b545e8 100644 --- a/framework/encode/CMakeLists.txt +++ b/framework/encode/CMakeLists.txt @@ -93,6 +93,8 @@ target_sources(gfxrecon_encode ${CMAKE_CURRENT_LIST_DIR}/struct_pointer_encoder.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_capture_manager.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_capture_manager.cpp + ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.h + ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_handle_wrappers.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_handle_wrapper_util.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_handle_wrapper_util.cpp diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index 9284d48b69..ebbc013eb0 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -857,12 +857,16 @@ VkResult VulkanCaptureManager::OverrideCreateBuffer(VkDevice vulkan_wrappers::BufferWrapper>( device, vulkan_wrappers::NoParentWrapper::kHandleValue, pBuffer, GetUniqueId); + auto buffer_wrapper = vulkan_wrappers::GetWrapper(*pBuffer); + GFXRECON_ASSERT(buffer_wrapper) + buffer_wrapper->created_size = modified_create_info->size; + buffer_wrapper->usage = pCreateInfo->usage; + if (uses_address) { // If the buffer has a device address, write the 'set buffer address' command before writing the API call to // create the buffer. The address will need to be passed to vkCreateBuffer through the pCreateInfo pNext // list. - auto buffer_wrapper = vulkan_wrappers::GetWrapper(*pBuffer); VkBufferDeviceAddressInfo info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; info.pNext = nullptr; info.buffer = buffer_wrapper->handle; @@ -984,7 +988,8 @@ void VulkanCaptureManager::OverrideCmdBuildAccelerationStructuresKHR( { if (IsCaptureModeTrack()) { - state_tracker_->TrackTLASBuildCommand(commandBuffer, infoCount, pInfos, ppBuildRangeInfos); +// state_tracker_->TrackTLASBuildCommand(commandBuffer, infoCount, pInfos, ppBuildRangeInfos); + state_tracker_->TrackAccelerationStructureBuildCommand(commandBuffer, infoCount, pInfos, ppBuildRangeInfos); } const VulkanDeviceTable* device_table = vulkan_wrappers::GetDeviceTable(commandBuffer); diff --git a/framework/encode/vulkan_device_address_tracker.cpp b/framework/encode/vulkan_device_address_tracker.cpp new file mode 100644 index 0000000000..0ffa18f817 --- /dev/null +++ b/framework/encode/vulkan_device_address_tracker.cpp @@ -0,0 +1,104 @@ +/* +** Copyright (c) 2024 LunarG, Inc. +** Copyright (c) 2024 Arm Limited and/or its affiliates +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and associated documentation files (the "Software"), +** to deal in the Software without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Software, and to permit persons to whom the +** Software is furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +*/ + +#include "encode/vulkan_device_address_tracker.h" + +GFXRECON_BEGIN_NAMESPACE(gfxrecon) +GFXRECON_BEGIN_NAMESPACE(encode) + +void encode::VulkanDeviceAddressTracker::TrackBuffer(const vulkan_wrappers::BufferWrapper* wrapper) +{ + if (wrapper != nullptr && wrapper->handle != VK_NULL_HANDLE && wrapper->address != 0 && wrapper->created_size != 0) + { + _buffer_addresses[wrapper->address] = { wrapper->handle, wrapper->created_size }; + } +} + +void VulkanDeviceAddressTracker::RemoveBuffer(const vulkan_wrappers::BufferWrapper* wrapper) +{ + if (wrapper != nullptr) + { + _buffer_addresses.erase(wrapper->address); + } +} + +void VulkanDeviceAddressTracker::TrackAccelerationStructure( + const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) +{ + if (wrapper != nullptr && wrapper->handle != VK_NULL_HANDLE && wrapper->address != 0) + { + _acceleration_structure_addresses[wrapper->address] = wrapper->handle; + } +} + +void VulkanDeviceAddressTracker::RemoveAccelerationStructure( + const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) +{ + if (wrapper != nullptr) + { + _acceleration_structure_addresses.erase(wrapper->address); + } +} + +VkBuffer VulkanDeviceAddressTracker::GetBufferByDeviceAddress(VkDeviceAddress device_address) const +{ + if (!_buffer_addresses.empty()) + { + // find first address equal or greater + auto address_it = _buffer_addresses.lower_bound(device_address); + + if (address_it == _buffer_addresses.end() || address_it->first > device_address) + { + // not found + if (address_it == _buffer_addresses.begin()) + { + return nullptr; + } + + // decrement iterator, now pointing to the first VkDeviceAddress that is lower than device_address + address_it--; + } + // found_address is lower or equal to device_address + const auto& [found_address, buffer_item] = *address_it; + + if (device_address < found_address + buffer_item.size) + { + return buffer_item.handle; + } + } + return VK_NULL_HANDLE; +} + +VkAccelerationStructureKHR +VulkanDeviceAddressTracker::GetAccelerationStructureByDeviceAddress(VkDeviceAddress device_address) const +{ + auto address_it = _acceleration_structure_addresses.find(device_address); + if (address_it != _acceleration_structure_addresses.end()) + { + return address_it->second; + } + return VK_NULL_HANDLE; +} + +GFXRECON_END_NAMESPACE(encode) +GFXRECON_END_NAMESPACE(gfxrecon) \ No newline at end of file diff --git a/framework/encode/vulkan_device_address_tracker.h b/framework/encode/vulkan_device_address_tracker.h new file mode 100644 index 0000000000..c4a98680a7 --- /dev/null +++ b/framework/encode/vulkan_device_address_tracker.h @@ -0,0 +1,109 @@ +/* +** Copyright (c) 2024 LunarG, Inc. +** Copyright (c) 2024 Arm Limited and/or its affiliates +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and associated documentation files (the "Software"), +** to deal in the Software without restriction, including without limitation +** the rights to use, copy, modify, merge, publish, distribute, sublicense, +** and/or sell copies of the Software, and to permit persons to whom the +** Software is furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +*/ + +#ifndef GFXRECON_ENCODE_VULKAN_DEVICE_ADDRESS_TRACKER_H +#define GFXRECON_ENCODE_VULKAN_DEVICE_ADDRESS_TRACKER_H + +#include "encode/vulkan_handle_wrappers.h" +#include +#include + +GFXRECON_BEGIN_NAMESPACE(gfxrecon) +GFXRECON_BEGIN_NAMESPACE(encode) + +class VulkanDeviceAddressTracker +{ + public: + VulkanDeviceAddressTracker() = default; + + //! prevent copying + VulkanDeviceAddressTracker(const VulkanDeviceAddressTracker&) = delete; + + //! allow moving + VulkanDeviceAddressTracker(VulkanDeviceAddressTracker&&) = default; + + ~VulkanDeviceAddressTracker() = default; + + /** + * @brief Track an existing buffer by its VkDeviceAddress. + * + * @param buffer a provided buffer-handle + * @param address a device-address + * @param size buffer-size in bytes + */ + void TrackBuffer(const vulkan_wrappers::BufferWrapper* wrapper); + + /** + * @brief Stop tracking of a currently tracked buffer. + * + * @param wrapper a provided buffer-wrapper. + */ + void RemoveBuffer(const vulkan_wrappers::BufferWrapper* wrapper); + + /** + * @brief Track an existing acceleration-structure by its VkDeviceAddress. + * + * @param wrapper a provided acceleration-structure wrapper containing a handle and device-address. + */ + void TrackAccelerationStructure(const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); + + /** + * @brief Stop tracking of a currently tracked acceleration-structure. + * + * @param wrapper a provided acceleration-structure wrapper. + */ + void RemoveAccelerationStructure(const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); + + /** + * @brief Retrieve a buffer by providing a VkDeviceAddress within its range. + * + * @param device_address a capture-time VkDeviceAddress pointing inside a buffer. + * @return a found VkBuffer-handle or VK_NULL_HANDLE. + */ + [[nodiscard]] VkBuffer GetBufferByDeviceAddress(VkDeviceAddress device_address) const; + + /** + * @brief Retrieve an acceleration-structure by providing a capture-time VkDeviceAddress. + * + * @param device_address a capture-time VkDeviceAddress for an acceleration-structure. + * @return a found AccelerationStructureKHR-handle or VK_NULL_HANDLE. + */ + [[nodiscard]] VkAccelerationStructureKHR + GetAccelerationStructureByDeviceAddress(VkDeviceAddress device_address) const; + + private: + struct buffer_item_t + { + VkBuffer handle = VK_NULL_HANDLE; + size_t size = 0; + }; + //! use a sorted (BST-based) map to look-up ranges + std::map _buffer_addresses; + + std::unordered_map _acceleration_structure_addresses; +}; + +GFXRECON_END_NAMESPACE(encode) +GFXRECON_END_NAMESPACE(gfxrecon) + +#endif // GFXRECON_ENCODE_VULKAN_DEVICE_ADDRESS_TRACKER_H diff --git a/framework/encode/vulkan_handle_wrappers.h b/framework/encode/vulkan_handle_wrappers.h index e131d8026d..822652cffb 100644 --- a/framework/encode/vulkan_handle_wrappers.h +++ b/framework/encode/vulkan_handle_wrappers.h @@ -210,10 +210,11 @@ struct BufferWrapper : public HandleWrapper const void* bind_pnext{ nullptr }; std::unique_ptr bind_pnext_memory; - format::HandleId bind_memory_id{ format::kNullHandleId }; - VkDeviceSize bind_offset{ 0 }; - uint32_t queue_family_index{ 0 }; - VkDeviceSize created_size{ 0 }; + format::HandleId bind_memory_id{ format::kNullHandleId }; + VkDeviceSize bind_offset{ 0 }; + uint32_t queue_family_index{ 0 }; + VkDeviceSize created_size{ 0 }; + VkBufferUsageFlags usage{ 0 }; // State tracking info for buffers with device addresses. format::HandleId device_id{ format::kNullHandleId }; @@ -510,6 +511,55 @@ struct AccelerationStructureKHRWrapper : public HandleWrapper blas; + + VkAccelerationStructureTypeKHR type_; + // Only used when tracking + + struct ASInputBuffer + { + // Required data to correctly create a buffer + VkBuffer handle{ VK_NULL_HANDLE }; + format::HandleId handle_id{ format::kNullHandleId }; + DeviceWrapper* bind_device{ nullptr }; + uint32_t queue_family_index{ 0 }; + VkDeviceSize created_size{ 0 }; + VkBufferUsageFlags usage{ 0 }; + + bool destroyed{ false }; + + VkDeviceAddress capture_address{ 0 }; + VkDeviceAddress actual_address{ 0 }; + + std::vector bytes; + + VkMemoryRequirements memory_requirements{}; + format::HandleId bind_memory{}; + VkDeviceMemory bind_memory_handle{ VK_NULL_HANDLE }; + }; + + struct AccelerationStructureKHRBuildCommandData + { + VkAccelerationStructureBuildGeometryInfoKHR geometry_info; + std::unique_ptr geometry_info_memory; + std::vector build_range_infos; + std::vector input_buffers; + }; + std::optional latest_update_command_{ std::nullopt }; + std::optional latest_build_command_{ std::nullopt }; + + struct AccelerationStructureCopyCommandData + { + format::HandleId device; + VkCopyAccelerationStructureInfoKHR info; + }; + std::optional latest_copy_command_{ std::nullopt }; + + struct AccelerationStructureWritePropertiesCommandData + { + format::HandleId device; + VkQueryType query_type; + }; + std::optional latest_write_properties_command_{ std::nullopt }; }; struct AccelerationStructureNVWrapper : public HandleWrapper diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 19ba67aabc..cb6e8ba1e1 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -340,6 +340,8 @@ void VulkanStateTracker::TrackBufferDeviceAddress(VkDevice device, VkBuffer buff auto wrapper = vulkan_wrappers::GetWrapper(buffer); wrapper->device_id = vulkan_wrappers::GetWrappedId(device); wrapper->address = address; + + device_address_tracker_.TrackBuffer(wrapper); } void VulkanStateTracker::TrackOpaqueBufferDeviceAddress(VkDevice device, @@ -370,47 +372,167 @@ void VulkanStateTracker::TrackBufferMemoryBinding( } } -void VulkanStateTracker::TrackTLASBuildCommand( +//void VulkanStateTracker::TrackTLASBuildCommand( +// VkCommandBuffer command_buffer, +// uint32_t info_count, +// const VkAccelerationStructureBuildGeometryInfoKHR* infos, +// const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos) +//{ +// if (info_count && infos && pp_buildRange_infos) +// { +// vulkan_wrappers::CommandBufferWrapper* buf_wrapper = +// vulkan_wrappers::GetWrapper(command_buffer); +// +// for (uint32_t i = 0; i < info_count; ++i) +// { +// if (infos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR && +// infos[i].dstAccelerationStructure != VK_NULL_HANDLE && infos[i].geometryCount && infos[i].pGeometries) +// { +// vulkan_wrappers::AccelerationStructureKHRWrapper* tlas_wrapper = +// vulkan_wrappers::GetWrapper( +// infos[i].dstAccelerationStructure); +// +// tlas_wrapper->blas.clear(); +// +// for (uint32_t g = 0; g < infos[i].geometryCount; ++g) +// { +// if (infos[i].pGeometries[g].geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) +// { +// const VkDeviceAddress address = infos[i].pGeometries[g].geometry.instances.data.deviceAddress; +// const uint32_t primitive_count = pp_buildRange_infos[i]->primitiveCount; +// // According to spec both address and primitiveCount can be 0. +// // Nothing to handle in these cases. +// if (address && primitive_count) +// { +// const vulkan_wrappers::CommandBufferWrapper::tlas_build_info tlas_info = { +// address, primitive_count, pp_buildRange_infos[i]->primitiveOffset +// }; +// +// buf_wrapper->tlas_build_info_map.emplace_back( +// std::make_pair(tlas_wrapper, std::move(tlas_info))); +// } +// } +// } +// } +// } +// } +//} + +void VulkanStateTracker::TrackAccelerationStructureBuildCommand( VkCommandBuffer command_buffer, uint32_t info_count, - const VkAccelerationStructureBuildGeometryInfoKHR* infos, + const VkAccelerationStructureBuildGeometryInfoKHR* p_infos, const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos) { - if (info_count && infos && pp_buildRange_infos) + if (info_count == 0 || p_infos == nullptr || pp_buildRange_infos == nullptr) { - vulkan_wrappers::CommandBufferWrapper* buf_wrapper = - vulkan_wrappers::GetWrapper(command_buffer); + return; + } - for (uint32_t i = 0; i < info_count; ++i) + auto cmd_buf_wrapper = vulkan_wrappers::GetWrapper(command_buffer); + for (uint32_t info = 0; info < info_count; ++info) + { + if (p_infos[info].dstAccelerationStructure == VK_NULL_HANDLE || p_infos[info].geometryCount == 0 || + (p_infos[info].pGeometries == nullptr && p_infos[info].ppGeometries == nullptr)) { - if (infos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR && - infos[i].dstAccelerationStructure != VK_NULL_HANDLE && infos[i].geometryCount && infos[i].pGeometries) - { - vulkan_wrappers::AccelerationStructureKHRWrapper* tlas_wrapper = - vulkan_wrappers::GetWrapper( - infos[i].dstAccelerationStructure); + continue; + } - tlas_wrapper->blas.clear(); + auto wrapper = vulkan_wrappers::GetWrapper( + p_infos[info].dstAccelerationStructure); + + vulkan_wrappers::AccelerationStructureKHRWrapper::AccelerationStructureKHRBuildCommandData dst_command{}; + // Extract command information for 1 AccelerationStructure + for (uint32_t geometry = 0; geometry < p_infos[info].geometryCount; ++geometry) + { + // TODO: pGeometries vs ppGeometries -> handle both cases - for (uint32_t g = 0; g < infos[i].geometryCount; ++g) + std::vector to_extract; + switch (p_infos[info].pGeometries[geometry].geometryType) + { + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_TRIANGLES_KHR: { - if (infos[i].pGeometries[g].geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) - { - const VkDeviceAddress address = infos[i].pGeometries[g].geometry.instances.data.deviceAddress; - const uint32_t primitive_count = pp_buildRange_infos[i]->primitiveCount; - // According to spec both address and primitiveCount can be 0. - // Nothing to handle in these cases. - if (address && primitive_count) - { - const vulkan_wrappers::CommandBufferWrapper::tlas_build_info tlas_info = { - address, primitive_count, pp_buildRange_infos[i]->primitiveOffset - }; + to_extract = { p_infos[info].pGeometries[geometry].geometry.triangles.vertexData.deviceAddress, + p_infos[info].pGeometries[geometry].geometry.triangles.indexData.deviceAddress, + p_infos[info].pGeometries[geometry].geometry.triangles.transformData.deviceAddress }; + break; + } + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_AABBS_KHR: + { + to_extract = { p_infos[info].pGeometries[geometry].geometry.aabbs.data.deviceAddress }; + break; + } + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_INSTANCES_KHR: + { + to_extract = { p_infos[info].pGeometries[geometry].geometry.instances.data.deviceAddress }; + break; + } + case VK_GEOMETRY_TYPE_MAX_ENUM_KHR: + break; + } - buf_wrapper->tlas_build_info_map.emplace_back( - std::make_pair(tlas_wrapper, std::move(tlas_info))); - } - } + for (const VkDeviceAddress address : to_extract) + { + if (address == 0) + { + continue; } + + auto target_buffer_wrapper = vulkan_wrappers::GetWrapper( + device_address_tracker_.GetBufferByDeviceAddress(address)); + + GFXRECON_ASSERT(target_buffer_wrapper != nullptr); + + vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer& buffer = + dst_command.input_buffers.emplace_back(); + + buffer.capture_address = address; + buffer.handle = target_buffer_wrapper->handle; + buffer.handle_id = target_buffer_wrapper->handle_id; + buffer.bind_device = target_buffer_wrapper->bind_device; + buffer.queue_family_index = target_buffer_wrapper->queue_family_index; + buffer.created_size = target_buffer_wrapper->created_size; + buffer.usage = target_buffer_wrapper->usage; + } + + dst_command.geometry_info = p_infos[info]; + VkAccelerationStructureGeometryKHR* unwrapped = gfxrecon::encode::vulkan_trackers::TrackStructs( + p_infos[info].pGeometries, p_infos[info].geometryCount, dst_command.geometry_info_memory); + dst_command.geometry_info.pGeometries = unwrapped; + + dst_command.build_range_infos.insert(dst_command.build_range_infos.end(), + pp_buildRange_infos[info], + pp_buildRange_infos[info] + p_infos[info].geometryCount); + } + + if (p_infos[info].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + { + wrapper->latest_build_command_ = std::move(dst_command); + } + else if (p_infos[info].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) + { + wrapper->latest_update_command_ = std::move(dst_command); + } + + wrapper->blas.clear(); + + for (uint32_t g = 0; g < p_infos[info].geometryCount; ++g) + { + if (p_infos[info].pGeometries[g].geometryType != VK_GEOMETRY_TYPE_INSTANCES_KHR) + { + continue; + } + const VkDeviceAddress address = p_infos[info].pGeometries[g].geometry.instances.data.deviceAddress; + const uint32_t primitive_count = pp_buildRange_infos[info]->primitiveCount; + // According to spec both address and primitiveCount can be 0. + // Nothing to handle in these cases. + if (address && primitive_count) + { + const vulkan_wrappers::CommandBufferWrapper::tlas_build_info tlas_info = { + address, primitive_count, pp_buildRange_infos[info]->primitiveOffset + }; + + cmd_buf_wrapper->tlas_build_info_map.emplace_back(std::make_pair(wrapper, std::move(tlas_info))); } } } @@ -1381,6 +1503,7 @@ void VulkanStateTracker::TrackAccelerationStructureKHRDeviceAddress(VkDevice assert(address); as_device_addresses_map.emplace(address, wrapper); + device_address_tracker_.TrackAccelerationStructure(wrapper); } void VulkanStateTracker::TrackDeviceMemoryDeviceAddress(VkDevice device, VkDeviceMemory memory, VkDeviceAddress address) @@ -1549,6 +1672,47 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrap } } +void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferWrapper* wrapper) +{ + assert(wrapper != nullptr); +// auto memory_wrapper = state_table_.GetDeviceMemoryWrapper(wrapper->bind_memory_id); +// if (memory_wrapper) +// { +// memory_wrapper->bound_buffers.erase(wrapper); +// } +// + device_address_tracker_.RemoveBuffer(wrapper); + + state_table_.VisitWrappers([&wrapper, this](vulkan_wrappers::AccelerationStructureKHRWrapper* acc_wrapper) { + GFXRECON_ASSERT(acc_wrapper); + for (auto& command : { &acc_wrapper->latest_build_command_, &acc_wrapper->latest_update_command_ }) + { + if (!command || !command->has_value()) + { + continue; + } + for (vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer& buffer : (*command)->input_buffers) + { + if (wrapper->handle_id == buffer.handle_id) + { + buffer.destroyed = true; +// auto [resource_util, created] = resource_utils.try_emplace( +// buffer.bind_device->handle_id, +// graphics::VulkanResourcesUtil(buffer.bind_device->handle, +// buffer.bind_device->physical_device->handle, +// buffer.bind_device->layer_table, +// *buffer.bind_device->physical_device->layer_table_ref, +// buffer.bind_device->physical_device->memory_properties)); +// buffer.bind_device->layer_table.GetBufferMemoryRequirements( +// buffer.bind_device->handle, buffer.handle, &buffer.memory_requirements); +// resource_util->second.ReadFromBufferResource( +// buffer.handle, buffer.created_size, 0, buffer.queue_family_index, buffer.bytes); + } + } + } + }); +} + void VulkanStateTracker::DestroyState(vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { assert(wrapper != nullptr); @@ -1559,6 +1723,7 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::AccelerationStructureKHRW { as_device_addresses_map.erase(entry); } + device_address_tracker_.RemoveAccelerationStructure(wrapper); } void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t command_buffer_count, diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index 00d690e8b5..2ce17679fd 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -25,6 +25,7 @@ #include "encode/descriptor_update_template_info.h" #include "encode/vulkan_handle_wrappers.h" +#include "encode/vulkan_device_address_tracker.h" #include "generated/generated_vulkan_state_table.h" #include "encode/vulkan_state_tracker_initializers.h" #include "encode/vulkan_state_writer.h" @@ -390,10 +391,15 @@ class VulkanStateTracker VkAccelerationStructureKHR accel_struct, VkDeviceAddress address); - void TrackTLASBuildCommand(VkCommandBuffer command_buffer, - uint32_t info_count, - const VkAccelerationStructureBuildGeometryInfoKHR* infos, - const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); + // void TrackTLASBuildCommand(VkCommandBuffer command_buffer, + // uint32_t info_count, + // const VkAccelerationStructureBuildGeometryInfoKHR* infos, + // const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); + void + TrackAccelerationStructureBuildCommand(VkCommandBuffer command_buffer, + uint32_t info_count, + const VkAccelerationStructureBuildGeometryInfoKHR* infos, + const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); void TrackDeviceMemoryDeviceAddress(VkDevice device, VkDeviceMemory memory, VkDeviceAddress address); @@ -479,6 +485,8 @@ class VulkanStateTracker void DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrapper); + void DestroyState(vulkan_wrappers::BufferWrapper* wrapper); + void DestroyState(vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); void TrackQuerySubmissions(vulkan_wrappers::CommandBufferWrapper* command_wrapper); @@ -490,7 +498,10 @@ class VulkanStateTracker std::unordered_map device_memory_addresses_map; // Keeps track of acceleration structures' device addresses + // TODO: refactor with encode::VulkanDeviceAddressTracker std::unordered_map as_device_addresses_map; + + encode::VulkanDeviceAddressTracker device_address_tracker_; }; GFXRECON_END_NAMESPACE(encode) From 33681af2064af06eff3e609b98eed0ba740402e0 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 12:35:38 +0200 Subject: [PATCH 03/18] minor cleanup/refactor AS-lookup --- .../encode/vulkan_device_address_tracker.h | 10 +-- framework/encode/vulkan_handle_wrapper_util.h | 2 +- framework/encode/vulkan_state_tracker.cpp | 62 ++----------------- framework/encode/vulkan_state_tracker.h | 5 +- 4 files changed, 11 insertions(+), 68 deletions(-) diff --git a/framework/encode/vulkan_device_address_tracker.h b/framework/encode/vulkan_device_address_tracker.h index c4a98680a7..1b616dbe80 100644 --- a/framework/encode/vulkan_device_address_tracker.h +++ b/framework/encode/vulkan_device_address_tracker.h @@ -56,28 +56,28 @@ class VulkanDeviceAddressTracker /** * @brief Stop tracking of a currently tracked buffer. * - * @param wrapper a provided buffer-wrapper. + * @param wrapper provided buffer-wrapper. */ void RemoveBuffer(const vulkan_wrappers::BufferWrapper* wrapper); /** * @brief Track an existing acceleration-structure by its VkDeviceAddress. * - * @param wrapper a provided acceleration-structure wrapper containing a handle and device-address. + * @param wrapper provided acceleration-structure wrapper containing a handle and device-address. */ void TrackAccelerationStructure(const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); /** * @brief Stop tracking of a currently tracked acceleration-structure. * - * @param wrapper a provided acceleration-structure wrapper. + * @param wrapper provided acceleration-structure wrapper. */ void RemoveAccelerationStructure(const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); /** * @brief Retrieve a buffer by providing a VkDeviceAddress within its range. * - * @param device_address a capture-time VkDeviceAddress pointing inside a buffer. + * @param device_address VkDeviceAddress pointing inside a buffer. * @return a found VkBuffer-handle or VK_NULL_HANDLE. */ [[nodiscard]] VkBuffer GetBufferByDeviceAddress(VkDeviceAddress device_address) const; @@ -85,7 +85,7 @@ class VulkanDeviceAddressTracker /** * @brief Retrieve an acceleration-structure by providing a capture-time VkDeviceAddress. * - * @param device_address a capture-time VkDeviceAddress for an acceleration-structure. + * @param device_address VkDeviceAddress for an acceleration-structure. * @return a found AccelerationStructureKHR-handle or VK_NULL_HANDLE. */ [[nodiscard]] VkAccelerationStructureKHR diff --git a/framework/encode/vulkan_handle_wrapper_util.h b/framework/encode/vulkan_handle_wrapper_util.h index 4dfb973b29..f8cf42b751 100644 --- a/framework/encode/vulkan_handle_wrapper_util.h +++ b/framework/encode/vulkan_handle_wrapper_util.h @@ -103,7 +103,7 @@ Wrapper* GetWrapper(const typename Wrapper::HandleType& handle) { if (handle == VK_NULL_HANDLE) { - return 0; + return nullptr; } auto wrapper = state_handle_table_.GetWrapper(handle); if (wrapper == nullptr) diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index cb6e8ba1e1..c61d2a5880 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -372,52 +372,6 @@ void VulkanStateTracker::TrackBufferMemoryBinding( } } -//void VulkanStateTracker::TrackTLASBuildCommand( -// VkCommandBuffer command_buffer, -// uint32_t info_count, -// const VkAccelerationStructureBuildGeometryInfoKHR* infos, -// const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos) -//{ -// if (info_count && infos && pp_buildRange_infos) -// { -// vulkan_wrappers::CommandBufferWrapper* buf_wrapper = -// vulkan_wrappers::GetWrapper(command_buffer); -// -// for (uint32_t i = 0; i < info_count; ++i) -// { -// if (infos[i].type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR && -// infos[i].dstAccelerationStructure != VK_NULL_HANDLE && infos[i].geometryCount && infos[i].pGeometries) -// { -// vulkan_wrappers::AccelerationStructureKHRWrapper* tlas_wrapper = -// vulkan_wrappers::GetWrapper( -// infos[i].dstAccelerationStructure); -// -// tlas_wrapper->blas.clear(); -// -// for (uint32_t g = 0; g < infos[i].geometryCount; ++g) -// { -// if (infos[i].pGeometries[g].geometryType == VK_GEOMETRY_TYPE_INSTANCES_KHR) -// { -// const VkDeviceAddress address = infos[i].pGeometries[g].geometry.instances.data.deviceAddress; -// const uint32_t primitive_count = pp_buildRange_infos[i]->primitiveCount; -// // According to spec both address and primitiveCount can be 0. -// // Nothing to handle in these cases. -// if (address && primitive_count) -// { -// const vulkan_wrappers::CommandBufferWrapper::tlas_build_info tlas_info = { -// address, primitive_count, pp_buildRange_infos[i]->primitiveOffset -// }; -// -// buf_wrapper->tlas_build_info_map.emplace_back( -// std::make_pair(tlas_wrapper, std::move(tlas_info))); -// } -// } -// } -// } -// } -// } -//} - void VulkanStateTracker::TrackAccelerationStructureBuildCommand( VkCommandBuffer command_buffer, uint32_t info_count, @@ -478,7 +432,7 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( continue; } - auto target_buffer_wrapper = vulkan_wrappers::GetWrapper( + auto target_buffer_wrapper = vulkan_wrappers::GetWrapper( device_address_tracker_.GetBufferByDeviceAddress(address)); GFXRECON_ASSERT(target_buffer_wrapper != nullptr); @@ -1501,8 +1455,6 @@ void VulkanStateTracker::TrackAccelerationStructureKHRDeviceAddress(VkDevice wrapper->device_id = vulkan_wrappers::GetWrappedId(device); wrapper->address = address; - assert(address); - as_device_addresses_map.emplace(address, wrapper); device_address_tracker_.TrackAccelerationStructure(wrapper); } @@ -1717,12 +1669,6 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::AccelerationStructureKHRW { assert(wrapper != nullptr); wrapper->create_parameters = nullptr; - - const auto& entry = as_device_addresses_map.find(wrapper->address); - if (entry != as_device_addresses_map.end()) - { - as_device_addresses_map.erase(entry); - } device_address_tracker_.RemoveAccelerationStructure(wrapper); } @@ -1824,10 +1770,10 @@ void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t comm // VkAccelerationStructureInstanceKHR::accelerationStructureReference referes to const uint64_t as_reference = instances[b].accelerationStructureReference; - const auto blas_dev_mem_pair = as_device_addresses_map.find(as_reference); - if (blas_dev_mem_pair != as_device_addresses_map.end()) + if(auto as_wrapper = vulkan_wrappers::GetWrapper( + device_address_tracker_.GetAccelerationStructureByDeviceAddress(as_reference))) { - tlas_wrapper->blas.push_back(blas_dev_mem_pair->second); + tlas_wrapper->blas.push_back(as_wrapper); } } diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index 2ce17679fd..a017d478f0 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -497,10 +497,7 @@ class VulkanStateTracker // Keeps track of device memories' device addresses std::unordered_map device_memory_addresses_map; - // Keeps track of acceleration structures' device addresses - // TODO: refactor with encode::VulkanDeviceAddressTracker - std::unordered_map as_device_addresses_map; - + // Keeps track of buffer- and acceleration structures' device addresses encode::VulkanDeviceAddressTracker device_address_tracker_; }; From 31c0c2788c395f81c102b5b5c75ca55990ea2006 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 12:42:34 +0200 Subject: [PATCH 04/18] Add DispatchVulkanAccelerationStructuresCopyMetaCommand --- framework/decode/api_decoder.h | 3 ++ framework/decode/vulkan_decoder_base.cpp | 36 ++++++++++++------------ framework/decode/vulkan_decoder_base.h | 3 ++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/framework/decode/api_decoder.h b/framework/decode/api_decoder.h index 2a969209e3..4279a294d2 100644 --- a/framework/decode/api_decoder.h +++ b/framework/decode/api_decoder.h @@ -205,6 +205,9 @@ class ApiDecoder virtual void DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, size_t buffer_size) {}; + + virtual void DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) {}; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/decode/vulkan_decoder_base.cpp b/framework/decode/vulkan_decoder_base.cpp index 506d3a7640..769e0a0ae0 100644 --- a/framework/decode/vulkan_decoder_base.cpp +++ b/framework/decode/vulkan_decoder_base.cpp @@ -625,24 +625,24 @@ void VulkanDecoderBase::DispatchVulkanAccelerationStructuresCopyMetaCommand(cons } } -//void VulkanDecoderBase::DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, -// size_t buffer_size) -//{ -// format::HandleId device_id; -// VkQueryType query_type; -// format::HandleId acceleration_structure_id; -// -// std::size_t bytes_read = ValueDecoder::DecodeHandleIdValue(parameter_buffer, sizeof(format::HandleId), &device_id); -// bytes_read += ValueDecoder::DecodeEnumValue(parameter_buffer + bytes_read, sizeof(VkQueryType), &query_type); -// bytes_read += ValueDecoder::DecodeHandleIdValue( -// parameter_buffer + bytes_read, sizeof(format::HandleId), &acceleration_structure_id); -// -// for (auto consumer : consumers_) -// { -// consumer->ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( -// device_id, query_type, acceleration_structure_id); -// } -//} +void VulkanDecoderBase::DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) +{ + format::HandleId device_id; + VkQueryType query_type; + format::HandleId acceleration_structure_id; + + std::size_t bytes_read = ValueDecoder::DecodeHandleIdValue(parameter_buffer, sizeof(format::HandleId), &device_id); + bytes_read += ValueDecoder::DecodeEnumValue(parameter_buffer + bytes_read, sizeof(VkQueryType), &query_type); + bytes_read += ValueDecoder::DecodeHandleIdValue( + parameter_buffer + bytes_read, sizeof(format::HandleId), &acceleration_structure_id); + + for (auto consumer : consumers_) + { + consumer->ProcessVulkanAccelerationStructuresWritePropertiesMetaCommand( + device_id, query_type, acceleration_structure_id); + } +} GFXRECON_END_NAMESPACE(decode) GFXRECON_END_NAMESPACE(gfxrecon) diff --git a/framework/decode/vulkan_decoder_base.h b/framework/decode/vulkan_decoder_base.h index 7b4bbd8519..d99e71cda1 100644 --- a/framework/decode/vulkan_decoder_base.h +++ b/framework/decode/vulkan_decoder_base.h @@ -206,6 +206,9 @@ class VulkanDecoderBase : public ApiDecoder void DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, size_t buffer_size) override; + void DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, + size_t buffer_size) override; + protected: const std::vector& GetConsumers() const { return consumers_; } From 3fb4c8ebf2495096000bc693089ccfddd096b0d0 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 13:08:22 +0200 Subject: [PATCH 05/18] mutex locking seems required (was not done before) --- .../encode/vulkan_device_address_tracker.cpp | 48 +++++++++++++++---- .../encode/vulkan_device_address_tracker.h | 13 +++-- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/framework/encode/vulkan_device_address_tracker.cpp b/framework/encode/vulkan_device_address_tracker.cpp index 0ffa18f817..ffc0dc16dd 100644 --- a/framework/encode/vulkan_device_address_tracker.cpp +++ b/framework/encode/vulkan_device_address_tracker.cpp @@ -26,11 +26,33 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(encode) +VulkanDeviceAddressTracker::VulkanDeviceAddressTracker(VulkanDeviceAddressTracker&& other) noexcept : + VulkanDeviceAddressTracker() +{ + swap(*this, other); +} + +VulkanDeviceAddressTracker& VulkanDeviceAddressTracker::operator=(VulkanDeviceAddressTracker other) +{ + swap(*this, other); + return *this; +} + +void swap(VulkanDeviceAddressTracker& lhs, VulkanDeviceAddressTracker& rhs) noexcept +{ + std::lock(lhs.mutex_, rhs.mutex_); + std::lock_guard lock_lhs(lhs.mutex_, std::adopt_lock); + std::lock_guard lock_rhs(rhs.mutex_, std::adopt_lock); + std::swap(lhs.buffer_addresses_, rhs.buffer_addresses_); + std::swap(lhs.acceleration_structure_addresses_, rhs.acceleration_structure_addresses_); +} + void encode::VulkanDeviceAddressTracker::TrackBuffer(const vulkan_wrappers::BufferWrapper* wrapper) { if (wrapper != nullptr && wrapper->handle != VK_NULL_HANDLE && wrapper->address != 0 && wrapper->created_size != 0) { - _buffer_addresses[wrapper->address] = { wrapper->handle, wrapper->created_size }; + std::unique_lock lock(mutex_); + buffer_addresses_[wrapper->address] = { wrapper->handle, wrapper->created_size }; } } @@ -38,7 +60,8 @@ void VulkanDeviceAddressTracker::RemoveBuffer(const vulkan_wrappers::BufferWrapp { if (wrapper != nullptr) { - _buffer_addresses.erase(wrapper->address); + std::unique_lock lock(mutex_); + buffer_addresses_.erase(wrapper->address); } } @@ -47,7 +70,8 @@ void VulkanDeviceAddressTracker::TrackAccelerationStructure( { if (wrapper != nullptr && wrapper->handle != VK_NULL_HANDLE && wrapper->address != 0) { - _acceleration_structure_addresses[wrapper->address] = wrapper->handle; + std::unique_lock lock(mutex_); + acceleration_structure_addresses_[wrapper->address] = wrapper->handle; } } @@ -56,21 +80,24 @@ void VulkanDeviceAddressTracker::RemoveAccelerationStructure( { if (wrapper != nullptr) { - _acceleration_structure_addresses.erase(wrapper->address); + std::unique_lock lock(mutex_); + acceleration_structure_addresses_.erase(wrapper->address); } } VkBuffer VulkanDeviceAddressTracker::GetBufferByDeviceAddress(VkDeviceAddress device_address) const { - if (!_buffer_addresses.empty()) + std::shared_lock lock(mutex_); + + if (!buffer_addresses_.empty()) { // find first address equal or greater - auto address_it = _buffer_addresses.lower_bound(device_address); + auto address_it = buffer_addresses_.lower_bound(device_address); - if (address_it == _buffer_addresses.end() || address_it->first > device_address) + if (address_it == buffer_addresses_.end() || address_it->first > device_address) { // not found - if (address_it == _buffer_addresses.begin()) + if (address_it == buffer_addresses_.begin()) { return nullptr; } @@ -92,8 +119,9 @@ VkBuffer VulkanDeviceAddressTracker::GetBufferByDeviceAddress(VkDeviceAddress de VkAccelerationStructureKHR VulkanDeviceAddressTracker::GetAccelerationStructureByDeviceAddress(VkDeviceAddress device_address) const { - auto address_it = _acceleration_structure_addresses.find(device_address); - if (address_it != _acceleration_structure_addresses.end()) + std::shared_lock lock(mutex_); + auto address_it = acceleration_structure_addresses_.find(device_address); + if (address_it != acceleration_structure_addresses_.end()) { return address_it->second; } diff --git a/framework/encode/vulkan_device_address_tracker.h b/framework/encode/vulkan_device_address_tracker.h index 1b616dbe80..7ba16210d1 100644 --- a/framework/encode/vulkan_device_address_tracker.h +++ b/framework/encode/vulkan_device_address_tracker.h @@ -25,6 +25,7 @@ #define GFXRECON_ENCODE_VULKAN_DEVICE_ADDRESS_TRACKER_H #include "encode/vulkan_handle_wrappers.h" +#include #include #include @@ -40,10 +41,14 @@ class VulkanDeviceAddressTracker VulkanDeviceAddressTracker(const VulkanDeviceAddressTracker&) = delete; //! allow moving - VulkanDeviceAddressTracker(VulkanDeviceAddressTracker&&) = default; + VulkanDeviceAddressTracker(VulkanDeviceAddressTracker&&) noexcept; ~VulkanDeviceAddressTracker() = default; + VulkanDeviceAddressTracker& operator=(VulkanDeviceAddressTracker); + + friend void swap(VulkanDeviceAddressTracker& lhs, VulkanDeviceAddressTracker& rhs) noexcept; + /** * @brief Track an existing buffer by its VkDeviceAddress. * @@ -98,9 +103,11 @@ class VulkanDeviceAddressTracker size_t size = 0; }; //! use a sorted (BST-based) map to look-up ranges - std::map _buffer_addresses; + std::map buffer_addresses_; + + std::unordered_map acceleration_structure_addresses_; - std::unordered_map _acceleration_structure_addresses; + mutable std::shared_mutex mutex_; }; GFXRECON_END_NAMESPACE(encode) From fad6941378574e5e65bd757ddb401944cb689b57 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 16:40:38 +0200 Subject: [PATCH 06/18] work on OverrideCreateAccelerationStructureKHR --- framework/encode/vulkan_capture_manager.cpp | 62 ++++++++++----------- framework/encode/vulkan_handle_wrappers.h | 2 +- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index ebbc013eb0..87af75a630 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -926,28 +926,23 @@ VulkanCaptureManager::OverrideCreateAccelerationStructureKHR(VkDevice const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructureKHR) { - auto handle_unwrap_memory = VulkanCaptureManager::Get()->GetHandleUnwrapMemory(); - auto device_wrapper = vulkan_wrappers::GetWrapper(device); - VkDevice device_unwrapped = device_wrapper->handle; - const VulkanDeviceTable* device_table = vulkan_wrappers::GetDeviceTable(device); - const VkAccelerationStructureCreateInfoKHR* pCreateInfo_unwrapped = - vulkan_wrappers::UnwrapStructPtrHandles(pCreateInfo, handle_unwrap_memory); + auto device_wrapper = vulkan_wrappers::GetWrapper(device); + VkDevice device_unwrapped = device_wrapper->handle; + const VulkanDeviceTable* device_table = vulkan_wrappers::GetDeviceTable(device); + + std::unique_ptr struct_memory; + VkAccelerationStructureCreateInfoKHR* modified_create_info = + vulkan_trackers::TrackStructs(pCreateInfo, 1, struct_memory); - VkResult result; if (device_wrapper->property_feature_info.feature_accelerationStructureCaptureReplay) { // Add flag to allow for opaque address capture - VkAccelerationStructureCreateInfoKHR modified_create_info = (*pCreateInfo_unwrapped); - modified_create_info.createFlags |= VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR; - result = device_table->CreateAccelerationStructureKHR( - device_unwrapped, &modified_create_info, pAllocator, pAccelerationStructureKHR); - } - else - { - result = device_table->CreateAccelerationStructureKHR( - device_unwrapped, pCreateInfo_unwrapped, pAllocator, pAccelerationStructureKHR); + modified_create_info->createFlags |= VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR; } + VkResult result = device_table->CreateAccelerationStructureKHR( + device_unwrapped, modified_create_info, pAllocator, pAccelerationStructureKHR); + if ((result == VK_SUCCESS) && (pAccelerationStructureKHR != nullptr)) { vulkan_wrappers::CreateWrappedHandle( device, vulkan_wrappers::NoParentWrapper::kHandleValue, pAccelerationStructureKHR, GetUniqueId); - if (device_wrapper->property_feature_info.feature_accelerationStructureCaptureReplay) - { - auto accel_struct_wrapper = vulkan_wrappers::GetWrapper( - *pAccelerationStructureKHR); + auto accel_struct_wrapper = + vulkan_wrappers::GetWrapper(*pAccelerationStructureKHR); - VkAccelerationStructureDeviceAddressInfoKHR address_info{ - VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, nullptr, accel_struct_wrapper->handle - }; + VkAccelerationStructureDeviceAddressInfoKHR address_info{ + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, nullptr, accel_struct_wrapper->handle + }; - // save address to use as pCreateInfo->deviceAddress during replay - VkDeviceAddress address = - device_table->GetAccelerationStructureDeviceAddressKHR(device_unwrapped, &address_info); + // save address to use as pCreateInfo->deviceAddress during replay + VkDeviceAddress address = + device_table->GetAccelerationStructureDeviceAddressKHR(device_unwrapped, &address_info); - WriteSetOpaqueAddressCommand(device_wrapper->handle_id, accel_struct_wrapper->handle_id, address); + accel_struct_wrapper->device_id = device_wrapper->handle_id; + accel_struct_wrapper->address = address; + accel_struct_wrapper->type = modified_create_info->type; - if (IsCaptureModeTrack()) - { - state_tracker_->TrackAccelerationStructureKHRDeviceAddress(device, *pAccelerationStructureKHR, address); - } + if (IsCaptureModeTrack()) + { + state_tracker_->TrackAccelerationStructureKHRDeviceAddress(device, *pAccelerationStructureKHR, address); } - } + if (device_wrapper->property_feature_info.feature_accelerationStructureCaptureReplay) + { + WriteSetOpaqueAddressCommand(device_wrapper->handle_id, accel_struct_wrapper->handle_id, address); + } + } return result; } diff --git a/framework/encode/vulkan_handle_wrappers.h b/framework/encode/vulkan_handle_wrappers.h index 822652cffb..bb3fedf45f 100644 --- a/framework/encode/vulkan_handle_wrappers.h +++ b/framework/encode/vulkan_handle_wrappers.h @@ -512,7 +512,7 @@ struct AccelerationStructureKHRWrapper : public HandleWrapper blas; - VkAccelerationStructureTypeKHR type_; + VkAccelerationStructureTypeKHR type; // Only used when tracking struct ASInputBuffer From 784b9a9d2624820d643757a519d210e7db00ba74 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 15 Oct 2024 18:36:13 +0200 Subject: [PATCH 07/18] VulkanResourcesUtil based AS-buffer copy --- framework/encode/vulkan_capture_manager.cpp | 1 - framework/encode/vulkan_state_tracker.cpp | 34 ++++++++++----------- framework/encode/vulkan_state_tracker.h | 4 ++- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index 87af75a630..7b6a154538 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -986,7 +986,6 @@ void VulkanCaptureManager::OverrideCmdBuildAccelerationStructuresKHR( { if (IsCaptureModeTrack()) { -// state_tracker_->TrackTLASBuildCommand(commandBuffer, infoCount, pInfos, ppBuildRangeInfos); state_tracker_->TrackAccelerationStructureBuildCommand(commandBuffer, infoCount, pInfos, ppBuildRangeInfos); } diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index c61d2a5880..0ec1e505b2 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -1627,12 +1627,12 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrap void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferWrapper* wrapper) { assert(wrapper != nullptr); -// auto memory_wrapper = state_table_.GetDeviceMemoryWrapper(wrapper->bind_memory_id); -// if (memory_wrapper) -// { -// memory_wrapper->bound_buffers.erase(wrapper); -// } -// + // auto memory_wrapper = state_table_.GetDeviceMemoryWrapper(wrapper->bind_memory_id); + // if (memory_wrapper) + // { + // memory_wrapper->bound_buffers.erase(wrapper); + // } + // device_address_tracker_.RemoveBuffer(wrapper); state_table_.VisitWrappers([&wrapper, this](vulkan_wrappers::AccelerationStructureKHRWrapper* acc_wrapper) { @@ -1648,17 +1648,17 @@ void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferW if (wrapper->handle_id == buffer.handle_id) { buffer.destroyed = true; -// auto [resource_util, created] = resource_utils.try_emplace( -// buffer.bind_device->handle_id, -// graphics::VulkanResourcesUtil(buffer.bind_device->handle, -// buffer.bind_device->physical_device->handle, -// buffer.bind_device->layer_table, -// *buffer.bind_device->physical_device->layer_table_ref, -// buffer.bind_device->physical_device->memory_properties)); -// buffer.bind_device->layer_table.GetBufferMemoryRequirements( -// buffer.bind_device->handle, buffer.handle, &buffer.memory_requirements); -// resource_util->second.ReadFromBufferResource( -// buffer.handle, buffer.created_size, 0, buffer.queue_family_index, buffer.bytes); + auto [resource_util, created] = resource_utils_.try_emplace( + buffer.bind_device->handle, + graphics::VulkanResourcesUtil(buffer.bind_device->handle, + buffer.bind_device->physical_device->handle, + buffer.bind_device->layer_table, + *buffer.bind_device->physical_device->layer_table_ref, + buffer.bind_device->physical_device->memory_properties)); + buffer.bind_device->layer_table.GetBufferMemoryRequirements( + buffer.bind_device->handle, buffer.handle, &buffer.memory_requirements); + resource_util->second.ReadFromBufferResource( + buffer.handle, buffer.created_size, 0, buffer.queue_family_index, buffer.bytes); } } } diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index a017d478f0..79cdcdf381 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -497,8 +497,10 @@ class VulkanStateTracker // Keeps track of device memories' device addresses std::unordered_map device_memory_addresses_map; - // Keeps track of buffer- and acceleration structures' device addresses + // Keeps track of buffer- and acceleration-structure device addresses encode::VulkanDeviceAddressTracker device_address_tracker_; + + std::map resource_utils_; }; GFXRECON_END_NAMESPACE(encode) From 6ad03f1a2a499fb29f458f70d757ee8d0c281ea3 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 10:57:01 +0200 Subject: [PATCH 08/18] Heaps of logic added to StateWriter --- framework/encode/vulkan_capture_manager.cpp | 2 +- .../encode/vulkan_device_address_tracker.cpp | 4 +- framework/encode/vulkan_state_writer.cpp | 506 +++++++++++++++++- framework/encode/vulkan_state_writer.h | 49 +- framework/format/format.h | 3 + 5 files changed, 552 insertions(+), 12 deletions(-) diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index 7b6a154538..9d1b3f0a3f 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -100,7 +100,7 @@ void VulkanCaptureManager::DestroyInstance() void VulkanCaptureManager::WriteTrackedState(util::FileOutputStream* file_stream, format::ThreadId thread_id) { - VulkanStateWriter state_writer(file_stream, GetCompressor(), thread_id); + VulkanStateWriter state_writer(file_stream, GetCompressor(), thread_id, [] { return GetUniqueId(); }); uint64_t n_blocks = state_tracker_->WriteState(&state_writer, GetCurrentFrame()); common_manager_->IncrementBlockIndex(n_blocks); } diff --git a/framework/encode/vulkan_device_address_tracker.cpp b/framework/encode/vulkan_device_address_tracker.cpp index ffc0dc16dd..751eefa0db 100644 --- a/framework/encode/vulkan_device_address_tracker.cpp +++ b/framework/encode/vulkan_device_address_tracker.cpp @@ -41,8 +41,8 @@ VulkanDeviceAddressTracker& VulkanDeviceAddressTracker::operator=(VulkanDeviceAd void swap(VulkanDeviceAddressTracker& lhs, VulkanDeviceAddressTracker& rhs) noexcept { std::lock(lhs.mutex_, rhs.mutex_); - std::lock_guard lock_lhs(lhs.mutex_, std::adopt_lock); - std::lock_guard lock_rhs(rhs.mutex_, std::adopt_lock); + std::lock_guard lock_lhs(lhs.mutex_, std::adopt_lock); + std::lock_guard lock_rhs(rhs.mutex_, std::adopt_lock); std::swap(lhs.buffer_addresses_, rhs.buffer_addresses_); std::swap(lhs.acceleration_structure_addresses_, rhs.acceleration_structure_addresses_); } diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index 5b724681a2..f2aab06c33 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -27,6 +27,7 @@ #include "encode/vulkan_state_info.h" #include "format/format_util.h" #include "util/logging.h" +#include "custom_vulkan_array_size_2d.h" #include #include @@ -78,11 +79,12 @@ static bool IsImageReadable(VkMemoryPropertyFlags property (memory_wrapper->mapped_size == VK_WHOLE_SIZE))))); } -VulkanStateWriter::VulkanStateWriter(util::FileOutputStream* output_stream, - util::Compressor* compressor, - format::ThreadId thread_id) : - output_stream_(output_stream), - compressor_(compressor), thread_id_(thread_id), encoder_(¶meter_stream_) +VulkanStateWriter::VulkanStateWriter(util::FileOutputStream* output_stream, + util::Compressor* compressor, + format::ThreadId thread_id, + std::function get_unique_id_fn) : + output_stream_(output_stream), compressor_(compressor), thread_id_(thread_id), encoder_(¶meter_stream_), + get_unique_id_(std::move(get_unique_id_fn)) { assert(output_stream != nullptr); } @@ -159,6 +161,7 @@ uint64_t VulkanStateWriter::WriteState(const VulkanStateTable& state_table, uint WritePipelineState(state_table); WriteAccelerationStructureKHRState(state_table); WriteTlasToBlasDependenciesMetadata(state_table); + WriteAccelerationStructureStateMetaCommands(state_table); StandardCreateWrite(state_table); StandardCreateWrite(state_table); @@ -1164,14 +1167,219 @@ void VulkanStateWriter::WriteBufferState(const VulkanStateTable& state_table) }); } +void VulkanStateWriter::BeginAccelerationStructuresSection(format::HandleId device_id, uint64_t max_resource_size) +{ + uint64_t max_staging_copy_size = 0; + + format::BeginResourceInitCommand begin_cmd{}; + begin_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(begin_cmd); + begin_cmd.meta_header.block_header.type = format::kMetaDataBlock; + begin_cmd.meta_header.meta_data_id = + format::MakeMetaDataId(format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kBeginResourceInitCommand); + begin_cmd.thread_id = thread_id_; + begin_cmd.device_id = device_id; + begin_cmd.max_resource_size = max_resource_size; + // Our buffers should not need staging copy as the memroy should be host visible and coherent + begin_cmd.max_copy_size = 0; + + output_stream_->Write(&begin_cmd, sizeof(begin_cmd)); + ++blocks_written_; +} + +void VulkanStateWriter::WriteASInputBufferState(ASInputBuffer& buffer) +{ + const VkAllocationCallbacks* alloc_callbacks = nullptr; + // Issue a new create call, creating the buffer we want, and replacing data + vulkan_wrappers::DeviceWrapper* device_wrapper = buffer.bind_device; + + VkBufferCreateInfo create_info{ VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + nullptr, + {}, + buffer.created_size, + buffer.usage, + VK_SHARING_MODE_EXCLUSIVE, + 1, + &buffer.queue_family_index }; + device_wrapper->layer_table.CreateBuffer(device_wrapper->handle, &create_info, nullptr, &buffer.handle); + + buffer.handle_id = get_unique_id_(); + // Write down this new call + parameter_stream_.Clear(); + encoder_.EncodeHandleIdValue(device_wrapper->handle_id); + EncodeStructPtr(&encoder_, &create_info); + EncodeStructPtr(&encoder_, alloc_callbacks); + encoder_.EncodeHandleIdPtr(&buffer.handle_id); + encoder_.EncodeEnumValue(VK_SUCCESS); + WriteFunctionCall(format::ApiCallId::ApiCall_vkCreateBuffer, ¶meter_stream_); +} + +void VulkanStateWriter::WriteASInputMemoryState(ASInputBuffer& buffer) +{ + const VkAllocationCallbacks* alloc_callbacks = nullptr; + vulkan_wrappers::DeviceWrapper* device_wrapper = buffer.bind_device; + + // Write allocate memory call + VkMemoryAllocateInfo allocate_info{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, nullptr }; + allocate_info.allocationSize = buffer.memory_requirements.size; + + VkMemoryAllocateFlagsInfo memory_allocate_flags_info{ VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, nullptr }; + memory_allocate_flags_info.flags = + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT | VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; + allocate_info.pNext = &memory_allocate_flags_info; + + uint32_t mem_type_index = 0; + VkMemoryPropertyFlags desired_flags{}; + VkMemoryPropertyFlags found_flags{}; + graphics::FindMemoryTypeIndex(buffer.bind_device->physical_device->memory_properties, + buffer.memory_requirements.memoryTypeBits, + desired_flags, + &mem_type_index, + &found_flags); + allocate_info.memoryTypeIndex = mem_type_index; + buffer.bind_memory = get_unique_id_(); + + device_wrapper->layer_table.AllocateMemory( + device_wrapper->handle, &allocate_info, alloc_callbacks, &buffer.bind_memory_handle); + device_wrapper->layer_table.BindBufferMemory(device_wrapper->handle, buffer.handle, buffer.bind_memory_handle, 0); + + VkBufferDeviceAddressInfoKHR pInfo{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, nullptr, buffer.handle }; + buffer.actual_address = device_wrapper->layer_table.GetBufferDeviceAddressKHR(device_wrapper->handle, &pInfo); + + VkDeviceMemoryOpaqueCaptureAddressInfo info{ VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + nullptr, + buffer.bind_memory_handle }; + + uint64_t address = 0; + if (device_wrapper->physical_device->instance_api_version >= VK_MAKE_VERSION(1, 2, 0)) + { + address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddress(device_wrapper->handle, &info); + } + else + { + address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddressKHR(device_wrapper->handle, &info); + } + + WriteSetOpaqueAddressCommand(device_wrapper->handle_id, buffer.bind_memory, address); + + parameter_stream_.Clear(); + encoder_.EncodeHandleIdValue(device_wrapper->handle_id); + EncodeStructPtr(&encoder_, &allocate_info); + EncodeStructPtr(&encoder_, alloc_callbacks); + encoder_.EncodeHandleIdPtr(&buffer.bind_memory); + encoder_.EncodeEnumValue(VK_SUCCESS); + WriteFunctionCall(format::ApiCallId::ApiCall_vkAllocateMemory, ¶meter_stream_); + parameter_stream_.Clear(); + + encoder_.EncodeHandleIdValue(buffer.bind_device->handle_id); + encoder_.EncodeHandleIdValue(buffer.handle_id); + encoder_.EncodeHandleIdValue(buffer.bind_memory); + encoder_.EncodeUInt64Value(0); + encoder_.EncodeEnumValue(VK_SUCCESS); + WriteFunctionCall(format::ApiCall_vkBindBufferMemory, ¶meter_stream_); + parameter_stream_.Clear(); + + // Manual encoding because tmp objects are not in the state table + encoder_.EncodeHandleIdValue(device_wrapper->handle_id); + encoder_.EncodeStructPtrPreamble(&pInfo); + encoder_.EncodeEnumValue(pInfo.sType); + EncodePNextStruct(&encoder_, pInfo.pNext); + encoder_.EncodeHandleIdValue(buffer.handle_id); + encoder_.EncodeVkDeviceAddressValue(buffer.actual_address); + + auto call_id = device_wrapper->physical_device->instance_api_version >= VK_MAKE_VERSION(1, 2, 0) + ? format::ApiCall_vkGetBufferDeviceAddress + : format::ApiCall_vkGetBufferDeviceAddressKHR; + WriteFunctionCall(call_id, ¶meter_stream_); + parameter_stream_.Clear(); +} + +void VulkanStateWriter::InitializeASInputBuffer(ASInputBuffer& buffer) +{ + parameter_stream_.Clear(); + + format::HandleId device_id = buffer.bind_device->handle_id; + + GFXRECON_CHECK_CONVERSION_DATA_LOSS(size_t, buffer.created_size); + + auto data_size = static_cast(buffer.created_size); + format::InitBufferCommandHeader upload_cmd{}; + + upload_cmd.meta_header.block_header.type = format::kMetaDataBlock; + upload_cmd.meta_header.meta_data_id = + format::MakeMetaDataId(format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kInitBufferCommand); + upload_cmd.thread_id = thread_id_; + upload_cmd.device_id = device_id; + upload_cmd.buffer_id = buffer.handle_id; + upload_cmd.data_size = data_size; + + const uint8_t* bytes = buffer.bytes.data(); + if (compressor_ != nullptr) + { + size_t compressed_size = compressor_->Compress(data_size, bytes, &compressed_parameter_buffer_, 0); + + if ((compressed_size > 0) && (compressed_size < data_size)) + { + upload_cmd.meta_header.block_header.type = format::BlockType::kCompressedMetaDataBlock; + + bytes = compressed_parameter_buffer_.data(); + data_size = compressed_size; + } + } + + // Calculate size of packet with compressed or uncompressed data size. + upload_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(upload_cmd) + data_size; + + output_stream_->Write(&upload_cmd, sizeof(upload_cmd)); + output_stream_->Write(bytes, data_size); + ++blocks_written_; +} + +void VulkanStateWriter::WriteDestroyASInputBuffer(ASInputBuffer& buffer) +{ + const VkAllocationCallbacks* callbacks = nullptr; + vulkan_wrappers::DeviceWrapper* device_wrapper = buffer.bind_device; + + parameter_stream_.Clear(); + + encoder_.EncodeHandleIdValue(buffer.bind_device->handle_id); + encoder_.EncodeHandleIdValue(buffer.handle_id); + EncodeStructPtr(&encoder_, callbacks); + WriteFunctionCall(format::ApiCall_vkDestroyBuffer, ¶meter_stream_); + device_wrapper->layer_table.DestroyBuffer(device_wrapper->handle, buffer.handle, callbacks); + + parameter_stream_.Clear(); + + encoder_.EncodeHandleIdValue(buffer.bind_device->handle_id); + encoder_.EncodeHandleIdValue(buffer.bind_memory); + EncodeStructPtr(&encoder_, callbacks); + WriteFunctionCall(format::ApiCall_vkFreeMemory, ¶meter_stream_); + device_wrapper->layer_table.FreeMemory(device_wrapper->handle, buffer.bind_memory_handle, callbacks); + + parameter_stream_.Clear(); +} + +void VulkanStateWriter::EndAccelerationStructureSection(format::HandleId device_id) +{ + format::EndResourceInitCommand end_cmd{}; + end_cmd.meta_header.block_header.size = format::GetMetaDataBlockBaseSize(end_cmd); + end_cmd.meta_header.block_header.type = format::kMetaDataBlock; + end_cmd.meta_header.meta_data_id = + format::MakeMetaDataId(format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kEndResourceInitCommand); + end_cmd.thread_id = thread_id_; + end_cmd.device_id = device_id; + + output_stream_->Write(&end_cmd, sizeof(end_cmd)); + ++blocks_written_; +} + void VulkanStateWriter::WriteTlasToBlasDependenciesMetadata(const VulkanStateTable& state_table) { state_table.VisitWrappers([&](const vulkan_wrappers::AccelerationStructureKHRWrapper* tlas) { assert(tlas != nullptr); - if (tlas->blas.size()) + if (!tlas->blas.empty()) { - format::ParentToChildDependencyHeader tlas_to_blas; + format::ParentToChildDependencyHeader tlas_to_blas{}; const size_t blas_count = tlas->blas.size(); tlas_to_blas.meta_header.block_header.type = format::BlockType::kMetaDataBlock; @@ -1196,6 +1404,288 @@ void VulkanStateWriter::WriteTlasToBlasDependenciesMetadata(const VulkanStateTab }); } +// Rename this to represent the whole acc structure prepare process +void VulkanStateWriter::WriteAccelerationStructureStateMetaCommands(const VulkanStateTable& state_table) +{ + struct AccelerationStructureCommands + { + std::vector blas_build; + std::vector tlas_build; + std::vector write_properties; + AccelerationStructureCopyCommandData copies; + std::vector blas_update; + std::vector tlas_update; + }; + + std::unordered_map commands; + size_t max_resource_size = 0; + + state_table.VisitWrappers([&](vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { + assert(wrapper != nullptr); + + auto& per_device_container = commands[wrapper->device_id]; + std::vector* build_container = nullptr; + std::vector* update_container = nullptr; + + if (wrapper->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) + { + build_container = &per_device_container.blas_build; + update_container = &per_device_container.blas_update; + } + else if (wrapper->type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR) + { + build_container = &per_device_container.tlas_build; + update_container = &per_device_container.tlas_update; + } + + if (wrapper->latest_build_command_) + { + build_container->push_back(&wrapper->latest_build_command_.value()); + for (const vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer& buffer : + wrapper->latest_build_command_->input_buffers) + { + max_resource_size = std::max(max_resource_size, buffer.bytes.size()); + } + } + + if (wrapper->latest_update_command_) + { + update_container->push_back(&wrapper->latest_update_command_.value()); + for (const vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer& buffer : + wrapper->latest_update_command_->input_buffers) + { + max_resource_size = std::max(max_resource_size, buffer.bytes.size()); + } + } + + if (wrapper->latest_copy_command_) + { + per_device_container.copies.infos.push_back(wrapper->latest_copy_command_.value().info); + } + + if (wrapper->latest_write_properties_command_) + { + per_device_container.write_properties.push_back( + { wrapper->latest_write_properties_command_->query_type, wrapper->handle_id }); + } + }); + + for (auto& [device, command] : commands) + { + BeginAccelerationStructuresSection(device, max_resource_size); + + for (auto& blas_build : command.blas_build) + { + WriteAccelerationStructureBuildState(device, *blas_build); + } + + for (const auto& cmd_properties : command.write_properties) + { + EncodeAccelerationStructureWritePropertiesCommand(device, cmd_properties); + } + + EncodeAccelerationStructureCopyMetaCommand(device, command.copies); + + for (auto& tlas_build : command.tlas_build) + { + WriteAccelerationStructureBuildState(device, *tlas_build); + } + + for (auto& blas_update : command.blas_update) + { + WriteAccelerationStructureBuildState(device, *blas_update); + } + + for (auto& tlas_update : command.tlas_update) + { + WriteAccelerationStructureBuildState(device, *tlas_update); + } + EndAccelerationStructureSection(device); + } +} + +void VulkanStateWriter::WriteAccelerationStructureBuildState(const gfxrecon::format::HandleId& device, + AccelerationStructureBuildCommandData& command) +{ + for (ASInputBuffer& buffer : command.input_buffers) + { + if (!buffer.destroyed) + { + continue; + } + WriteASInputBufferState(buffer); + WriteASInputMemoryState(buffer); + InitializeASInputBuffer(buffer); + } + + UpdateAddresses(command); + EncodeAccelerationStructureBuildMetaCommand(device, command); + for (ASInputBuffer& buffer : command.input_buffers) + { + if (!buffer.destroyed) + { + continue; + } + WriteDestroyASInputBuffer(buffer); + } +} + +void VulkanStateWriter::UpdateAddresses(AccelerationStructureBuildCommandData& command) +{ + if (command.input_buffers.empty()) + { + return; + } + + std::vector addresses_to_replace; + for (uint32_t g = 0; g < command.geometry_info.geometryCount; ++g) + { + switch (command.geometry_info.pGeometries[g].geometryType) + { + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_TRIANGLES_KHR: + { + addresses_to_replace = { + const_cast( + &command.geometry_info.pGeometries[g].geometry.triangles.vertexData.deviceAddress), + const_cast( + &command.geometry_info.pGeometries[g].geometry.triangles.indexData.deviceAddress), + const_cast( + &command.geometry_info.pGeometries[g].geometry.triangles.transformData.deviceAddress) + }; + break; + } + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_AABBS_KHR: + { + addresses_to_replace = { const_cast( + &command.geometry_info.pGeometries[g].geometry.aabbs.data.deviceAddress) }; + break; + } + case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_INSTANCES_KHR: + { + addresses_to_replace = { const_cast( + &command.geometry_info.pGeometries[g].geometry.instances.data.deviceAddress) }; + break; + } + case VK_GEOMETRY_TYPE_MAX_ENUM_KHR: + break; + } + } + // O(geometryCount * 3) at worst, improve? + for (VkDeviceAddress* address : addresses_to_replace) + { + for (const ASInputBuffer& buffer : command.input_buffers) + { + if (!buffer.destroyed) + { + continue; + } + if (buffer.capture_address == *address) + { + *address = buffer.actual_address; + } + } + } +} + +void VulkanStateWriter::EncodeAccelerationStructureBuildMetaCommand( + format::HandleId device_id, const AccelerationStructureBuildCommandData& command) +{ + using RangeInfoArraySize = encode::ArraySize2D; + + parameter_stream_.Clear(); + + format::VulkanMetaBuildAccelerationStructuresHeader header{}; + header.meta_header.block_header.type = format::BlockType::kMetaDataBlock; + header.meta_header.block_header.size = GetMetaDataBlockBaseSize(header); + header.meta_header.meta_data_id = format::MakeMetaDataId( + format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kVulkanBuildAccelerationStructuresCommand); + + encoder_.EncodeHandleIdValue(device_id); + + EncodeStructArray(&encoder_, &command.geometry_info, 1); + + const VkAccelerationStructureBuildRangeInfoKHR* ptr = command.build_range_infos.data(); + EncodeStructArray2D(&encoder_, &ptr, RangeInfoArraySize(VK_NULL_HANDLE, 1, &command.geometry_info, &ptr)); + + header.meta_header.block_header.size += parameter_stream_.GetDataSize(); + output_stream_->Write(&header, sizeof(header)); + output_stream_->Write(parameter_stream_.GetData(), parameter_stream_.GetDataSize()); + parameter_stream_.Clear(); + + ++blocks_written_; +} + +void VulkanStateWriter::EncodeAccelerationStructureCopyMetaCommand(format::HandleId device_id, + const AccelerationStructureCopyCommandData& command) +{ + parameter_stream_.Clear(); + + format::VulkanCopyAccelerationStructuresCommandHeader header{}; + header.meta_header.block_header.type = format::BlockType::kMetaDataBlock; + header.meta_header.block_header.size = GetMetaDataBlockBaseSize(header); + header.meta_header.meta_data_id = format::MakeMetaDataId( + format::ApiFamilyId::ApiFamily_Vulkan, format::MetaDataType::kVulkanCopyAccelerationStructuresCommand); + + encoder_.EncodeHandleIdValue(device_id); + EncodeStructArray(&encoder_, command.infos.data(), command.infos.size()); + + header.meta_header.block_header.size += parameter_stream_.GetDataSize(); + + output_stream_->Write(&header, sizeof(header)); + output_stream_->Write(parameter_stream_.GetData(), parameter_stream_.GetDataSize()); + + parameter_stream_.Clear(); + + ++blocks_written_; +} + +void VulkanStateWriter::EncodeAccelerationStructureWritePropertiesCommand( + format::HandleId device_id, const AccelerationStructureWritePropertiesCommandData& command) +{ + parameter_stream_.Clear(); + + format::VulkanWriteAccelerationStructuresPropertiesCommandHeader header{}; + + header.meta_header.block_header.type = format::BlockType::kMetaDataBlock; + header.meta_header.block_header.size = GetMetaDataBlockBaseSize(header); + header.meta_header.meta_data_id = + format::MakeMetaDataId(format::ApiFamilyId::ApiFamily_Vulkan, + format::MetaDataType::kVulkanWriteAccelerationStructuresPropertiesCommand); + + encoder_.EncodeHandleIdValue(device_id); + encoder_.EncodeEnumValue(command.query_type); + encoder_.EncodeHandleIdValue(command.acceleration_structure); + + header.meta_header.block_header.size += parameter_stream_.GetDataSize(); + + output_stream_->Write(&header, sizeof(header)); + output_stream_->Write(parameter_stream_.GetData(), parameter_stream_.GetDataSize()); + + parameter_stream_.Clear(); + + ++blocks_written_; +} + +void VulkanStateWriter::WriteGetAccelerationStructureDeviceAddressKHRCall( + const VulkanStateTable& state_table, const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) +{ + parameter_stream_.Clear(); + auto device_wrapper = state_table.GetDeviceWrapper(wrapper->device_id); + encoder_.EncodeVulkanHandleValue(device_wrapper->handle); + VkAccelerationStructureDeviceAddressInfoKHR info{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, + nullptr, + wrapper->handle }; + + EncodeStructPtr(&encoder_, &info); + encoder_.EncodeVkDeviceAddressValue(vulkan_wrappers::GetDeviceTable(device_wrapper->handle) + ->GetAccelerationStructureDeviceAddressKHR(device_wrapper->handle, &info)); + WriteFunctionCall(format::ApiCallId::ApiCall_vkGetAccelerationStructureDeviceAddressKHR, ¶meter_stream_); + parameter_stream_.Clear(); +} + void VulkanStateWriter::WriteRayTracingPipelinePropertiesState(const VulkanStateTable& state_table) { state_table.VisitWrappers([&](const vulkan_wrappers::PhysicalDeviceWrapper* wrapper) { @@ -1227,8 +1717,8 @@ void VulkanStateWriter::WriteAccelerationStructureKHRState(const VulkanStateTabl // vkCreateAccelerationStructKHR through the VkAccelerationStructureCreateInfoKHR::deviceAddress. WriteSetOpaqueAddressCommand(wrapper->device_id, wrapper->handle_id, wrapper->address); } - WriteFunctionCall(wrapper->create_call_id, wrapper->create_parameters.get()); + WriteGetAccelerationStructureDeviceAddressKHRCall(state_table, wrapper); }); } diff --git a/framework/encode/vulkan_state_writer.h b/framework/encode/vulkan_state_writer.h index ee6e6c9b73..2a8f02d6ba 100644 --- a/framework/encode/vulkan_state_writer.h +++ b/framework/encode/vulkan_state_writer.h @@ -47,7 +47,10 @@ GFXRECON_BEGIN_NAMESPACE(encode) class VulkanStateWriter { public: - VulkanStateWriter(util::FileOutputStream* output_stream, util::Compressor* compressor, format::ThreadId thread_id); + VulkanStateWriter(util::FileOutputStream* output_stream, + util::Compressor* compressor, + format::ThreadId thread_id, + std::function get_unique_id_fn); // Returns number of blocks written to the output_stream. uint64_t WriteState(const VulkanStateTable& state_table, uint64_t frame_number); @@ -348,6 +351,47 @@ class VulkanStateWriter void WriteTlasToBlasDependenciesMetadata(const VulkanStateTable& state_table); + void WriteAccelerationStructureStateMetaCommands(const VulkanStateTable& state_table); + + using AccelerationStructureBuildCommandData = + vulkan_wrappers::AccelerationStructureKHRWrapper::AccelerationStructureKHRBuildCommandData; + + void WriteAccelerationStructureBuildState(const gfxrecon::format::HandleId& device, + AccelerationStructureBuildCommandData& command); + + void EncodeAccelerationStructureBuildMetaCommand(format::HandleId device_id, + const AccelerationStructureBuildCommandData& command); + + struct AccelerationStructureCopyCommandData + { + std::vector infos; + }; + void EncodeAccelerationStructureCopyMetaCommand(format::HandleId device_id, + const AccelerationStructureCopyCommandData& command); + + struct AccelerationStructureWritePropertiesCommandData + { + VkQueryType query_type; + format::HandleId acceleration_structure; + }; + void + EncodeAccelerationStructureWritePropertiesCommand(format::HandleId device_id, + const AccelerationStructureWritePropertiesCommandData& command); + + void + WriteGetAccelerationStructureDeviceAddressKHRCall(const VulkanStateTable& state_table, + const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); + + void UpdateAddresses(AccelerationStructureBuildCommandData& command); + + using ASInputBuffer = vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer; + void BeginAccelerationStructuresSection(format::HandleId device_id, uint64_t max_resource_size); + void WriteASInputBufferState(ASInputBuffer& buffer); + void WriteASInputMemoryState(ASInputBuffer& buffer); + void InitializeASInputBuffer(ASInputBuffer& buffer); + void WriteDestroyASInputBuffer(ASInputBuffer& buffer); + void EndAccelerationStructureSection(format::HandleId device_id); + private: util::FileOutputStream* output_stream_; util::Compressor* compressor_; @@ -356,6 +400,9 @@ class VulkanStateWriter util::MemoryOutputStream parameter_stream_; ParameterEncoder encoder_; uint64_t blocks_written_{ 0 }; + + // helper to retrieve a unique id, e.g. from a CaptureManager + std::function get_unique_id_; }; GFXRECON_END_NAMESPACE(encode) diff --git a/framework/format/format.h b/framework/format/format.h index 00791ffad0..b590b7d7bb 100644 --- a/framework/format/format.h +++ b/framework/format/format.h @@ -156,6 +156,9 @@ enum class MetaDataType : uint16_t kReserved31 = 31, kSetEnvironmentVariablesCommand = 32, kViewRelativeLocation = 33, + kVulkanBuildAccelerationStructuresCommand = 33, + kVulkanCopyAccelerationStructuresCommand = 34, + kVulkanWriteAccelerationStructuresPropertiesCommand = 35, }; // MetaDataId is stored in the capture file and its type must be uint32_t to avoid breaking capture file compatibility. From e66b21dcc58cc3a92fd4bac9a628c9853f9a930b Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 12:16:42 +0200 Subject: [PATCH 09/18] minor round of corrections and improvements --- framework/encode/vulkan_state_tracker.cpp | 19 +++++----- framework/encode/vulkan_state_writer.cpp | 44 +++++++++++------------ framework/encode/vulkan_state_writer.h | 2 +- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 0ec1e505b2..f14eeec749 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -397,28 +397,29 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( vulkan_wrappers::AccelerationStructureKHRWrapper::AccelerationStructureKHRBuildCommandData dst_command{}; // Extract command information for 1 AccelerationStructure - for (uint32_t geometry = 0; geometry < p_infos[info].geometryCount; ++geometry) + for (uint32_t g = 0; g < p_infos[info].geometryCount; ++g) { - // TODO: pGeometries vs ppGeometries -> handle both cases + auto geometry = + p_infos[info].pGeometries != nullptr ? p_infos[info].pGeometries + g : p_infos[info].ppGeometries[g]; std::vector to_extract; - switch (p_infos[info].pGeometries[geometry].geometryType) + switch (geometry->geometryType) { case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_TRIANGLES_KHR: { - to_extract = { p_infos[info].pGeometries[geometry].geometry.triangles.vertexData.deviceAddress, - p_infos[info].pGeometries[geometry].geometry.triangles.indexData.deviceAddress, - p_infos[info].pGeometries[geometry].geometry.triangles.transformData.deviceAddress }; + to_extract = { geometry->geometry.triangles.vertexData.deviceAddress, + geometry->geometry.triangles.indexData.deviceAddress, + geometry->geometry.triangles.transformData.deviceAddress }; break; } case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_AABBS_KHR: { - to_extract = { p_infos[info].pGeometries[geometry].geometry.aabbs.data.deviceAddress }; + to_extract = { geometry->geometry.aabbs.data.deviceAddress }; break; } case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_INSTANCES_KHR: { - to_extract = { p_infos[info].pGeometries[geometry].geometry.instances.data.deviceAddress }; + to_extract = { geometry->geometry.instances.data.deviceAddress }; break; } case VK_GEOMETRY_TYPE_MAX_ENUM_KHR: @@ -486,7 +487,7 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( address, primitive_count, pp_buildRange_infos[info]->primitiveOffset }; - cmd_buf_wrapper->tlas_build_info_map.emplace_back(std::make_pair(wrapper, std::move(tlas_info))); + cmd_buf_wrapper->tlas_build_info_map.emplace_back(wrapper, tlas_info); } } } diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index f2aab06c33..f4e69ce345 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -1537,51 +1537,49 @@ void VulkanStateWriter::UpdateAddresses(AccelerationStructureBuildCommandData& c return; } - std::vector addresses_to_replace; + std::unordered_map addresses_to_replace; + auto insert_address = [&addresses_to_replace](const VkDeviceAddress& address) { + addresses_to_replace[address] = const_cast(&address); + }; + for (uint32_t g = 0; g < command.geometry_info.geometryCount; ++g) { - switch (command.geometry_info.pGeometries[g].geometryType) + auto geometry = command.geometry_info.pGeometries != nullptr ? command.geometry_info.pGeometries + g + : command.geometry_info.ppGeometries[g]; + + switch (geometry->geometryType) { case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_TRIANGLES_KHR: { - addresses_to_replace = { - const_cast( - &command.geometry_info.pGeometries[g].geometry.triangles.vertexData.deviceAddress), - const_cast( - &command.geometry_info.pGeometries[g].geometry.triangles.indexData.deviceAddress), - const_cast( - &command.geometry_info.pGeometries[g].geometry.triangles.transformData.deviceAddress) - }; + insert_address(geometry->geometry.triangles.vertexData.deviceAddress); + insert_address(geometry->geometry.triangles.indexData.deviceAddress); + insert_address(geometry->geometry.triangles.transformData.deviceAddress); break; } case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_AABBS_KHR: { - addresses_to_replace = { const_cast( - &command.geometry_info.pGeometries[g].geometry.aabbs.data.deviceAddress) }; + insert_address(geometry->geometry.aabbs.data.deviceAddress); break; } case VkGeometryTypeKHR::VK_GEOMETRY_TYPE_INSTANCES_KHR: { - addresses_to_replace = { const_cast( - &command.geometry_info.pGeometries[g].geometry.instances.data.deviceAddress) }; + insert_address(geometry->geometry.instances.data.deviceAddress); break; } case VK_GEOMETRY_TYPE_MAX_ENUM_KHR: break; } } - // O(geometryCount * 3) at worst, improve? - for (VkDeviceAddress* address : addresses_to_replace) + + for (const ASInputBuffer& buffer : command.input_buffers) { - for (const ASInputBuffer& buffer : command.input_buffers) + if (buffer.destroyed) { - if (!buffer.destroyed) - { - continue; - } - if (buffer.capture_address == *address) + auto it = addresses_to_replace.find(buffer.capture_address); + if (it != addresses_to_replace.end()) { - *address = buffer.actual_address; + VkDeviceAddress* address = it->second; + *address = buffer.actual_address; } } } diff --git a/framework/encode/vulkan_state_writer.h b/framework/encode/vulkan_state_writer.h index 2a8f02d6ba..dea3300882 100644 --- a/framework/encode/vulkan_state_writer.h +++ b/framework/encode/vulkan_state_writer.h @@ -382,7 +382,7 @@ class VulkanStateWriter WriteGetAccelerationStructureDeviceAddressKHRCall(const VulkanStateTable& state_table, const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper); - void UpdateAddresses(AccelerationStructureBuildCommandData& command); + static void UpdateAddresses(AccelerationStructureBuildCommandData& command); using ASInputBuffer = vulkan_wrappers::AccelerationStructureKHRWrapper::ASInputBuffer; void BeginAccelerationStructuresSection(format::HandleId device_id, uint64_t max_resource_size); From b1f181d99ebaf90c0c46ea49b49bb57475aa892e Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 13:04:44 +0200 Subject: [PATCH 10/18] acceleration-structure meta-data hooked up in replay/file-processor --- framework/decode/file_processor.cpp | 71 ++++++++++++++++++++++++ framework/encode/vulkan_state_writer.cpp | 14 ++--- 2 files changed, 77 insertions(+), 8 deletions(-) diff --git a/framework/decode/file_processor.cpp b/framework/decode/file_processor.cpp index 304fe3bc2f..7d39369a7b 100644 --- a/framework/decode/file_processor.cpp +++ b/framework/decode/file_processor.cpp @@ -1842,6 +1842,77 @@ bool FileProcessor::ProcessMetaData(const format::BlockHeader& block_header, for decoder->DispatchSetEnvironmentVariablesCommand(header, env_string); } } + else if (meta_data_type == format::MetaDataType::kVulkanBuildAccelerationStructuresCommand) + { + format::VulkanMetaBuildAccelerationStructuresHeader header{}; + size_t parameter_buffer_size = static_cast(block_header.size) - sizeof(meta_data_id); + success = ReadParameterBuffer(parameter_buffer_size); + + if (success) + { + for (auto decoder : decoders_) + { + if (decoder->SupportsMetaDataId(meta_data_id)) + { + DecodeAllocator::Begin(); + + decoder->DispatchVulkanAccelerationStructuresBuildMetaCommand(parameter_buffer_.data(), + parameter_buffer_size); + + DecodeAllocator::End(); + } + } + } + else + { + HandleBlockReadError(kErrorReadingBlockHeader, + "Failed to read acceleration structure init meta-data block header"); + } + } + else if (meta_data_type == format::MetaDataType::kVulkanCopyAccelerationStructuresCommand) + { + format::VulkanCopyAccelerationStructuresCommandHeader header{}; + size_t parameter_buffer_size = static_cast(block_header.size) - sizeof(meta_data_id); + success = ReadParameterBuffer(parameter_buffer_size); + + if (success) + { + for (auto decoder : decoders_) + { + if (decoder->SupportsMetaDataId(meta_data_id)) + { + DecodeAllocator::Begin(); + + decoder->DispatchVulkanAccelerationStructuresCopyMetaCommand(parameter_buffer_.data(), + parameter_buffer_size); + + DecodeAllocator::End(); + } + } + } + } + else if (meta_data_type == format::MetaDataType::kVulkanWriteAccelerationStructuresPropertiesCommand) + { + format::VulkanCopyAccelerationStructuresCommandHeader header{}; + size_t parameter_buffer_size = static_cast(block_header.size) - sizeof(meta_data_id); + success = ReadParameterBuffer(parameter_buffer_size); + + if (success) + { + for (auto decoder : decoders_) + { + if (decoder->SupportsMetaDataId(meta_data_id)) + { + DecodeAllocator::Begin(); + + decoder->DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(parameter_buffer_.data(), + parameter_buffer_size); + + DecodeAllocator::End(); + } + } + } + } else { if ((meta_data_type == format::MetaDataType::kReserved23) || diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index f4e69ce345..d9ab1197bb 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -1509,24 +1509,22 @@ void VulkanStateWriter::WriteAccelerationStructureBuildState(const gfxrecon::for { for (ASInputBuffer& buffer : command.input_buffers) { - if (!buffer.destroyed) + if (buffer.destroyed) { - continue; + WriteASInputBufferState(buffer); + WriteASInputMemoryState(buffer); + InitializeASInputBuffer(buffer); } - WriteASInputBufferState(buffer); - WriteASInputMemoryState(buffer); - InitializeASInputBuffer(buffer); } UpdateAddresses(command); EncodeAccelerationStructureBuildMetaCommand(device, command); for (ASInputBuffer& buffer : command.input_buffers) { - if (!buffer.destroyed) + if (buffer.destroyed) { - continue; + WriteDestroyASInputBuffer(buffer); } - WriteDestroyASInputBuffer(buffer); } } From 74b6f7d07941ebb9e02cfd403fecbd3c0f7dc5a1 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 15:55:59 +0200 Subject: [PATCH 11/18] re-doing some changes after rebase --- framework/format/format.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/framework/format/format.h b/framework/format/format.h index b590b7d7bb..8d7d728841 100644 --- a/framework/format/format.h +++ b/framework/format/format.h @@ -150,15 +150,12 @@ enum class MetaDataType : uint16_t kReserved25 = 25, kDx12RuntimeInfoCommand = 26, kParentToChildDependency = 27, - kReserved28 = 28, - kReserved29 = 29, - kReserved30 = 30, + kVulkanBuildAccelerationStructuresCommand = 28, + kVulkanCopyAccelerationStructuresCommand = 29, + kVulkanWriteAccelerationStructuresPropertiesCommand = 30, kReserved31 = 31, kSetEnvironmentVariablesCommand = 32, kViewRelativeLocation = 33, - kVulkanBuildAccelerationStructuresCommand = 33, - kVulkanCopyAccelerationStructuresCommand = 34, - kVulkanWriteAccelerationStructuresPropertiesCommand = 35, }; // MetaDataId is stored in the capture file and its type must be uint32_t to avoid breaking capture file compatibility. @@ -666,6 +663,21 @@ struct SetEnvironmentVariablesCommand // containing a list of environment variables and their values }; +struct VulkanMetaBuildAccelerationStructuresHeader +{ + format::MetaDataHeader meta_header; +}; + +struct VulkanWriteAccelerationStructuresPropertiesCommandHeader +{ + format::MetaDataHeader meta_header; +}; + +struct VulkanCopyAccelerationStructuresCommandHeader +{ + format::MetaDataHeader meta_header; +}; + // Restore size_t to normal behavior. #undef size_t From 8bf872dc2365a808b65f4bd7c70523f7d8ac9678 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 16:09:33 +0200 Subject: [PATCH 12/18] minor refactor --- framework/encode/vulkan_state_tracker.cpp | 37 ++++++++++++----------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index f14eeec749..70fa15e375 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -384,23 +384,24 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( } auto cmd_buf_wrapper = vulkan_wrappers::GetWrapper(command_buffer); - for (uint32_t info = 0; info < info_count; ++info) + for (uint32_t i = 0; i < info_count; ++i) { - if (p_infos[info].dstAccelerationStructure == VK_NULL_HANDLE || p_infos[info].geometryCount == 0 || - (p_infos[info].pGeometries == nullptr && p_infos[info].ppGeometries == nullptr)) + const VkAccelerationStructureBuildGeometryInfoKHR& build_info = p_infos[i]; + + if (build_info.dstAccelerationStructure == VK_NULL_HANDLE || build_info.geometryCount == 0 || + (build_info.pGeometries == nullptr && build_info.ppGeometries == nullptr)) { continue; } auto wrapper = vulkan_wrappers::GetWrapper( - p_infos[info].dstAccelerationStructure); + build_info.dstAccelerationStructure); vulkan_wrappers::AccelerationStructureKHRWrapper::AccelerationStructureKHRBuildCommandData dst_command{}; // Extract command information for 1 AccelerationStructure - for (uint32_t g = 0; g < p_infos[info].geometryCount; ++g) + for (uint32_t g = 0; g < build_info.geometryCount; ++g) { - auto geometry = - p_infos[info].pGeometries != nullptr ? p_infos[info].pGeometries + g : p_infos[info].ppGeometries[g]; + auto geometry = build_info.pGeometries != nullptr ? build_info.pGeometries + g : build_info.ppGeometries[g]; std::vector to_extract; switch (geometry->geometryType) @@ -450,41 +451,41 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( buffer.usage = target_buffer_wrapper->usage; } - dst_command.geometry_info = p_infos[info]; + dst_command.geometry_info = build_info; VkAccelerationStructureGeometryKHR* unwrapped = gfxrecon::encode::vulkan_trackers::TrackStructs( - p_infos[info].pGeometries, p_infos[info].geometryCount, dst_command.geometry_info_memory); + build_info.pGeometries, build_info.geometryCount, dst_command.geometry_info_memory); dst_command.geometry_info.pGeometries = unwrapped; dst_command.build_range_infos.insert(dst_command.build_range_infos.end(), - pp_buildRange_infos[info], - pp_buildRange_infos[info] + p_infos[info].geometryCount); + pp_buildRange_infos[i], + pp_buildRange_infos[i] + build_info.geometryCount); } - if (p_infos[info].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) + if (build_info.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR) { wrapper->latest_build_command_ = std::move(dst_command); } - else if (p_infos[info].mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) + else if (build_info.mode == VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR) { wrapper->latest_update_command_ = std::move(dst_command); } wrapper->blas.clear(); - for (uint32_t g = 0; g < p_infos[info].geometryCount; ++g) + for (uint32_t g = 0; g < build_info.geometryCount; ++g) { - if (p_infos[info].pGeometries[g].geometryType != VK_GEOMETRY_TYPE_INSTANCES_KHR) + if (build_info.pGeometries[g].geometryType != VK_GEOMETRY_TYPE_INSTANCES_KHR) { continue; } - const VkDeviceAddress address = p_infos[info].pGeometries[g].geometry.instances.data.deviceAddress; - const uint32_t primitive_count = pp_buildRange_infos[info]->primitiveCount; + const VkDeviceAddress address = build_info.pGeometries[g].geometry.instances.data.deviceAddress; + const uint32_t primitive_count = pp_buildRange_infos[i]->primitiveCount; // According to spec both address and primitiveCount can be 0. // Nothing to handle in these cases. if (address && primitive_count) { const vulkan_wrappers::CommandBufferWrapper::tlas_build_info tlas_info = { - address, primitive_count, pp_buildRange_infos[info]->primitiveOffset + address, primitive_count, pp_buildRange_infos[i]->primitiveOffset }; cmd_buf_wrapper->tlas_build_info_map.emplace_back(wrapper, tlas_info); From fa5f6b1bc78de2af4adf6743728ed846e3e920d6 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 16:25:03 +0200 Subject: [PATCH 13/18] minor cleanup --- framework/encode/vulkan_device_address_tracker.h | 4 +--- framework/encode/vulkan_state_tracker.cpp | 8 +------- framework/encode/vulkan_state_tracker.h | 4 ---- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/framework/encode/vulkan_device_address_tracker.h b/framework/encode/vulkan_device_address_tracker.h index 7ba16210d1..917a13f94a 100644 --- a/framework/encode/vulkan_device_address_tracker.h +++ b/framework/encode/vulkan_device_address_tracker.h @@ -52,9 +52,7 @@ class VulkanDeviceAddressTracker /** * @brief Track an existing buffer by its VkDeviceAddress. * - * @param buffer a provided buffer-handle - * @param address a device-address - * @param size buffer-size in bytes + * @param wrapper provided buffer-wrapper. */ void TrackBuffer(const vulkan_wrappers::BufferWrapper* wrapper); diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 70fa15e375..84dd2102b9 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -1628,13 +1628,7 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrap void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferWrapper* wrapper) { - assert(wrapper != nullptr); - // auto memory_wrapper = state_table_.GetDeviceMemoryWrapper(wrapper->bind_memory_id); - // if (memory_wrapper) - // { - // memory_wrapper->bound_buffers.erase(wrapper); - // } - // + GFXRECON_ASSERT(wrapper != nullptr); device_address_tracker_.RemoveBuffer(wrapper); state_table_.VisitWrappers([&wrapper, this](vulkan_wrappers::AccelerationStructureKHRWrapper* acc_wrapper) { diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index 79cdcdf381..d081084a73 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -391,10 +391,6 @@ class VulkanStateTracker VkAccelerationStructureKHR accel_struct, VkDeviceAddress address); - // void TrackTLASBuildCommand(VkCommandBuffer command_buffer, - // uint32_t info_count, - // const VkAccelerationStructureBuildGeometryInfoKHR* infos, - // const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); void TrackAccelerationStructureBuildCommand(VkCommandBuffer command_buffer, uint32_t info_count, From 9f7faca576d2f7020f24b31484efd660751bad1d Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Wed, 16 Oct 2024 16:43:38 +0200 Subject: [PATCH 14/18] use correct GetBufferDeviceAddress / KHR --- framework/encode/vulkan_state_writer.cpp | 29 ++++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index d9ab1197bb..c743e39d8f 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -1242,21 +1242,27 @@ void VulkanStateWriter::WriteASInputMemoryState(ASInputBuffer& buffer) device_wrapper->handle, &allocate_info, alloc_callbacks, &buffer.bind_memory_handle); device_wrapper->layer_table.BindBufferMemory(device_wrapper->handle, buffer.handle, buffer.bind_memory_handle, 0); - VkBufferDeviceAddressInfoKHR pInfo{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, nullptr, buffer.handle }; - buffer.actual_address = device_wrapper->layer_table.GetBufferDeviceAddressKHR(device_wrapper->handle, &pInfo); - - VkDeviceMemoryOpaqueCaptureAddressInfo info{ VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, - nullptr, - buffer.bind_memory_handle }; + VkBufferDeviceAddressInfoKHR buffer_address_info{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR, + nullptr, + buffer.handle }; + VkDeviceMemoryOpaqueCaptureAddressInfo memory_opaque_address_info{ + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, nullptr, buffer.bind_memory_handle + }; uint64_t address = 0; if (device_wrapper->physical_device->instance_api_version >= VK_MAKE_VERSION(1, 2, 0)) { - address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddress(device_wrapper->handle, &info); + buffer.actual_address = + device_wrapper->layer_table.GetBufferDeviceAddress(device_wrapper->handle, &buffer_address_info); + address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddress(device_wrapper->handle, + &memory_opaque_address_info); } else { - address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddressKHR(device_wrapper->handle, &info); + buffer.actual_address = + device_wrapper->layer_table.GetBufferDeviceAddressKHR(device_wrapper->handle, &buffer_address_info); + address = device_wrapper->layer_table.GetDeviceMemoryOpaqueCaptureAddressKHR(device_wrapper->handle, + &memory_opaque_address_info); } WriteSetOpaqueAddressCommand(device_wrapper->handle_id, buffer.bind_memory, address); @@ -1280,12 +1286,11 @@ void VulkanStateWriter::WriteASInputMemoryState(ASInputBuffer& buffer) // Manual encoding because tmp objects are not in the state table encoder_.EncodeHandleIdValue(device_wrapper->handle_id); - encoder_.EncodeStructPtrPreamble(&pInfo); - encoder_.EncodeEnumValue(pInfo.sType); - EncodePNextStruct(&encoder_, pInfo.pNext); + encoder_.EncodeStructPtrPreamble(&buffer_address_info); + encoder_.EncodeEnumValue(buffer_address_info.sType); + EncodePNextStruct(&encoder_, buffer_address_info.pNext); encoder_.EncodeHandleIdValue(buffer.handle_id); encoder_.EncodeVkDeviceAddressValue(buffer.actual_address); - auto call_id = device_wrapper->physical_device->instance_api_version >= VK_MAKE_VERSION(1, 2, 0) ? format::ApiCall_vkGetBufferDeviceAddress : format::ApiCall_vkGetBufferDeviceAddressKHR; From 58ecfc85d3de833689ece2ef59502ff18396bfa3 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Thu, 17 Oct 2024 12:25:15 +0200 Subject: [PATCH 15/18] remove a comment --- framework/decode/vulkan_replay_consumer_base.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index 3a18f6d5fb..95e3e5463e 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -9397,7 +9397,6 @@ void VulkanReplayConsumerBase::ProcessBuildVulkanAccelerationStructuresMetaComma auto allocator = device_info->allocator.get(); GFXRECON_ASSERT(allocator != nullptr); - // TODO: really questioning "SupportsOpaqueDeviceAddresses" condition if (allocator->SupportsOpaqueDeviceAddresses() || !loading_trim_state_) { return; From b3be6cf83d9c2810f09318a496158dd8fcbe810a Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Thu, 17 Oct 2024 12:50:58 +0200 Subject: [PATCH 16/18] corrections for 32-bit, formatting --- framework/decode/api_decoder.h | 18 +++++++++--------- framework/encode/vulkan_capture_manager.cpp | 4 ++-- .../encode/vulkan_device_address_tracker.cpp | 4 ++-- .../encode/vulkan_device_address_tracker.h | 4 ++-- framework/encode/vulkan_state_tracker.cpp | 4 ++-- framework/encode/vulkan_state_tracker.h | 8 ++++---- framework/encode/vulkan_state_writer.cpp | 13 +++++++------ 7 files changed, 28 insertions(+), 27 deletions(-) diff --git a/framework/decode/api_decoder.h b/framework/decode/api_decoder.h index 4279a294d2..f7a37b5927 100644 --- a/framework/decode/api_decoder.h +++ b/framework/decode/api_decoder.h @@ -186,28 +186,28 @@ class ApiDecoder std::vector& geometry_descs, const uint8_t* build_inputs_data) = 0; - virtual void DispatchGetDxgiAdapterInfo(const format::DxgiAdapterInfoCommandHeader& adapter_info_header) {}; + virtual void DispatchGetDxgiAdapterInfo(const format::DxgiAdapterInfoCommandHeader& adapter_info_header){}; - virtual void DispatchGetDx12RuntimeInfo(const format::Dx12RuntimeInfoCommandHeader& runtime_info_header) {}; + virtual void DispatchGetDx12RuntimeInfo(const format::Dx12RuntimeInfoCommandHeader& runtime_info_header){}; - virtual void SetCurrentBlockIndex(uint64_t block_index) {}; + virtual void SetCurrentBlockIndex(uint64_t block_index){}; - virtual void SetCurrentApiCallId(format::ApiCallId api_call_id) {}; + virtual void SetCurrentApiCallId(format::ApiCallId api_call_id){}; virtual void DispatchSetTlasToBlasDependencyCommand(format::HandleId tlas, - const std::vector& blases) {}; + const std::vector& blases){}; virtual void DispatchSetEnvironmentVariablesCommand(format::SetEnvironmentVariablesCommand& header, - const char* env_string) {}; + const char* env_string){}; virtual void DispatchVulkanAccelerationStructuresBuildMetaCommand(const uint8_t* parameter_buffer, - size_t buffer_size) {}; + size_t buffer_size){}; virtual void DispatchVulkanAccelerationStructuresCopyMetaCommand(const uint8_t* parameter_buffer, - size_t buffer_size) {}; + size_t buffer_size){}; virtual void DispatchVulkanAccelerationStructuresWritePropertiesMetaCommand(const uint8_t* parameter_buffer, - size_t buffer_size) {}; + size_t buffer_size){}; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index 9d1b3f0a3f..a789a44f24 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -962,8 +962,8 @@ VulkanCaptureManager::OverrideCreateAccelerationStructureKHR(VkDevice device_table->GetAccelerationStructureDeviceAddressKHR(device_unwrapped, &address_info); accel_struct_wrapper->device_id = device_wrapper->handle_id; - accel_struct_wrapper->address = address; - accel_struct_wrapper->type = modified_create_info->type; + accel_struct_wrapper->address = address; + accel_struct_wrapper->type = modified_create_info->type; if (IsCaptureModeTrack()) { diff --git a/framework/encode/vulkan_device_address_tracker.cpp b/framework/encode/vulkan_device_address_tracker.cpp index 751eefa0db..cb8d04b0f6 100644 --- a/framework/encode/vulkan_device_address_tracker.cpp +++ b/framework/encode/vulkan_device_address_tracker.cpp @@ -99,7 +99,7 @@ VkBuffer VulkanDeviceAddressTracker::GetBufferByDeviceAddress(VkDeviceAddress de // not found if (address_it == buffer_addresses_.begin()) { - return nullptr; + return VK_NULL_HANDLE; } // decrement iterator, now pointing to the first VkDeviceAddress that is lower than device_address @@ -120,7 +120,7 @@ VkAccelerationStructureKHR VulkanDeviceAddressTracker::GetAccelerationStructureByDeviceAddress(VkDeviceAddress device_address) const { std::shared_lock lock(mutex_); - auto address_it = acceleration_structure_addresses_.find(device_address); + auto address_it = acceleration_structure_addresses_.find(device_address); if (address_it != acceleration_structure_addresses_.end()) { return address_it->second; diff --git a/framework/encode/vulkan_device_address_tracker.h b/framework/encode/vulkan_device_address_tracker.h index 917a13f94a..5d27e593a8 100644 --- a/framework/encode/vulkan_device_address_tracker.h +++ b/framework/encode/vulkan_device_address_tracker.h @@ -97,8 +97,8 @@ class VulkanDeviceAddressTracker private: struct buffer_item_t { - VkBuffer handle = VK_NULL_HANDLE; - size_t size = 0; + VkBuffer handle = VK_NULL_HANDLE; + VkDeviceSize size = 0; }; //! use a sorted (BST-based) map to look-up ranges std::map buffer_addresses_; diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 84dd2102b9..37ebbabc5a 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -1766,8 +1766,8 @@ void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t comm // VkAccelerationStructureInstanceKHR::accelerationStructureReference referes to const uint64_t as_reference = instances[b].accelerationStructureReference; - if(auto as_wrapper = vulkan_wrappers::GetWrapper( - device_address_tracker_.GetAccelerationStructureByDeviceAddress(as_reference))) + if (auto as_wrapper = vulkan_wrappers::GetWrapper( + device_address_tracker_.GetAccelerationStructureByDeviceAddress(as_reference))) { tlas_wrapper->blas.push_back(as_wrapper); } diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index d081084a73..cc8a350477 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -392,10 +392,10 @@ class VulkanStateTracker VkDeviceAddress address); void - TrackAccelerationStructureBuildCommand(VkCommandBuffer command_buffer, - uint32_t info_count, - const VkAccelerationStructureBuildGeometryInfoKHR* infos, - const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); + TrackAccelerationStructureBuildCommand(VkCommandBuffer command_buffer, + uint32_t info_count, + const VkAccelerationStructureBuildGeometryInfoKHR* infos, + const VkAccelerationStructureBuildRangeInfoKHR* const* pp_buildRange_infos); void TrackDeviceMemoryDeviceAddress(VkDevice device, VkDeviceMemory memory, VkDeviceAddress address); diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index c743e39d8f..bb22a2b861 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -83,7 +83,8 @@ VulkanStateWriter::VulkanStateWriter(util::FileOutputStream* output_st util::Compressor* compressor, format::ThreadId thread_id, std::function get_unique_id_fn) : - output_stream_(output_stream), compressor_(compressor), thread_id_(thread_id), encoder_(¶meter_stream_), + output_stream_(output_stream), + compressor_(compressor), thread_id_(thread_id), encoder_(¶meter_stream_), get_unique_id_(std::move(get_unique_id_fn)) { assert(output_stream != nullptr); @@ -1414,12 +1415,12 @@ void VulkanStateWriter::WriteAccelerationStructureStateMetaCommands(const Vulkan { struct AccelerationStructureCommands { - std::vector blas_build; - std::vector tlas_build; + std::vector blas_build; + std::vector tlas_build; std::vector write_properties; AccelerationStructureCopyCommandData copies; - std::vector blas_update; - std::vector tlas_update; + std::vector blas_update; + std::vector tlas_update; }; std::unordered_map commands; @@ -1428,7 +1429,7 @@ void VulkanStateWriter::WriteAccelerationStructureStateMetaCommands(const Vulkan state_table.VisitWrappers([&](vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { assert(wrapper != nullptr); - auto& per_device_container = commands[wrapper->device_id]; + auto& per_device_container = commands[wrapper->device_id]; std::vector* build_container = nullptr; std::vector* update_container = nullptr; From 3670d52375d75b3fe38738bcf0e1f1e54338c087 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 22 Oct 2024 12:30:47 +0200 Subject: [PATCH 17/18] capture: need device-address-tracker per device --- framework/encode/vulkan_capture_manager.cpp | 6 ++--- framework/encode/vulkan_handle_wrapper_util.h | 11 ++++++++++ framework/encode/vulkan_handle_wrappers.h | 4 ++-- framework/encode/vulkan_state_tracker.cpp | 22 +++++++++++-------- framework/encode/vulkan_state_tracker.h | 2 +- framework/encode/vulkan_state_writer.cpp | 12 +++++----- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index a789a44f24..6ad521cf9e 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -961,9 +961,9 @@ VulkanCaptureManager::OverrideCreateAccelerationStructureKHR(VkDevice VkDeviceAddress address = device_table->GetAccelerationStructureDeviceAddressKHR(device_unwrapped, &address_info); - accel_struct_wrapper->device_id = device_wrapper->handle_id; - accel_struct_wrapper->address = address; - accel_struct_wrapper->type = modified_create_info->type; + accel_struct_wrapper->device = device_wrapper; + accel_struct_wrapper->address = address; + accel_struct_wrapper->type = modified_create_info->type; if (IsCaptureModeTrack()) { diff --git a/framework/encode/vulkan_handle_wrapper_util.h b/framework/encode/vulkan_handle_wrapper_util.h index f8cf42b751..e10d753a5c 100644 --- a/framework/encode/vulkan_handle_wrapper_util.h +++ b/framework/encode/vulkan_handle_wrapper_util.h @@ -327,6 +327,17 @@ inline void CreateWrappedHandle( } } +template <> +inline void CreateWrappedHandle(VkDevice device, + NoParentWrapper::HandleType, + VkCommandPool* handle, + PFN_GetHandleId get_id) +{ + CreateWrappedNonDispatchHandle(handle, get_id); + auto pool_wrapper = GetWrapper(*handle); + pool_wrapper->device = GetWrapper(device); +} + template <> inline void CreateWrappedHandle(VkDevice parent, VkCommandPool co_parent, diff --git a/framework/encode/vulkan_handle_wrappers.h b/framework/encode/vulkan_handle_wrappers.h index bb3fedf45f..2c61f38944 100644 --- a/framework/encode/vulkan_handle_wrappers.h +++ b/framework/encode/vulkan_handle_wrappers.h @@ -506,8 +506,8 @@ struct SwapchainKHRWrapper : public HandleWrapper struct AccelerationStructureKHRWrapper : public HandleWrapper { // State tracking info for buffers with device addresses. - format::HandleId device_id{ format::kNullHandleId }; - VkDeviceAddress address{ 0 }; + DeviceWrapper* device{ nullptr }; + VkDeviceAddress address{ 0 }; // List of BLASes this AS references. Used only while tracking. std::vector blas; diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 37ebbabc5a..b9113dde3d 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -341,7 +341,7 @@ void VulkanStateTracker::TrackBufferDeviceAddress(VkDevice device, VkBuffer buff wrapper->device_id = vulkan_wrappers::GetWrappedId(device); wrapper->address = address; - device_address_tracker_.TrackBuffer(wrapper); + device_address_trackers_[device].TrackBuffer(wrapper); } void VulkanStateTracker::TrackOpaqueBufferDeviceAddress(VkDevice device, @@ -384,6 +384,8 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( } auto cmd_buf_wrapper = vulkan_wrappers::GetWrapper(command_buffer); + auto device_wrapper = cmd_buf_wrapper->parent_pool->device; + for (uint32_t i = 0; i < info_count; ++i) { const VkAccelerationStructureBuildGeometryInfoKHR& build_info = p_infos[i]; @@ -435,7 +437,7 @@ void VulkanStateTracker::TrackAccelerationStructureBuildCommand( } auto target_buffer_wrapper = vulkan_wrappers::GetWrapper( - device_address_tracker_.GetBufferByDeviceAddress(address)); + device_address_trackers_[device_wrapper->handle].GetBufferByDeviceAddress(address)); GFXRECON_ASSERT(target_buffer_wrapper != nullptr); @@ -1453,11 +1455,11 @@ void VulkanStateTracker::TrackAccelerationStructureKHRDeviceAddress(VkDevice { assert((device != VK_NULL_HANDLE) && (accel_struct != VK_NULL_HANDLE)); - auto wrapper = vulkan_wrappers::GetWrapper(accel_struct); - wrapper->device_id = vulkan_wrappers::GetWrappedId(device); - wrapper->address = address; + auto wrapper = vulkan_wrappers::GetWrapper(accel_struct); + wrapper->device = vulkan_wrappers::GetWrapper(device); + wrapper->address = address; - device_address_tracker_.TrackAccelerationStructure(wrapper); + device_address_trackers_[device].TrackAccelerationStructure(wrapper); } void VulkanStateTracker::TrackDeviceMemoryDeviceAddress(VkDevice device, VkDeviceMemory memory, VkDeviceAddress address) @@ -1629,7 +1631,7 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrap void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferWrapper* wrapper) { GFXRECON_ASSERT(wrapper != nullptr); - device_address_tracker_.RemoveBuffer(wrapper); + device_address_trackers_[wrapper->bind_device->handle].RemoveBuffer(wrapper); state_table_.VisitWrappers([&wrapper, this](vulkan_wrappers::AccelerationStructureKHRWrapper* acc_wrapper) { GFXRECON_ASSERT(acc_wrapper); @@ -1665,7 +1667,7 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::AccelerationStructureKHRW { assert(wrapper != nullptr); wrapper->create_parameters = nullptr; - device_address_tracker_.RemoveAccelerationStructure(wrapper); + device_address_trackers_[wrapper->device->handle].RemoveAccelerationStructure(wrapper); } void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t command_buffer_count, @@ -1680,6 +1682,7 @@ void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t comm { const vulkan_wrappers::CommandBufferWrapper* cmd_buf_wrapper = vulkan_wrappers::GetWrapper(command_buffers[c]); + const auto device_wrapper = cmd_buf_wrapper->parent_pool->device; for (const auto& tlas_build_info : cmd_buf_wrapper->tlas_build_info_map) { @@ -1767,7 +1770,8 @@ void VulkanStateTracker::TrackTlasToBlasDependencies(uint32_t comm const uint64_t as_reference = instances[b].accelerationStructureReference; if (auto as_wrapper = vulkan_wrappers::GetWrapper( - device_address_tracker_.GetAccelerationStructureByDeviceAddress(as_reference))) + device_address_trackers_[device_wrapper->handle].GetAccelerationStructureByDeviceAddress( + as_reference))) { tlas_wrapper->blas.push_back(as_wrapper); } diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index cc8a350477..7f162bb8ce 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -494,7 +494,7 @@ class VulkanStateTracker std::unordered_map device_memory_addresses_map; // Keeps track of buffer- and acceleration-structure device addresses - encode::VulkanDeviceAddressTracker device_address_tracker_; + std::unordered_map device_address_trackers_; std::map resource_utils_; }; diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index bb22a2b861..6c7a4e44c5 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -1429,9 +1429,9 @@ void VulkanStateWriter::WriteAccelerationStructureStateMetaCommands(const Vulkan state_table.VisitWrappers([&](vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { assert(wrapper != nullptr); - auto& per_device_container = commands[wrapper->device_id]; - std::vector* build_container = nullptr; - std::vector* update_container = nullptr; + auto& per_device_container = commands[wrapper->device->handle_id]; + std::vector* build_container = nullptr; + std::vector* update_container = nullptr; if (wrapper->type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR) { @@ -1675,7 +1675,7 @@ void VulkanStateWriter::WriteGetAccelerationStructureDeviceAddressKHRCall( const VulkanStateTable& state_table, const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { parameter_stream_.Clear(); - auto device_wrapper = state_table.GetDeviceWrapper(wrapper->device_id); + auto device_wrapper = wrapper->device; encoder_.EncodeVulkanHandleValue(device_wrapper->handle); VkAccelerationStructureDeviceAddressInfoKHR info{ VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, nullptr, @@ -1712,12 +1712,12 @@ void VulkanStateWriter::WriteAccelerationStructureKHRState(const VulkanStateTabl state_table.VisitWrappers([&](const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { assert(wrapper != nullptr); - if ((wrapper->device_id != format::kNullHandleId) && (wrapper->address != 0)) + if ((wrapper->device != nullptr) && (wrapper->address != 0)) { // If the acceleration struct has a device address, write the 'set opaque address' command before writing // the API call to create the acceleration struct. The address will need to be passed to // vkCreateAccelerationStructKHR through the VkAccelerationStructureCreateInfoKHR::deviceAddress. - WriteSetOpaqueAddressCommand(wrapper->device_id, wrapper->handle_id, wrapper->address); + WriteSetOpaqueAddressCommand(wrapper->device->handle_id, wrapper->handle_id, wrapper->address); } WriteFunctionCall(wrapper->create_call_id, wrapper->create_parameters.get()); WriteGetAccelerationStructureDeviceAddressKHRCall(state_table, wrapper); From 86df9bf1847098b772ddfa70f8b4a7a578a9ba36 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Tue, 22 Oct 2024 14:53:05 +0200 Subject: [PATCH 18/18] nullptr-check before accessing device-wrappers --- framework/encode/vulkan_state_tracker.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index b9113dde3d..52afe7219c 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -1631,7 +1631,11 @@ void VulkanStateTracker::DestroyState(vulkan_wrappers::DeviceMemoryWrapper* wrap void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferWrapper* wrapper) { GFXRECON_ASSERT(wrapper != nullptr); - device_address_trackers_[wrapper->bind_device->handle].RemoveBuffer(wrapper); + + if (wrapper != nullptr && wrapper->bind_device != nullptr) + { + device_address_trackers_[wrapper->bind_device->handle].RemoveBuffer(wrapper); + } state_table_.VisitWrappers([&wrapper, this](vulkan_wrappers::AccelerationStructureKHRWrapper* acc_wrapper) { GFXRECON_ASSERT(acc_wrapper); @@ -1666,6 +1670,7 @@ void gfxrecon::encode::VulkanStateTracker::DestroyState(vulkan_wrappers::BufferW void VulkanStateTracker::DestroyState(vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { assert(wrapper != nullptr); + assert(wrapper->device != nullptr); wrapper->create_parameters = nullptr; device_address_trackers_[wrapper->device->handle].RemoveAccelerationStructure(wrapper); }