From 67db4fd36ea6c75f9ad3d2b1198e791fc80395de Mon Sep 17 00:00:00 2001 From: Locke Lin Date: Thu, 11 Jul 2024 17:33:50 -0600 Subject: [PATCH] Use replay MemoryRequirements of VideoSession replay MemoryRequirements could have different count and size. Some devices have one big MemoryRequirements. Some have plural small. Use replay MemoryRequirements to AllocateMemory and Bind on RebindAllocator. --- framework/decode/vulkan_default_allocator.h | 2 + framework/decode/vulkan_rebind_allocator.cpp | 51 ++++++++++++++----- framework/decode/vulkan_rebind_allocator.h | 1 + .../decode/vulkan_replay_consumer_base.cpp | 37 ++++++++------ framework/decode/vulkan_resource_allocator.h | 1 + 5 files changed, 64 insertions(+), 28 deletions(-) diff --git a/framework/decode/vulkan_default_allocator.h b/framework/decode/vulkan_default_allocator.h index 935811f2cd..4fb13f6c54 100644 --- a/framework/decode/vulkan_default_allocator.h +++ b/framework/decode/vulkan_default_allocator.h @@ -274,6 +274,8 @@ class VulkanDefaultAllocator : public VulkanResourceAllocator virtual bool SupportsOpaqueDeviceAddresses() override { return true; } + virtual bool SupportBindVideoSessionMemory() override { return false; } + protected: struct ResourceAllocInfo { diff --git a/framework/decode/vulkan_rebind_allocator.cpp b/framework/decode/vulkan_rebind_allocator.cpp index 228bf1c161..38e64ac063 100644 --- a/framework/decode/vulkan_rebind_allocator.cpp +++ b/framework/decode/vulkan_rebind_allocator.cpp @@ -887,23 +887,32 @@ VkResult VulkanRebindAllocator::BindVideoSessionMemory(VkVideoSessionKHR functions_.get_video_session_memory_requirements( device_, video_session, &session_requirements_count, session_requirements.data()); - for (uint32_t i = 0; i < bind_info_count; ++i) + // Use replay MemoryRequeirements to AllocateMemory and Bind. + for (uint32_t mem_index = 0; mem_index < session_requirements_count; ++mem_index) { - uint32_t mem_index = bind_infos[i].memoryBindIndex; uintptr_t allocator_session_data = allocator_session_datas[mem_index]; uintptr_t allocator_memory_data = allocator_memory_datas[mem_index]; - if ((allocator_session_data != 0) && (allocator_memory_data != 0)) + if (allocator_session_data != 0) { VmaAllocation allocation = VK_NULL_HANDLE; auto resource_alloc_info = reinterpret_cast(allocator_session_data); - auto memory_alloc_info = reinterpret_cast(allocator_memory_data); + // if allocator_memory_data is 0, it means replay MemoryRequirements has more count. + MemoryAllocInfo* memory_alloc_info = (allocator_memory_data == 0) + ? new MemoryAllocInfo + : reinterpret_cast(allocator_memory_data); + auto requirements = session_requirements[mem_index].memoryRequirements; + if (allocator_memory_data == 0) + { + memory_alloc_info->allocation_size = requirements.size; + memory_alloc_info->original_index = requirements.memoryTypeBits; + } VmaAllocationCreateInfo create_info; create_info.flags = 0; create_info.usage = GetVideoSeesionMemoryUsage( capture_memory_properties_.memoryTypes[memory_alloc_info->original_index].propertyFlags, - session_requirements[mem_index].memoryRequirements); + requirements); create_info.requiredFlags = 0; create_info.preferredFlags = 0; create_info.memoryTypeBits = 0; @@ -929,8 +938,11 @@ VkResult VulkanRebindAllocator::BindVideoSessionMemory(VkVideoSessionKHR if (result >= 0) { - auto bind_info = &bind_infos[i]; - auto modified_bind_info = *bind_info; + VkBindVideoSessionMemoryInfoKHR modified_bind_info{}; + modified_bind_info.sType = VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR; + modified_bind_info.memoryBindIndex = mem_index; + modified_bind_info.memoryOffset = 0; + modified_bind_info.memorySize = session_requirements[mem_index].memoryRequirements.size; switch (allocation->GetType()) { @@ -962,10 +974,23 @@ VkResult VulkanRebindAllocator::BindVideoSessionMemory(VkVideoSessionKHR if (result >= 0) { - resource_alloc_info->allocation = allocation; - resource_alloc_info->mapped_pointer = nullptr; - resource_alloc_info->memory_info = memory_alloc_info; - resource_alloc_info->original_offset = bind_info->memoryOffset; + resource_alloc_info->allocation = allocation; + resource_alloc_info->mapped_pointer = nullptr; + resource_alloc_info->memory_info = memory_alloc_info; + + // The new bind_infos's index and captured bind_infos's index meanings are different. + VkDeviceSize src_offset = 0; + + for (uint32_t i = 0; i < bind_info_count; ++i) + { + if (bind_infos[i].memoryBindIndex == mem_index) + { + src_offset = bind_infos[mem_index].memoryOffset; + break; + } + } + + resource_alloc_info->original_offset = src_offset; resource_alloc_info->rebind_offset = allocation_info.offset; resource_alloc_info->size = allocation_info.size; @@ -983,7 +1008,7 @@ VkResult VulkanRebindAllocator::BindVideoSessionMemory(VkVideoSessionKHR // Memory has been mapped and written prior to bind. Copy the original content to the new // allocation to ensure it contains the correct data. WriteBoundResource(resource_alloc_info, - bind_info->memoryOffset, + src_offset, 0, allocation_info.size, memory_alloc_info->original_content.get()); @@ -991,7 +1016,7 @@ VkResult VulkanRebindAllocator::BindVideoSessionMemory(VkVideoSessionKHR memory_alloc_info->original_sessions.insert(std::make_pair(video_session, resource_alloc_info)); - bind_memory_properties[i] = property_flags; + bind_memory_properties[mem_index] = property_flags; } } } diff --git a/framework/decode/vulkan_rebind_allocator.h b/framework/decode/vulkan_rebind_allocator.h index 556437b5ce..1c0549c365 100644 --- a/framework/decode/vulkan_rebind_allocator.h +++ b/framework/decode/vulkan_rebind_allocator.h @@ -305,6 +305,7 @@ class VulkanRebindAllocator : public VulkanResourceAllocator } virtual bool SupportsOpaqueDeviceAddresses() override { return false; } + virtual bool SupportBindVideoSessionMemory() override { return true; } private: struct MemoryAllocInfo; diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index a8f81f37e5..1faa6578c5 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -4631,6 +4631,15 @@ VkResult VulkanReplayConsumerBase::OverrideBindVideoSessionMemoryKHR( GFXRECON_ASSERT((device_info != nullptr) && (video_session_info != nullptr) && (pBindSessionMemoryInfos != nullptr)); + auto allocator = device_info->allocator.get(); + GFXRECON_ASSERT(allocator != nullptr); + + if (!allocator->SupportBindVideoSessionMemory()) + { + GFXRECON_LOG_WARNING_ONCE("The replay VideoSession's MemoryRequirements could be different, so replay may " + "fail. Try '-m rebind', if it fails."); + } + auto replay_bind_infos = pBindSessionMemoryInfos->GetPointer(); auto replay_bind_meta_infos = pBindSessionMemoryInfos->GetMetaStructPointer(); GFXRECON_ASSERT((replay_bind_infos != nullptr) && (replay_bind_meta_infos != nullptr)); @@ -4641,27 +4650,25 @@ VkResult VulkanReplayConsumerBase::OverrideBindVideoSessionMemoryKHR( std::vector allocator_memory_datas(session_mem_count, 0); std::vector memory_property_flags(session_mem_count, 0); - for (uint32_t i = 0; i < bindSessionMemoryInfoCount; ++i) + for (uint32_t mem_index = 0; mem_index < session_mem_count; ++mem_index) { - const auto* bind_meta_info = &replay_bind_meta_infos[i]; - auto mem_index = bind_meta_info->decoded_value->memoryBindIndex; - GFXRECON_ASSERT(mem_index < session_mem_count); - - auto memory_info = object_info_table_.GetDeviceMemoryInfo(bind_meta_info->memory); - - memory_infos.push_back(memory_info); - allocator_session_datas[mem_index] = video_session_info->allocator_datas[mem_index]; - if (memory_info != nullptr) + for (uint32_t i = 0; i < bindSessionMemoryInfoCount; ++i) { - allocator_memory_datas[mem_index] = memory_info->allocator_data; + const auto* bind_meta_info = &replay_bind_meta_infos[i]; + if (mem_index == bind_meta_info->decoded_value->memoryBindIndex) + { + auto memory_info = object_info_table_.GetDeviceMemoryInfo(bind_meta_info->memory); + memory_infos.push_back(memory_info); + + if (memory_info != nullptr) + { + allocator_memory_datas[mem_index] = memory_info->allocator_data; + } + } } } - - auto allocator = device_info->allocator.get(); - GFXRECON_ASSERT(allocator != nullptr); - VkResult result = allocator->BindVideoSessionMemory(video_session_info->handle, bindSessionMemoryInfoCount, replay_bind_infos, diff --git a/framework/decode/vulkan_resource_allocator.h b/framework/decode/vulkan_resource_allocator.h index b6578e4f48..fb29edf4fe 100644 --- a/framework/decode/vulkan_resource_allocator.h +++ b/framework/decode/vulkan_resource_allocator.h @@ -295,6 +295,7 @@ class VulkanResourceAllocator const MemoryData* allocator_datas) = 0; virtual bool SupportsOpaqueDeviceAddresses() = 0; + virtual bool SupportBindVideoSessionMemory() = 0; }; GFXRECON_END_NAMESPACE(decode)