diff --git a/android/framework/decode/CMakeLists.txt b/android/framework/decode/CMakeLists.txt index ef329df82..789e3866f 100644 --- a/android/framework/decode/CMakeLists.txt +++ b/android/framework/decode/CMakeLists.txt @@ -44,13 +44,13 @@ target_sources(gfxrecon_decode ${GFXRECON_SOURCE_DIR}/framework/decode/value_decoder.h ${GFXRECON_SOURCE_DIR}/framework/decode/metadata_consumer_base.h ${GFXRECON_SOURCE_DIR}/framework/decode/marker_consumer_base.h - ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_buffer_tracker.h - ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_buffer_tracker.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_consumer_base.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_decoder_base.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_decoder_base.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_default_allocator.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_default_allocator.cpp + ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_device_address_tracker.h + ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_device_address_tracker.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_captured_swapchain.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_captured_swapchain.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_enum_util.h diff --git a/framework/decode/CMakeLists.txt b/framework/decode/CMakeLists.txt index d2164cd54..1e41c32e0 100644 --- a/framework/decode/CMakeLists.txt +++ b/framework/decode/CMakeLists.txt @@ -141,12 +141,12 @@ target_sources(gfxrecon_decode $<$:${CMAKE_CURRENT_LIST_DIR}/dx12_browse_consumer.h> $<$:${CMAKE_CURRENT_LIST_DIR}/dx12_dump_resources.h> $<$:${CMAKE_CURRENT_LIST_DIR}/dx12_dump_resources.cpp> - ${CMAKE_CURRENT_LIST_DIR}/vulkan_buffer_tracker.h - ${CMAKE_CURRENT_LIST_DIR}/vulkan_buffer_tracker.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_decoder_base.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_decoder_base.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_default_allocator.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_default_allocator.cpp + ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.h + ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_captured_swapchain.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_captured_swapchain.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_json_consumer_base.h diff --git a/framework/decode/vulkan_buffer_tracker.cpp b/framework/decode/vulkan_device_address_tracker.cpp similarity index 50% rename from framework/decode/vulkan_buffer_tracker.cpp rename to framework/decode/vulkan_device_address_tracker.cpp index e017bee9c..2eeccc105 100644 --- a/framework/decode/vulkan_buffer_tracker.cpp +++ b/framework/decode/vulkan_device_address_tracker.cpp @@ -21,42 +21,59 @@ ** DEALINGS IN THE SOFTWARE. */ -#include "decode/vulkan_buffer_tracker.h" +#include "decode/vulkan_device_address_tracker.h" GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(decode) -VulkanBufferTracker::VulkanBufferTracker(const VulkanObjectInfoTable& object_info_table) : +VulkanDeviceAddressTracker::VulkanDeviceAddressTracker(const VulkanObjectInfoTable& object_info_table) : _object_info_table(object_info_table) {} -void decode::VulkanBufferTracker::TrackBuffer(const decode::BufferInfo* buffer_info) +void decode::VulkanDeviceAddressTracker::TrackBuffer(const decode::BufferInfo* buffer_info) { - if (buffer_info != nullptr) + if (buffer_info != nullptr && buffer_info->capture_address != 0) { - if (buffer_info->capture_address != 0) - { - _capture_addresses[buffer_info->capture_address] = buffer_info->capture_id; - } + _buffer_capture_addresses[buffer_info->capture_address] = buffer_info->capture_id; } } -void VulkanBufferTracker::RemoveBuffer(const BufferInfo* buffer_info) +void VulkanDeviceAddressTracker::RemoveBuffer(const BufferInfo* buffer_info) { if (buffer_info != nullptr) { - _capture_addresses.erase(buffer_info->capture_address); + _buffer_capture_addresses.erase(buffer_info->capture_address); + } +} + +void VulkanDeviceAddressTracker::TrackAccelerationStructure( + const AccelerationStructureKHRInfo* acceleration_structure_info) +{ + if (acceleration_structure_info != nullptr && acceleration_structure_info->capture_address != 0) + { + _acceleration_structure_capture_addresses[acceleration_structure_info->capture_address] = + acceleration_structure_info->capture_id; + } +} + +void VulkanDeviceAddressTracker::RemoveAccelerationStructure( + const AccelerationStructureKHRInfo* acceleration_structure_info) +{ + if (acceleration_structure_info != nullptr) + { + _acceleration_structure_capture_addresses.erase(acceleration_structure_info->capture_id); } } const decode::BufferInfo* -decode::VulkanBufferTracker::GetBufferByCaptureDeviceAddress(VkDeviceAddress capture_address) const +decode::VulkanDeviceAddressTracker::GetBufferByCaptureDeviceAddress(VkDeviceAddress capture_address) const { - return GetBufferInfo(capture_address, _capture_addresses); + return GetBufferInfo(capture_address, _buffer_capture_addresses); } -const BufferInfo* VulkanBufferTracker::GetBufferInfo(VkDeviceAddress device_address, - const VulkanBufferTracker::device_address_map_t& address_map) const +const BufferInfo* +VulkanDeviceAddressTracker::GetBufferInfo(VkDeviceAddress device_address, + const VulkanDeviceAddressTracker::buffer_address_map_t& address_map) const { if (!address_map.empty()) { @@ -89,5 +106,23 @@ const BufferInfo* VulkanBufferTracker::GetBufferInfo(VkDeviceAddress return nullptr; } +const AccelerationStructureKHRInfo* +VulkanDeviceAddressTracker::GetAccelerationStructureByCaptureDeviceAddress(VkDeviceAddress capture_address) const +{ + auto address_it = _acceleration_structure_capture_addresses.find(capture_address); + if (address_it != _acceleration_structure_capture_addresses.end()) + { + const auto& [found_address, acceleration_structure_handle] = *address_it; + const AccelerationStructureKHRInfo* found_acceleration_structure_info = + _object_info_table.GetAccelerationStructureKHRInfo(acceleration_structure_handle); + + if (found_acceleration_structure_info != nullptr) + { + return found_acceleration_structure_info; + } + } + return nullptr; +} + GFXRECON_END_NAMESPACE(decode) GFXRECON_END_NAMESPACE(gfxrecon) \ No newline at end of file diff --git a/framework/decode/vulkan_buffer_tracker.h b/framework/decode/vulkan_device_address_tracker.h similarity index 57% rename from framework/decode/vulkan_buffer_tracker.h rename to framework/decode/vulkan_device_address_tracker.h index 18eeca415..36b92f43c 100644 --- a/framework/decode/vulkan_buffer_tracker.h +++ b/framework/decode/vulkan_device_address_tracker.h @@ -31,18 +31,18 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(decode) -class VulkanBufferTracker +class VulkanDeviceAddressTracker { public: - explicit VulkanBufferTracker(const VulkanObjectInfoTable& object_info_table); + explicit VulkanDeviceAddressTracker(const VulkanObjectInfoTable& object_info_table); //! prevent copying - VulkanBufferTracker(const VulkanBufferTracker&) = delete; + VulkanDeviceAddressTracker(const VulkanDeviceAddressTracker&) = delete; //! allow moving - VulkanBufferTracker(VulkanBufferTracker&&) = default; + VulkanDeviceAddressTracker(VulkanDeviceAddressTracker&&) = default; - ~VulkanBufferTracker() = default; + ~VulkanDeviceAddressTracker() = default; /** * @brief Track an existing buffer by its capture-time VkDeviceAddress. @@ -58,23 +58,48 @@ class VulkanBufferTracker */ void RemoveBuffer(const BufferInfo* buffer_info); + /** + * @brief Track an existing acceleration-structure by its capture-time VkDeviceAddress. + * + * @param acceleration_structure_info a provided acceleration-structure containing a handle and associated + * device-addresses. + */ + void TrackAccelerationStructure(const AccelerationStructureKHRInfo* acceleration_structure_info); + + /** + * @brief RemoveAccelerationStructure will stop tracking of a currently tracked acceleration-structure. + * + * @param acceleration_structure_info a provided acceleration-structure-info. + */ + void RemoveAccelerationStructure(const AccelerationStructureKHRInfo* acceleration_structure_info); + /** * @brief Retrieve a buffer by providing a capture-time VkDeviceAddress within its range. * - * @param replay_address a capture-time VkDeviceAddress pointing inside a buffer. + * @param capture_address a capture-time VkDeviceAddress pointing inside a buffer. * @return a const-pointer to a found BufferInfo or nullptr. */ [[nodiscard]] const BufferInfo* GetBufferByCaptureDeviceAddress(VkDeviceAddress capture_address) const; + /** + * @brief Retrieve an acceleration-structure by providing a capture-time VkDeviceAddress. + * + * @param capture_address a capture-time VkDeviceAddress for an acceleration-structure. + * @return a const-pointer to a found AccelerationStructureKHRInfo or nullptr. + */ + [[nodiscard]] const AccelerationStructureKHRInfo* + GetAccelerationStructureByCaptureDeviceAddress(VkDeviceAddress capture_address) const; + private: //! use a sorted (BST-based) map - using device_address_map_t = std::map; + using buffer_address_map_t = std::map; [[nodiscard]] const BufferInfo* GetBufferInfo(VkDeviceAddress device_address, - const device_address_map_t& address_map) const; + const buffer_address_map_t& address_map) const; - const VulkanObjectInfoTable& _object_info_table; - device_address_map_t _capture_addresses; + const VulkanObjectInfoTable& _object_info_table; + buffer_address_map_t _buffer_capture_addresses; + std::unordered_map _acceleration_structure_capture_addresses; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/decode/vulkan_object_info.h b/framework/decode/vulkan_object_info.h index be21b1b93..217a256c3 100644 --- a/framework/decode/vulkan_object_info.h +++ b/framework/decode/vulkan_object_info.h @@ -223,7 +223,6 @@ typedef VulkanObjectInfo DisplayModeKHRInfo; typedef VulkanObjectInfo DebugReportCallbackEXTInfo; typedef VulkanObjectInfo IndirectCommandsLayoutNVInfo; typedef VulkanObjectInfo DebugUtilsMessengerEXTInfo; -typedef VulkanObjectInfo AccelerationStructureKHRInfo; typedef VulkanObjectInfo AccelerationStructureNVInfo; typedef VulkanObjectInfo PerformanceConfigurationINTELInfo; typedef VulkanObjectInfo MicromapEXTInfo; @@ -687,6 +686,12 @@ struct DescriptorSetInfo : public VulkanPoolObjectInfo DescriptorBindingsInfo descriptors; }; +struct AccelerationStructureKHRInfo : public VulkanObjectInfo +{ + VkDeviceAddress capture_address = 0; + VkDeviceAddress replay_address = 0; +}; + // // Handle alias types for extension handle types that have been promoted to core types. // diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index bba3d31ef..9d22a8ab4 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -4442,6 +4442,7 @@ VkResult VulkanReplayConsumerBase::OverrideBindBufferMemory(PFN_vkBindBufferMemo if (result == VK_SUCCESS && !allocator->SupportsOpaqueDeviceAddresses()) { + // TODO: this might be not necessary // On fast-forwarded traces buffer device addresses might be missing (no GetBufferDeviceAddress calls) // Fill out this data based on original memory device address and binding offset auto entry = device_info->opaque_addresses.find(memory_info->capture_id); @@ -4459,7 +4460,7 @@ VkResult VulkanReplayConsumerBase::OverrideBindBufferMemory(PFN_vkBindBufferMemo GetDeviceTable(device_info->handle)->GetBufferDeviceAddress(device_info->handle, &info); // track buffer-addresses - GetBufferTracker(device_info->handle).TrackBuffer(buffer_info); + GetDeviceAddressTracker(device_info->handle).TrackBuffer(buffer_info); } } return result; @@ -4871,7 +4872,7 @@ void VulkanReplayConsumerBase::OverrideDestroyBuffer( allocator->DestroyBuffer(buffer, GetAllocationCallbacks(pAllocator), allocator_data); // remove from device-address tracking - GetBufferTracker(device_info->handle).RemoveBuffer(buffer_info); + GetDeviceAddressTracker(device_info->handle).RemoveBuffer(buffer_info); } VkResult @@ -7518,6 +7519,141 @@ VkResult VulkanReplayConsumerBase::OverrideCreateAccelerationStructureKHR( return result; } +void VulkanReplayConsumerBase::OverrideDestroyAccelerationStructureKHR( + PFN_vkDestroyAccelerationStructureKHR func, + const DeviceInfo* device_info, + const AccelerationStructureKHRInfo* acceleration_structure_info, + StructPointerDecoder* pAllocator) +{ + GFXRECON_ASSERT(device_info != nullptr); + + auto allocator = device_info->allocator.get(); + GFXRECON_ASSERT(allocator != nullptr); + + VkAccelerationStructureKHR acceleration_structure = VK_NULL_HANDLE; + VulkanResourceAllocator::ResourceData allocator_data = 0; + + if (acceleration_structure_info != nullptr) + { + acceleration_structure = acceleration_structure_info->handle; + + // remove from address-tracking + GetDeviceAddressTracker(device_info->handle).RemoveAccelerationStructure(acceleration_structure_info); + } + func(device_info->handle, acceleration_structure, GetAllocationCallbacks(pAllocator)); +} + +void VulkanReplayConsumerBase::OverrideCmdBuildAccelerationStructuresKHR( + PFN_vkCmdBuildAccelerationStructuresKHR func, + CommandBufferInfo* command_buffer_info, + uint32_t infoCount, + StructPointerDecoder* pInfos, + StructPointerDecoder* ppBuildRangeInfos) +{ + DeviceInfo* device_info = object_info_table_.GetDeviceInfo(command_buffer_info->parent_id); + VkCommandBuffer command_buffer = command_buffer_info->handle; + VkAccelerationStructureBuildGeometryInfoKHR* build_geometry_infos = pInfos->GetPointer(); + VkAccelerationStructureBuildRangeInfoKHR** build_range_infos = ppBuildRangeInfos->GetPointer(); + + auto& address_tracker = GetDeviceAddressTracker(device_info->handle); + + auto address_remap = [&address_tracker](VkDeviceAddress& capture_address) { + auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(capture_address); + + // TODO: we 'should' find that buffer here, check what's missing + if (buffer_info != nullptr && buffer_info->replay_address != 0) + { + uint64_t offset = capture_address - buffer_info->capture_address; + + // in-place address-remap via const-cast + capture_address = buffer_info->replay_address + offset; + } + }; + + for (uint32_t i = 0; i < infoCount; ++i) + { + auto& build_geometry_info = build_geometry_infos[i]; + + for (uint32_t j = 0; j < build_geometry_info.geometryCount; ++j) + { + auto geometry = const_cast(build_geometry_info.pGeometries != nullptr + ? build_geometry_info.pGeometries + j + : build_geometry_info.ppGeometries[j]); + switch (geometry->geometryType) + { + case VK_GEOMETRY_TYPE_TRIANGLES_KHR: + { + auto& triangles = geometry->geometry.triangles; + address_remap(triangles.vertexData.deviceAddress); + address_remap(triangles.indexData.deviceAddress); + break; + } + case VK_GEOMETRY_TYPE_AABBS_KHR: + { + auto& aabbs = geometry->geometry.aabbs; + address_remap(aabbs.data.deviceAddress); + break; + } + case VK_GEOMETRY_TYPE_INSTANCES_KHR: + { + auto& instances = geometry->geometry.instances; + address_remap(instances.data.deviceAddress); + // TODO: replace VkAccelerationStructureInstanceKHR::accelerationStructureReference inside buffer + // (issue #1526) + break; + } + default: + GFXRECON_LOG_ERROR( + "OverrideCmdBuildAccelerationStructuresKHR: unhandled case in switch-statement: %d", + geometry->geometryType); + break; + } + } + } + func(command_buffer, infoCount, build_geometry_infos, build_range_infos); +} + +void VulkanReplayConsumerBase::OverrideCmdCopyAccelerationStructureKHR( + PFN_vkCmdCopyAccelerationStructureKHR func, + CommandBufferInfo* command_buffer_info, + StructPointerDecoder* pInfo) +{ + DeviceInfo* device_info = object_info_table_.GetDeviceInfo(command_buffer_info->parent_id); + if (device_info->allocator->SupportsOpaqueDeviceAddresses()) + { + VkCommandBuffer command_buffer = command_buffer_info->handle; + VkCopyAccelerationStructureInfoKHR* info = pInfo->GetPointer(); + func(command_buffer, info); + } + else if (!loading_trim_state_) + { + // TODO: raytracing delegate-hook (issue #1526) + } +} + +void VulkanReplayConsumerBase::OverrideCmdWriteAccelerationStructuresPropertiesKHR( + PFN_vkCmdWriteAccelerationStructuresPropertiesKHR func, + CommandBufferInfo* command_buffer_info, + uint32_t count, + HandlePointerDecoder* pAccelerationStructures, + VkQueryType queryType, + gfxrecon::decode::QueryPoolInfo* query_pool_info, + uint32_t firstQuery) +{ + DeviceInfo* device_info = object_info_table_.GetDeviceInfo(command_buffer_info->parent_id); + if (device_info->allocator->SupportsOpaqueDeviceAddresses()) + { + VkCommandBuffer command_buffer = command_buffer_info->handle; + const VkAccelerationStructureKHR* acceleration_structs = pAccelerationStructures->GetHandlePointer(); + VkQueryPool query_pool = query_pool_info->handle; + func(command_buffer, count, acceleration_structs, queryType, query_pool, firstQuery); + } + else if (!loading_trim_state_) + { + // TODO: raytracing delegate-hook (issue #1526) + } +} + VkResult VulkanReplayConsumerBase::OverrideCreateRayTracingPipelinesKHR( PFN_vkCreateRayTracingPipelinesKHR func, VkResult original_result, @@ -7830,17 +7966,18 @@ VkDeviceAddress VulkanReplayConsumerBase::OverrideGetBufferDeviceAddress( else { // opaque device-addresses are expected to match - GFXRECON_ASSERT(original_result == replay_device_address); + GFXRECON_ASSERT(original_result == replay_device_address) } // keep track of old/new addresses in any case format::HandleId buffer = pInfo->GetMetaStructPointer()->buffer; BufferInfo* buffer_info = GetObjectInfoTable().GetBufferInfo(buffer); + GFXRECON_ASSERT(buffer_info != nullptr); buffer_info->capture_address = original_result; buffer_info->replay_address = replay_device_address; // track device-addresses - GetBufferTracker(device).TrackBuffer(buffer_info); + GetDeviceAddressTracker(device).TrackBuffer(buffer_info); return replay_device_address; } @@ -7859,17 +7996,31 @@ void VulkanReplayConsumerBase::OverrideGetAccelerationStructureDeviceAddressKHR( "replay. The replay device does not support this feature, so replay may fail."); } + VkDevice device = device_info->handle; + const VkAccelerationStructureDeviceAddressInfoKHR* address_info = pInfo->GetPointer(); + + VkDeviceAddress replay_address = func(device, address_info); + + AccelerationStructureKHRInfo* acceleration_structure_info = + GetObjectInfoTable().GetAccelerationStructureKHRInfo(pInfo->GetMetaStructPointer()->accelerationStructure); + GFXRECON_ASSERT(acceleration_structure_info != nullptr); + acceleration_structure_info->capture_address = original_result; + acceleration_structure_info->replay_address = replay_address; + + // track device-address + GetDeviceAddressTracker(device).TrackAccelerationStructure(acceleration_structure_info); + if (!device_info->allocator->SupportsOpaqueDeviceAddresses()) { GFXRECON_LOG_WARNING_ONCE( "The captured application used vkGetAccelerationStructureDeviceAddressKHR. The specified replay option '-m " "rebind' may not support the replay of captured device addresses, so replay may fail."); } - - VkDevice device = device_info->handle; - const VkAccelerationStructureDeviceAddressInfoKHR* address_info = pInfo->GetPointer(); - - func(device, address_info); + else + { + // opaque addresses should match + GFXRECON_ASSERT(original_result == replay_address); + } } VkResult @@ -8194,23 +8345,41 @@ void VulkanReplayConsumerBase::OverrideCmdTraceRaysKHR( { if (command_buffer_info != nullptr) { - VkCommandBuffer commandBuffer = command_buffer_info->handle; - const VkStridedDeviceAddressRegionKHR* in_pRaygenShaderBindingTable = pRaygenShaderBindingTable->GetPointer(); - const VkStridedDeviceAddressRegionKHR* in_pMissShaderBindingTable = pMissShaderBindingTable->GetPointer(); - const VkStridedDeviceAddressRegionKHR* in_pHitShaderBindingTable = pHitShaderBindingTable->GetPointer(); - const VkStridedDeviceAddressRegionKHR* in_pCallableShaderBindingTable = - pCallableShaderBindingTable->GetPointer(); - - // assert we can identify the buffer(s) by their device-address - const DeviceInfo* device_info = GetObjectInfoTable().GetDeviceInfo(command_buffer_info->parent_id); - const auto& buffer_tracker = GetBufferTracker(device_info->handle); - GFXRECON_ASSERT(buffer_tracker.GetBufferByCaptureDeviceAddress(in_pRaygenShaderBindingTable->deviceAddress)); - GFXRECON_ASSERT(in_pMissShaderBindingTable->size == 0 || - buffer_tracker.GetBufferByCaptureDeviceAddress(in_pMissShaderBindingTable->deviceAddress)); - GFXRECON_ASSERT(in_pHitShaderBindingTable->size == 0 || - buffer_tracker.GetBufferByCaptureDeviceAddress(in_pHitShaderBindingTable->deviceAddress)); - GFXRECON_ASSERT(in_pCallableShaderBindingTable->size == 0 || - buffer_tracker.GetBufferByCaptureDeviceAddress(in_pCallableShaderBindingTable->deviceAddress)); + VkCommandBuffer commandBuffer = command_buffer_info->handle; + VkStridedDeviceAddressRegionKHR* in_pRaygenShaderBindingTable = pRaygenShaderBindingTable->GetPointer(); + VkStridedDeviceAddressRegionKHR* in_pMissShaderBindingTable = pMissShaderBindingTable->GetPointer(); + VkStridedDeviceAddressRegionKHR* in_pHitShaderBindingTable = pHitShaderBindingTable->GetPointer(); + VkStridedDeviceAddressRegionKHR* in_pCallableShaderBindingTable = pCallableShaderBindingTable->GetPointer(); + + // identify buffer(s) by their device-address + const DeviceInfo* device_info = GetObjectInfoTable().GetDeviceInfo(command_buffer_info->parent_id); + const auto& address_tracker = GetDeviceAddressTracker(device_info->handle); + + auto address_remap = [&address_tracker](VkStridedDeviceAddressRegionKHR* address_region) { + if (address_region->size > 0) + { + auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(address_region->deviceAddress); + GFXRECON_ASSERT(buffer_info != nullptr); + + if (buffer_info->replay_address != 0) + { + uint64_t offset = address_region->deviceAddress - buffer_info->capture_address; + + // in-place address-remap via const-cast + address_region->deviceAddress = buffer_info->replay_address + offset; + } + else + { + GFXRECON_LOG_WARNING_ONCE( + "OverrideCmdTraceRaysKHR: missing buffer_info->replay_address, remap failed") + } + } + }; + // in-place remap: capture-addresses -> replay-addresses + address_remap(in_pRaygenShaderBindingTable); + address_remap(in_pMissShaderBindingTable); + address_remap(in_pHitShaderBindingTable); + address_remap(in_pCallableShaderBindingTable); const PhysicalDeviceInfo* physical_device_info = GetObjectInfoTable().GetPhysicalDeviceInfo(device_info->parent_id); @@ -8222,9 +8391,10 @@ void VulkanReplayConsumerBase::OverrideCmdTraceRaysKHR( physical_device_info->shaderGroupHandleAlignment != replay_props.shaderGroupHandleAlignment || physical_device_info->shaderGroupBaseAlignment != replay_props.shaderGroupBaseAlignment) { - // TODO: move forward with address-remapping and re-assembly of a binding-table + // TODO: binding-table re-assembly // TODO: remove TODO/warning when issue #1526 is solved - GFXRECON_LOG_WARNING_ONCE("capture/replay have mismatching shader-binding-table size or alignments"); + GFXRECON_LOG_WARNING_ONCE( + "OverrideCmdTraceRaysKHR: mismatching shader-binding-table size or alignments") } } @@ -8997,12 +9167,13 @@ void VulkanReplayConsumerBase::UpdateDescriptorSetInfoWithTemplate(DescriptorSet } } -VulkanBufferTracker& VulkanReplayConsumerBase::GetBufferTracker(VkDevice device) +VulkanDeviceAddressTracker& VulkanReplayConsumerBase::GetDeviceAddressTracker(VkDevice device) { - auto it = _buffer_trackers.find(device); - if (it == _buffer_trackers.end()) + auto it = _device_address_trackers.find(device); + if (it == _device_address_trackers.end()) { - auto [new_it, success] = _buffer_trackers.insert({ device, VulkanBufferTracker(object_info_table_) }); + auto [new_it, success] = + _device_address_trackers.insert({ device, VulkanDeviceAddressTracker(object_info_table_) }); return new_it->second; } return it->second; diff --git a/framework/decode/vulkan_replay_consumer_base.h b/framework/decode/vulkan_replay_consumer_base.h index b0886c7c5..bf5e8eb67 100644 --- a/framework/decode/vulkan_replay_consumer_base.h +++ b/framework/decode/vulkan_replay_consumer_base.h @@ -29,7 +29,7 @@ #include "decode/pointer_decoder.h" #include "decode/screenshot_handler.h" #include "decode/swapchain_image_tracker.h" -#include "decode/vulkan_buffer_tracker.h" +#include "decode/vulkan_device_address_tracker.h" #include "decode/vulkan_handle_mapping_util.h" #include "decode/vulkan_object_info.h" #include "decode/vulkan_object_info_table.h" @@ -1064,6 +1064,32 @@ class VulkanReplayConsumerBase : public VulkanConsumer const StructPointerDecoder* pAllocator, HandlePointerDecoder* pAccelerationStructureKHR); + void OverrideDestroyAccelerationStructureKHR(PFN_vkDestroyAccelerationStructureKHR func, + const DeviceInfo* device_info, + const AccelerationStructureKHRInfo* acceleration_structure_info, + StructPointerDecoder* pAllocator); + + void OverrideCmdBuildAccelerationStructuresKHR( + PFN_vkCmdBuildAccelerationStructuresKHR func, + CommandBufferInfo* command_buffer_info, + uint32_t infoCount, + StructPointerDecoder* pInfos, + StructPointerDecoder* ppBuildRangeInfos); + + void + OverrideCmdCopyAccelerationStructureKHR(PFN_vkCmdCopyAccelerationStructureKHR func, + CommandBufferInfo* command_buffer_info, + StructPointerDecoder* pInfo); + + void OverrideCmdWriteAccelerationStructuresPropertiesKHR( + PFN_vkCmdWriteAccelerationStructuresPropertiesKHR func, + CommandBufferInfo* command_buffer_info, + uint32_t count, + HandlePointerDecoder* pAccelerationStructures, + VkQueryType queryType, + gfxrecon::decode::QueryPoolInfo* query_pool_info, + uint32_t firstQuery); + VkResult OverrideCreateRayTracingPipelinesKHR( PFN_vkCreateRayTracingPipelinesKHR func, VkResult original_result, @@ -1405,7 +1431,7 @@ class VulkanReplayConsumerBase : public VulkanConsumer const DescriptorUpdateTemplateInfo* template_info, const DescriptorUpdateTemplateDecoder* decoder) const; - VulkanBufferTracker& GetBufferTracker(VkDevice device); + VulkanDeviceAddressTracker& GetDeviceAddressTracker(VkDevice device); private: struct HardwareBufferInfo @@ -1454,7 +1480,7 @@ class VulkanReplayConsumerBase : public VulkanConsumer std::string screenshot_file_prefix_; graphics::FpsInfo* fps_info_; - std::unordered_map _buffer_trackers; + std::unordered_map _device_address_trackers; util::ThreadPool main_thread_queue_; util::ThreadPool background_queue_; diff --git a/framework/encode/custom_vulkan_encoder_commands.h b/framework/encode/custom_vulkan_encoder_commands.h index c472558fd..70c3b3028 100644 --- a/framework/encode/custom_vulkan_encoder_commands.h +++ b/framework/encode/custom_vulkan_encoder_commands.h @@ -921,32 +921,32 @@ struct CustomEncoderPostCall }; template <> -struct CustomEncoderPreCall +struct CustomEncoderPostCall { template static void Dispatch(VulkanCaptureManager* manager, Args... args) { - manager->PreProcess_vkGetBufferDeviceAddress(args...); + manager->PostProcess_vkGetBufferDeviceAddress(args...); } }; template <> -struct CustomEncoderPreCall +struct CustomEncoderPostCall { template static void Dispatch(VulkanCaptureManager* manager, Args... args) { - manager->PreProcess_vkGetBufferDeviceAddress(args...); + manager->PostProcess_vkGetBufferDeviceAddress(args...); } }; template <> -struct CustomEncoderPreCall +struct CustomEncoderPostCall { template static void Dispatch(VulkanCaptureManager* manager, Args... args) { - manager->PreProcess_vkGetBufferDeviceAddress(args...); + manager->PostProcess_vkGetBufferDeviceAddress(args...); } }; diff --git a/framework/encode/parameter_encoder.h b/framework/encode/parameter_encoder.h index 1789a5080..f78d100d8 100644 --- a/framework/encode/parameter_encoder.h +++ b/framework/encode/parameter_encoder.h @@ -67,6 +67,7 @@ class ParameterEncoder void EncodeDoubleValue(double value) { EncodeValue(value); } void EncodeSizeTValue(size_t value) { EncodeValue(static_cast(value)); } void EncodeHandleIdValue(format::HandleId value) { EncodeValue(static_cast(value)); } + void EncodeVkDeviceAddressValue(VkDeviceAddress value) { EncodeValue(static_cast(value)); } // Encode the address values for pointers to non-Vulkan objects to be used as object IDs. void EncodeAddress(const void* value) { EncodeValue(reinterpret_cast(value)); } diff --git a/framework/encode/vulkan_capture_manager.cpp b/framework/encode/vulkan_capture_manager.cpp index dcb797589..aa8833276 100644 --- a/framework/encode/vulkan_capture_manager.cpp +++ b/framework/encode/vulkan_capture_manager.cpp @@ -25,6 +25,7 @@ #include PROJECT_VERSION_HEADER_FILE #include "encode/struct_pointer_encoder.h" +#include "encode/vulkan_track_struct.h" #include "encode/vulkan_capture_manager.h" #include "encode/vulkan_handle_wrapper_util.h" @@ -379,7 +380,7 @@ void VulkanCaptureManager::WriteSetDeviceMemoryPropertiesCommand( void VulkanCaptureManager::WriteSetOpaqueAddressCommand(format::HandleId device_id, format::HandleId object_id, - uint64_t address) + uint64_t opaque_address) { if (IsCaptureModeWrite()) { @@ -395,7 +396,7 @@ void VulkanCaptureManager::WriteSetOpaqueAddressCommand(format::HandleId device_ opaque_address_cmd.thread_id = thread_data->thread_id_; opaque_address_cmd.device_id = device_id; opaque_address_cmd.object_id = object_id; - opaque_address_cmd.address = address; + opaque_address_cmd.address = opaque_address; WriteToFile(&opaque_address_cmd, sizeof(opaque_address_cmd)); } @@ -794,55 +795,60 @@ VkResult VulkanCaptureManager::OverrideCreateBuffer(VkDevice const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) { - VkResult result = VK_SUCCESS; - auto device_wrapper = vulkan_wrappers::GetWrapper(device); - VkDevice device_unwrapped = device_wrapper->handle; - auto device_table = vulkan_wrappers::GetDeviceTable(device); - auto handle_unwrap_memory = VulkanCaptureManager::Get()->GetHandleUnwrapMemory(); + VkResult result = VK_SUCCESS; + auto device_wrapper = vulkan_wrappers::GetWrapper(device); + VkDevice device_unwrapped = device_wrapper->handle; + auto device_table = vulkan_wrappers::GetDeviceTable(device); - VkBufferCreateInfo modified_create_info = (*pCreateInfo); + // we need to deep-copy, potentially contains VkBufferUsageFlags2CreateInfoKHR in pNext-chain + std::unique_ptr struct_storage; + VkBufferCreateInfo* modified_create_info = vulkan_trackers::TrackStructs(pCreateInfo, 1, struct_storage); - if (IsTrimEnabled()) + bool uses_address = false; + VkBufferUsageFlags2KHR* address_usage_flags2_KHR = nullptr; + + if (auto usage_flags2_info = + graphics::vulkan_struct_get_pnext(modified_create_info)) { - modified_create_info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + address_usage_flags2_KHR = &usage_flags2_info->usage; } - bool uses_address = false; - VkBufferCreateFlags address_create_flags = 0; - VkBufferUsageFlags address_usage_flags = 0; + if (IsTrimEnabled()) + { + modified_create_info->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + + if (address_usage_flags2_KHR != nullptr) + { + *address_usage_flags2_KHR |= VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT_KHR; + } + } if (device_wrapper->property_feature_info.feature_bufferDeviceAddressCaptureReplay) { + // If the buffer has shader device address usage, but the device address capture replay flag was not set, it + // needs to be set here. We modify only a copy to prevent the modified pCreateInfo from being + // written to the capture file. if ((pCreateInfo->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) == VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) { uses_address = true; - address_create_flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; + modified_create_info->flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; } if ((pCreateInfo->usage & VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR) == VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR) { uses_address = true; - address_create_flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; - address_usage_flags |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; - } - } + modified_create_info->flags |= VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT; + modified_create_info->usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; - // NOTE: VkBufferCreateInfo does not currently support pNext structures with handles, so does not have a handle - // unwrapping function. If a pNext struct with handles is added in the future, it will be necessary to unwrap - // pCreateInfo before calling CreateBuffer. The unwrapping process will create a mutable copy of the original - // pCreateInfo, with unwrapped handles, which can be modified directly and would not require the - // 'modified_create_info' copy performed below. - if (uses_address && (((pCreateInfo->flags & address_create_flags) != address_create_flags) || - ((pCreateInfo->usage & address_usage_flags) != address_usage_flags))) - { - // If the buffer has shader device address usage, but the device address capture replay flag was not set, it - // needs to be set here. We create copy from an override to prevent the modified pCreateInfo from being - // written to the capture file. - modified_create_info.flags |= address_create_flags; - modified_create_info.usage |= address_usage_flags; + if (address_usage_flags2_KHR != nullptr) + { + *address_usage_flags2_KHR |= VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR; + } + } } - result = device_table->CreateBuffer(device_unwrapped, &modified_create_info, pAllocator, pBuffer); + // create buffer with augmented create- and usage-flags + result = device_table->CreateBuffer(device_unwrapped, modified_create_info, pAllocator, pBuffer); if ((result == VK_SUCCESS) && (pBuffer != nullptr)) { @@ -860,26 +866,24 @@ VkResult VulkanCaptureManager::OverrideCreateBuffer(VkDevice VkBufferDeviceAddressInfo info = { VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO }; info.pNext = nullptr; info.buffer = buffer_wrapper->handle; - uint64_t address = 0; + uint64_t opaque_address = 0; if (device_wrapper->physical_device->instance_api_version >= VK_MAKE_VERSION(1, 2, 0)) { - address = device_table->GetBufferOpaqueCaptureAddress(device_unwrapped, &info); + opaque_address = device_table->GetBufferOpaqueCaptureAddress(device_unwrapped, &info); } else { - address = device_table->GetBufferOpaqueCaptureAddressKHR(device_unwrapped, &info); + opaque_address = device_table->GetBufferOpaqueCaptureAddressKHR(device_unwrapped, &info); } - - WriteSetOpaqueAddressCommand(device_wrapper->handle_id, buffer_wrapper->handle_id, address); + WriteSetOpaqueAddressCommand(device_wrapper->handle_id, buffer_wrapper->handle_id, opaque_address); if (IsCaptureModeTrack()) { - state_tracker_->TrackBufferDeviceAddress(device, *pBuffer, address); + state_tracker_->TrackOpaqueBufferDeviceAddress(device, *pBuffer, opaque_address); } } } - return result; } @@ -1139,6 +1143,31 @@ VkResult VulkanCaptureManager::OverrideAllocateMemory(VkDevice return result; } +void VulkanCaptureManager::OverrideGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties) +{ + auto physical_device_wrapper = vulkan_wrappers::GetWrapper(physicalDevice); + GFXRECON_ASSERT(physical_device_wrapper != nullptr) + + if (physical_device_wrapper->instance_api_version >= VK_MAKE_VERSION(1, 1, 0)) + { + vulkan_wrappers::GetInstanceTable(physicalDevice)->GetPhysicalDeviceProperties2(physicalDevice, pProperties); + } + else + { + vulkan_wrappers::GetInstanceTable(physicalDevice)->GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties); + } + + if (auto raytracing_props = + graphics::vulkan_struct_get_pnext(pProperties)) + { + if (IsCaptureModeTrack()) + { + state_tracker_->TrackRayTracingPipelineProperties(physicalDevice, raytracing_props); + } + } +} + VkResult VulkanCaptureManager::OverrideGetPhysicalDeviceToolPropertiesEXT( VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties) { @@ -2527,7 +2556,9 @@ void VulkanCaptureManager::PreProcess_vkCreateDescriptorUpdateTemplateKHR( } } -void VulkanCaptureManager::PreProcess_vkGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo* pInfo) +void VulkanCaptureManager::PostProcess_vkGetBufferDeviceAddress(VkDeviceAddress result, + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo) { auto device_wrapper = vulkan_wrappers::GetWrapper(device); if (!device_wrapper->property_feature_info.feature_bufferDeviceAddressCaptureReplay) @@ -2537,6 +2568,11 @@ void VulkanCaptureManager::PreProcess_vkGetBufferDeviceAddress(VkDevice device, "feature for accurate capture and replay. The capture device does not support this feature, so replay of " "the captured file may fail."); } + + if (IsCaptureModeTrack()) + { + state_tracker_->TrackBufferDeviceAddress(device, pInfo->buffer, result); + } } void VulkanCaptureManager::PreProcess_vkGetBufferOpaqueCaptureAddress(VkDevice device, diff --git a/framework/encode/vulkan_capture_manager.h b/framework/encode/vulkan_capture_manager.h index 7f65dc346..c9bdef484 100644 --- a/framework/encode/vulkan_capture_manager.h +++ b/framework/encode/vulkan_capture_manager.h @@ -302,6 +302,9 @@ class VulkanCaptureManager : public ApiCaptureManager const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); + void OverrideGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties); + VkResult OverrideGetPhysicalDeviceToolPropertiesEXT(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolPropertiesEXT* pToolProperties); @@ -1215,7 +1218,9 @@ class VulkanCaptureManager : public ApiCaptureManager const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); - void PreProcess_vkGetBufferDeviceAddress(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); + void PostProcess_vkGetBufferDeviceAddress(VkDeviceAddress result, + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); void PreProcess_vkGetBufferOpaqueCaptureAddress(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); diff --git a/framework/encode/vulkan_handle_wrappers.h b/framework/encode/vulkan_handle_wrappers.h index 8c6c7438e..e131d8026 100644 --- a/framework/encode/vulkan_handle_wrappers.h +++ b/framework/encode/vulkan_handle_wrappers.h @@ -41,6 +41,7 @@ #include #include #include +#include GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(encode) @@ -137,6 +138,9 @@ struct PhysicalDeviceWrapper : public HandleWrapper std::unique_ptr queue_family_properties; std::unique_ptr queue_family_properties2; std::vector> queue_family_checkpoint_properties; + + // Track RayTracingPipelinePropertiesKHR + std::optional ray_tracing_pipeline_properties; }; struct InstanceWrapper : public HandleWrapper @@ -214,6 +218,7 @@ struct BufferWrapper : public HandleWrapper // State tracking info for buffers with device addresses. format::HandleId device_id{ format::kNullHandleId }; VkDeviceAddress address{ 0 }; + VkDeviceAddress opaque_address{ 0 }; }; struct ImageWrapper : public HandleWrapper diff --git a/framework/encode/vulkan_state_tracker.cpp b/framework/encode/vulkan_state_tracker.cpp index 22f619500..ff278c2ec 100644 --- a/framework/encode/vulkan_state_tracker.cpp +++ b/framework/encode/vulkan_state_tracker.cpp @@ -23,7 +23,6 @@ #include "encode/vulkan_state_tracker.h" #include "encode/vulkan_state_info.h" -#include "encode/custom_vulkan_struct_handle_wrappers.h" #include "encode/vulkan_handle_wrapper_util.h" #include "encode/vulkan_track_struct.h" #include "graphics/vulkan_struct_get_pnext.h" @@ -326,13 +325,24 @@ void VulkanStateTracker::TrackDeviceGroupSurfacePresentModes(VkDevice void VulkanStateTracker::TrackBufferDeviceAddress(VkDevice device, VkBuffer buffer, VkDeviceAddress address) { - assert((device != VK_NULL_HANDLE) && (buffer != VK_NULL_HANDLE)); + GFXRECON_ASSERT((device != VK_NULL_HANDLE) && (buffer != VK_NULL_HANDLE)); auto wrapper = vulkan_wrappers::GetWrapper(buffer); wrapper->device_id = vulkan_wrappers::GetWrappedId(device); wrapper->address = address; } +void VulkanStateTracker::TrackOpaqueBufferDeviceAddress(VkDevice device, + VkBuffer buffer, + VkDeviceAddress opaque_address) +{ + GFXRECON_ASSERT((device != VK_NULL_HANDLE) && (buffer != VK_NULL_HANDLE)); + + auto wrapper = vulkan_wrappers::GetWrapper(buffer); + wrapper->device_id = vulkan_wrappers::GetWrappedId(device); + wrapper->opaque_address = opaque_address; +} + void VulkanStateTracker::TrackBufferMemoryBinding( VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset, const void* bind_info_pnext) { @@ -1374,6 +1384,14 @@ void VulkanStateTracker::TrackDeviceMemoryDeviceAddress(VkDevice device, VkDevic device_memory_addresses_map.emplace(address, wrapper); } +void VulkanStateTracker::TrackRayTracingPipelineProperties( + VkPhysicalDevice physicalDevice, VkPhysicalDeviceRayTracingPipelinePropertiesKHR* ray_properties) +{ + auto wrapper = vulkan_wrappers::GetWrapper(physicalDevice); + wrapper->ray_tracing_pipeline_properties = *ray_properties; + wrapper->ray_tracing_pipeline_properties->pNext = nullptr; +} + void VulkanStateTracker::TrackRayTracingShaderGroupHandles(VkDevice device, VkPipeline pipeline, size_t data_size, diff --git a/framework/encode/vulkan_state_tracker.h b/framework/encode/vulkan_state_tracker.h index 768602f3a..00d690e8b 100644 --- a/framework/encode/vulkan_state_tracker.h +++ b/framework/encode/vulkan_state_tracker.h @@ -303,6 +303,8 @@ class VulkanStateTracker void TrackBufferDeviceAddress(VkDevice device, VkBuffer buffer, VkDeviceAddress address); + void TrackOpaqueBufferDeviceAddress(VkDevice device, VkBuffer buffer, VkDeviceAddress opaque_address); + void TrackBufferMemoryBinding(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, @@ -395,6 +397,9 @@ class VulkanStateTracker void TrackDeviceMemoryDeviceAddress(VkDevice device, VkDeviceMemory memory, VkDeviceAddress address); + void TrackRayTracingPipelineProperties(VkPhysicalDevice physicalDevice, + VkPhysicalDeviceRayTracingPipelinePropertiesKHR* ray_properties); + void TrackRayTracingShaderGroupHandles(VkDevice device, VkPipeline pipeline, size_t data_size, const void* data); void TrackAcquireFullScreenExclusiveMode(VkDevice device, VkSwapchainKHR swapchain); diff --git a/framework/encode/vulkan_state_writer.cpp b/framework/encode/vulkan_state_writer.cpp index 904851e2d..5b724681a 100644 --- a/framework/encode/vulkan_state_writer.cpp +++ b/framework/encode/vulkan_state_writer.cpp @@ -87,8 +87,6 @@ VulkanStateWriter::VulkanStateWriter(util::FileOutputStream* output_stream, assert(output_stream != nullptr); } -VulkanStateWriter::~VulkanStateWriter() {} - uint64_t VulkanStateWriter::WriteState(const VulkanStateTable& state_table, uint64_t frame_number) { // clang-format off @@ -110,6 +108,9 @@ uint64_t VulkanStateWriter::WriteState(const VulkanStateTable& state_table, uint WriteDeviceState(state_table); StandardCreateWrite(state_table); + // physical-device / raytracing properties + WriteRayTracingPipelinePropertiesState(state_table); + // Utility object creation. StandardCreateWrite(state_table); StandardCreateWrite(state_table); @@ -145,6 +146,9 @@ uint64_t VulkanStateWriter::WriteState(const VulkanStateTable& state_table, uint StandardCreateWrite(state_table); StandardCreateWrite(state_table); + // Retrieve buffer-device-addresses + WriteBufferDeviceAddressState(state_table); + // Render object creation. StandardCreateWrite(state_table); WriteFramebufferState(state_table); @@ -1121,17 +1125,39 @@ void VulkanStateWriter::WriteDeviceMemoryState(const VulkanStateTable& state_tab }); } +void VulkanStateWriter::WriteBufferDeviceAddressState(const VulkanStateTable& state_table) +{ + state_table.VisitWrappers([&](const vulkan_wrappers::BufferWrapper* wrapper) { + assert(wrapper != nullptr); + if ((wrapper->device_id != format::kNullHandleId) && (wrapper->address != 0)) + { + auto physical_device_wrapper = wrapper->bind_device->physical_device; + auto call_id = physical_device_wrapper->instance_api_version >= VK_MAKE_VERSION(1, 2, 0) + ? format::ApiCall_vkGetBufferDeviceAddress + : format::ApiCall_vkGetBufferDeviceAddressKHR; + + parameter_stream_.Clear(); + encoder_.EncodeHandleIdValue(wrapper->bind_device->handle_id); + VkBufferDeviceAddressInfoKHR info{ VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, nullptr, wrapper->handle }; + EncodeStructPtr(&encoder_, &info); + encoder_.EncodeVkDeviceAddressValue(wrapper->address); + WriteFunctionCall(call_id, ¶meter_stream_); + parameter_stream_.Clear(); + } + }); +} + void VulkanStateWriter::WriteBufferState(const VulkanStateTable& state_table) { state_table.VisitWrappers([&](const vulkan_wrappers::BufferWrapper* wrapper) { assert(wrapper != nullptr); - if ((wrapper->device_id != format::kNullHandleId) && (wrapper->address != 0)) + if ((wrapper->device_id != format::kNullHandleId) && (wrapper->opaque_address != 0)) { // If the buffer has a device address, write the 'set opaque 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. - WriteSetOpaqueAddressCommand(wrapper->device_id, wrapper->handle_id, wrapper->address); + WriteSetOpaqueAddressCommand(wrapper->device_id, wrapper->handle_id, wrapper->opaque_address); } WriteFunctionCall(wrapper->create_call_id, wrapper->create_parameters.get()); @@ -1170,6 +1196,25 @@ void VulkanStateWriter::WriteTlasToBlasDependenciesMetadata(const VulkanStateTab }); } +void VulkanStateWriter::WriteRayTracingPipelinePropertiesState(const VulkanStateTable& state_table) +{ + state_table.VisitWrappers([&](const vulkan_wrappers::PhysicalDeviceWrapper* wrapper) { + assert(wrapper != nullptr); + + if (wrapper->ray_tracing_pipeline_properties != std::nullopt) + { + parameter_stream_.Clear(); + encoder_.EncodeHandleIdValue(wrapper->handle_id); + VkPhysicalDeviceProperties2 properties2 = {}; + properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + properties2.pNext = (void*)&wrapper->ray_tracing_pipeline_properties.value(); + EncodeStructPtr(&encoder_, &properties2); + WriteFunctionCall(format::ApiCall_vkGetPhysicalDeviceProperties2, ¶meter_stream_); + parameter_stream_.Clear(); + } + }); +} + void VulkanStateWriter::WriteAccelerationStructureKHRState(const VulkanStateTable& state_table) { state_table.VisitWrappers([&](const vulkan_wrappers::AccelerationStructureKHRWrapper* wrapper) { diff --git a/framework/encode/vulkan_state_writer.h b/framework/encode/vulkan_state_writer.h index 3a2dbc206..ee6e6c9b7 100644 --- a/framework/encode/vulkan_state_writer.h +++ b/framework/encode/vulkan_state_writer.h @@ -49,8 +49,6 @@ class VulkanStateWriter public: VulkanStateWriter(util::FileOutputStream* output_stream, util::Compressor* compressor, format::ThreadId thread_id); - ~VulkanStateWriter(); - // Returns number of blocks written to the output_stream. uint64_t WriteState(const VulkanStateTable& state_table, uint64_t frame_number); @@ -136,8 +134,12 @@ class VulkanStateWriter void WriteBufferState(const VulkanStateTable& state_table); + void WriteBufferDeviceAddressState(const VulkanStateTable& state_table); + void WriteDeviceMemoryState(const VulkanStateTable& state_table); + void WriteRayTracingPipelinePropertiesState(const VulkanStateTable& state_table); + void WriteAccelerationStructureKHRState(const VulkanStateTable& state_table); void WriteDeferredOperationJoinCommand(format::HandleId device_id, format::HandleId deferred_operation_id); @@ -353,7 +355,7 @@ class VulkanStateWriter format::ThreadId thread_id_; util::MemoryOutputStream parameter_stream_; ParameterEncoder encoder_; - uint64_t blocks_written_; + uint64_t blocks_written_{ 0 }; }; GFXRECON_END_NAMESPACE(encode) diff --git a/framework/generated/generated_vulkan_api_call_encoders.cpp b/framework/generated/generated_vulkan_api_call_encoders.cpp index b969e7808..66105d79f 100644 --- a/framework/generated/generated_vulkan_api_call_encoders.cpp +++ b/framework/generated/generated_vulkan_api_call_encoders.cpp @@ -5712,7 +5712,7 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2( CustomEncoderPreCall::Dispatch(manager, physicalDevice, pProperties); - vulkan_wrappers::GetInstanceTable(physicalDevice)->GetPhysicalDeviceProperties2(physicalDevice, pProperties); + manager->OverrideGetPhysicalDeviceProperties2(physicalDevice, pProperties); auto encoder = manager->BeginApiCallCapture(format::ApiCallId::ApiCall_vkGetPhysicalDeviceProperties2); if (encoder) @@ -10277,7 +10277,7 @@ VKAPI_ATTR void VKAPI_CALL GetPhysicalDeviceProperties2KHR( CustomEncoderPreCall::Dispatch(manager, physicalDevice, pProperties); - vulkan_wrappers::GetInstanceTable(physicalDevice)->GetPhysicalDeviceProperties2KHR(physicalDevice, pProperties); + manager->OverrideGetPhysicalDeviceProperties2(physicalDevice, pProperties); auto encoder = manager->BeginApiCallCapture(format::ApiCallId::ApiCall_vkGetPhysicalDeviceProperties2KHR); if (encoder) diff --git a/framework/generated/generated_vulkan_replay_consumer.cpp b/framework/generated/generated_vulkan_replay_consumer.cpp index 140836e43..65fdf5afd 100644 --- a/framework/generated/generated_vulkan_replay_consumer.cpp +++ b/framework/generated/generated_vulkan_replay_consumer.cpp @@ -8038,11 +8038,11 @@ void VulkanReplayConsumer::Process_vkGetBufferDeviceAddressEXT( format::HandleId device, StructPointerDecoder* pInfo) { - VkDevice in_device = MapHandle(device, &VulkanObjectInfoTable::GetDeviceInfo); - const VkBufferDeviceAddressInfo* in_pInfo = pInfo->GetPointer(); + auto in_device = GetObjectInfoTable().GetDeviceInfo(device); + MapStructHandles(pInfo->GetMetaStructPointer(), GetObjectInfoTable()); - GetDeviceTable(in_device)->GetBufferDeviceAddressEXT(in_device, in_pInfo); + OverrideGetBufferDeviceAddress(GetDeviceTable(in_device->handle)->GetBufferDeviceAddressEXT, returnValue, in_device, pInfo); } void VulkanReplayConsumer::Process_vkGetPhysicalDeviceToolPropertiesEXT( @@ -10515,11 +10515,10 @@ void VulkanReplayConsumer::Process_vkDestroyAccelerationStructureKHR( format::HandleId accelerationStructure, StructPointerDecoder* pAllocator) { - VkDevice in_device = MapHandle(device, &VulkanObjectInfoTable::GetDeviceInfo); - VkAccelerationStructureKHR in_accelerationStructure = MapHandle(accelerationStructure, &VulkanObjectInfoTable::GetAccelerationStructureKHRInfo); - const VkAllocationCallbacks* in_pAllocator = GetAllocationCallbacks(pAllocator); + auto in_device = GetObjectInfoTable().GetDeviceInfo(device); + auto in_accelerationStructure = GetObjectInfoTable().GetAccelerationStructureKHRInfo(accelerationStructure); - GetDeviceTable(in_device)->DestroyAccelerationStructureKHR(in_device, in_accelerationStructure, in_pAllocator); + OverrideDestroyAccelerationStructureKHR(GetDeviceTable(in_device->handle)->DestroyAccelerationStructureKHR, in_device, in_accelerationStructure, pAllocator); RemoveHandle(accelerationStructure, &VulkanObjectInfoTable::RemoveAccelerationStructureKHRInfo); } @@ -10530,16 +10529,15 @@ void VulkanReplayConsumer::Process_vkCmdBuildAccelerationStructuresKHR( StructPointerDecoder* pInfos, StructPointerDecoder* ppBuildRangeInfos) { - VkCommandBuffer in_commandBuffer = MapHandle(commandBuffer, &VulkanObjectInfoTable::GetCommandBufferInfo); - const VkAccelerationStructureBuildGeometryInfoKHR* in_pInfos = pInfos->GetPointer(); + auto in_commandBuffer = GetObjectInfoTable().GetCommandBufferInfo(commandBuffer); + MapStructArrayHandles(pInfos->GetMetaStructPointer(), pInfos->GetLength(), GetObjectInfoTable()); - const VkAccelerationStructureBuildRangeInfoKHR* const* in_ppBuildRangeInfos = ppBuildRangeInfos->GetPointer(); - GetDeviceTable(in_commandBuffer)->CmdBuildAccelerationStructuresKHR(in_commandBuffer, infoCount, in_pInfos, in_ppBuildRangeInfos); + OverrideCmdBuildAccelerationStructuresKHR(GetDeviceTable(in_commandBuffer->handle)->CmdBuildAccelerationStructuresKHR, in_commandBuffer, infoCount, pInfos, ppBuildRangeInfos); if (options_.dumping_resources) { - resource_dumper.Process_vkCmdBuildAccelerationStructuresKHR(call_info, GetDeviceTable(in_commandBuffer)->CmdBuildAccelerationStructuresKHR, in_commandBuffer, infoCount, in_pInfos, in_ppBuildRangeInfos); + resource_dumper.Process_vkCmdBuildAccelerationStructuresKHR(call_info, GetDeviceTable(in_commandBuffer->handle)->CmdBuildAccelerationStructuresKHR, in_commandBuffer->handle, infoCount, pInfos->GetPointer(), ppBuildRangeInfos->GetPointer()); } } @@ -10623,15 +10621,15 @@ void VulkanReplayConsumer::Process_vkCmdCopyAccelerationStructureKHR( format::HandleId commandBuffer, StructPointerDecoder* pInfo) { - VkCommandBuffer in_commandBuffer = MapHandle(commandBuffer, &VulkanObjectInfoTable::GetCommandBufferInfo); - const VkCopyAccelerationStructureInfoKHR* in_pInfo = pInfo->GetPointer(); + auto in_commandBuffer = GetObjectInfoTable().GetCommandBufferInfo(commandBuffer); + MapStructHandles(pInfo->GetMetaStructPointer(), GetObjectInfoTable()); - GetDeviceTable(in_commandBuffer)->CmdCopyAccelerationStructureKHR(in_commandBuffer, in_pInfo); + OverrideCmdCopyAccelerationStructureKHR(GetDeviceTable(in_commandBuffer->handle)->CmdCopyAccelerationStructureKHR, in_commandBuffer, pInfo); if (options_.dumping_resources) { - resource_dumper.Process_vkCmdCopyAccelerationStructureKHR(call_info, GetDeviceTable(in_commandBuffer)->CmdCopyAccelerationStructureKHR, in_commandBuffer, in_pInfo); + resource_dumper.Process_vkCmdCopyAccelerationStructureKHR(call_info, GetDeviceTable(in_commandBuffer->handle)->CmdCopyAccelerationStructureKHR, in_commandBuffer->handle, pInfo->GetPointer()); } } @@ -10691,15 +10689,15 @@ void VulkanReplayConsumer::Process_vkCmdWriteAccelerationStructuresPropertiesKHR format::HandleId queryPool, uint32_t firstQuery) { - VkCommandBuffer in_commandBuffer = MapHandle(commandBuffer, &VulkanObjectInfoTable::GetCommandBufferInfo); - const VkAccelerationStructureKHR* in_pAccelerationStructures = MapHandles(pAccelerationStructures, accelerationStructureCount, &VulkanObjectInfoTable::GetAccelerationStructureKHRInfo); - VkQueryPool in_queryPool = MapHandle(queryPool, &VulkanObjectInfoTable::GetQueryPoolInfo); + auto in_commandBuffer = GetObjectInfoTable().GetCommandBufferInfo(commandBuffer); + MapHandles(pAccelerationStructures, accelerationStructureCount, &VulkanObjectInfoTable::GetAccelerationStructureKHRInfo); + auto in_queryPool = GetObjectInfoTable().GetQueryPoolInfo(queryPool); - GetDeviceTable(in_commandBuffer)->CmdWriteAccelerationStructuresPropertiesKHR(in_commandBuffer, accelerationStructureCount, in_pAccelerationStructures, queryType, in_queryPool, firstQuery); + OverrideCmdWriteAccelerationStructuresPropertiesKHR(GetDeviceTable(in_commandBuffer->handle)->CmdWriteAccelerationStructuresPropertiesKHR, in_commandBuffer, accelerationStructureCount, pAccelerationStructures, queryType, in_queryPool, firstQuery); if (options_.dumping_resources) { - resource_dumper.Process_vkCmdWriteAccelerationStructuresPropertiesKHR(call_info, GetDeviceTable(in_commandBuffer)->CmdWriteAccelerationStructuresPropertiesKHR, in_commandBuffer, accelerationStructureCount, in_pAccelerationStructures, queryType, in_queryPool, firstQuery); + resource_dumper.Process_vkCmdWriteAccelerationStructuresPropertiesKHR(call_info, GetDeviceTable(in_commandBuffer->handle)->CmdWriteAccelerationStructuresPropertiesKHR, in_commandBuffer->handle, accelerationStructureCount, pAccelerationStructures->GetHandlePointer(), queryType, in_queryPool->handle, firstQuery); } } diff --git a/framework/generated/vulkan_generators/capture_overrides.json b/framework/generated/vulkan_generators/capture_overrides.json index d3f59dd7e..dfe43ff1a 100644 --- a/framework/generated/vulkan_generators/capture_overrides.json +++ b/framework/generated/vulkan_generators/capture_overrides.json @@ -12,6 +12,8 @@ "vkGetPhysicalDeviceQueueFamilyProperties": "manager->OverrideGetPhysicalDeviceQueueFamilyProperties", "vkGetPhysicalDeviceQueueFamilyProperties2": "manager->OverrideGetPhysicalDeviceQueueFamilyProperties2", "vkGetPhysicalDeviceQueueFamilyProperties2KHR": "manager->OverrideGetPhysicalDeviceQueueFamilyProperties2KHR", - "vkCmdBuildAccelerationStructuresKHR": "manager->OverrideCmdBuildAccelerationStructuresKHR" + "vkCmdBuildAccelerationStructuresKHR": "manager->OverrideCmdBuildAccelerationStructuresKHR", + "vkGetPhysicalDeviceProperties2": "manager->OverrideGetPhysicalDeviceProperties2", + "vkGetPhysicalDeviceProperties2KHR": "manager->OverrideGetPhysicalDeviceProperties2" } } diff --git a/framework/generated/vulkan_generators/replay_overrides.json b/framework/generated/vulkan_generators/replay_overrides.json index 378034320..54ffafdee 100644 --- a/framework/generated/vulkan_generators/replay_overrides.json +++ b/framework/generated/vulkan_generators/replay_overrides.json @@ -88,10 +88,10 @@ "vkGetPhysicalDeviceWaylandPresentationSupportKHR": "OverrideGetPhysicalDeviceWaylandPresentationSupportKHR", "vkCreateMetalSurfaceEXT": "OverrideCreateMetalSurfaceEXT", "vkDestroySurfaceKHR": "OverrideDestroySurfaceKHR", - "vkCreateAccelerationStructureKHR": "OverrideCreateAccelerationStructureKHR", "vkGetRandROutputDisplayEXT": "OverrideGetRandROutputDisplayEXT", "vkGetBufferDeviceAddress": "OverrideGetBufferDeviceAddress", "vkGetBufferDeviceAddressKHR": "OverrideGetBufferDeviceAddress", + "vkGetBufferDeviceAddressEXT": "OverrideGetBufferDeviceAddress", "vkGetAccelerationStructureDeviceAddressKHR": "OverrideGetAccelerationStructureDeviceAddressKHR", "vkGetRayTracingShaderGroupHandlesKHR": "OverrideGetRayTracingShaderGroupHandlesKHR", "vkGetAndroidHardwareBufferPropertiesANDROID": "OverrideGetAndroidHardwareBufferPropertiesANDROID", @@ -122,6 +122,11 @@ "vkDestroyVideoSessionKHR": "OverrideDestroyVideoSessionKHR", "vkBindVideoSessionMemoryKHR": "OverrideBindVideoSessionMemoryKHR", "vkCreateShadersEXT": "OverrideCreateShadersEXT", - "vkCmdTraceRaysKHR": "OverrideCmdTraceRaysKHR" + "vkCmdTraceRaysKHR": "OverrideCmdTraceRaysKHR", + "vkCreateAccelerationStructureKHR": "OverrideCreateAccelerationStructureKHR", + "vkDestroyAccelerationStructureKHR": "OverrideDestroyAccelerationStructureKHR", + "vkCmdBuildAccelerationStructuresKHR": "OverrideCmdBuildAccelerationStructuresKHR", + "vkCmdCopyAccelerationStructureKHR" : "OverrideCmdCopyAccelerationStructureKHR", + "vkCmdWriteAccelerationStructuresPropertiesKHR" : "OverrideCmdWriteAccelerationStructuresPropertiesKHR" } } diff --git a/framework/generated/vulkan_generators/vulkan_replay_consumer_body_generator.py b/framework/generated/vulkan_generators/vulkan_replay_consumer_body_generator.py index f6d280a9c..c6dc5ca8f 100644 --- a/framework/generated/vulkan_generators/vulkan_replay_consumer_body_generator.py +++ b/framework/generated/vulkan_generators/vulkan_replay_consumer_body_generator.py @@ -362,12 +362,16 @@ def make_consumer_func_body(self, return_type, name, values): dump_resource_arglist = '' if is_override: for val in values: - if val.is_pointer and self.is_struct(val.base_type) and not is_dr_override: - dump_resource_arglist += val.name + '->GetPointer()' - elif val.is_pointer and self.is_struct(val.base_type) and is_dr_override: - dump_resource_arglist += val.name + if val.is_pointer and self.is_struct(val.base_type): + if is_dr_override: + dump_resource_arglist += val.name + else: + dump_resource_arglist += val.name + '->GetPointer()' elif self.is_handle(val.base_type): - dump_resource_arglist += 'in_' + val.name + '->handle' + if val.is_pointer: + dump_resource_arglist += val.name + '->GetHandlePointer()' + else: + dump_resource_arglist += 'in_' + val.name + '->handle' else: dump_resource_arglist += val.name dump_resource_arglist += ', '