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)