Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocator support VideoSession #1620

Merged
merged 3 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions external/VulkanMemoryAllocator/include/vk_mem_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6144,14 +6144,17 @@ class VmaDeviceMemoryBlock
VmaPool m_hParentPool; // VK_NULL_HANDLE if not belongs to custom pool.
uint32_t m_MemoryTypeIndex;
uint32_t m_Id;
public:
VkDeviceMemory m_hMemory;

/*
Protects access to m_hMemory so it is not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
Also protects m_MapCount, m_pMappedData.
Allocations, deallocations, any change in m_pMetadata is protected by parent's VmaBlockVector::m_Mutex.
*/
public:
VMA_MUTEX m_MapAndBindMutex;
private:
VmaMappingHysteresis m_MappingHysteresis;
uint32_t m_MapCount;
void* m_pMappedData;
Expand Down
117 changes: 117 additions & 0 deletions framework/decode/vulkan_default_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,51 @@ void VulkanDefaultAllocator::DestroyImage(VkImage image,
functions_.destroy_image(device_, image, allocation_callbacks);
}

VkResult VulkanDefaultAllocator::CreateVideoSession(const VkVideoSessionCreateInfoKHR* create_info,
const VkAllocationCallbacks* allocation_callbacks,
format::HandleId capture_id,
VkVideoSessionKHR* session,
std::vector<ResourceData>* allocator_datas)
{
VkResult result = VK_ERROR_INITIALIZATION_FAILED;

if (allocator_datas != nullptr)
{
result = functions_.create_video_session(device_, create_info, allocation_callbacks, session);

if (result >= 0)
{
uint32_t count = 0;
functions_.get_video_session_memory_requirements(device_, *session, &count, nullptr);
allocator_datas->resize(count);
for (auto& allocator_data : *allocator_datas)
{
auto resource_alloc_info = new ResourceAllocInfo;
resource_alloc_info->capture_id = capture_id;
allocator_data = reinterpret_cast<ResourceData>(resource_alloc_info);
}
}
}

return result;
}

void VulkanDefaultAllocator::DestroyVideoSession(VkVideoSessionKHR session,
const VkAllocationCallbacks* allocation_callbacks,
std::vector<ResourceData> allocator_datas)
{
for (auto allocator_data : allocator_datas)
{
if (allocator_data != 0)
{
auto resource_alloc_info = reinterpret_cast<ResourceAllocInfo*>(allocator_data);
delete resource_alloc_info;
}
}

functions_.destroy_video_session(device_, session, allocation_callbacks);
}

void VulkanDefaultAllocator::GetImageSubresourceLayout(VkImage image,
const VkImageSubresource* subresource,
VkSubresourceLayout* layout,
Expand Down Expand Up @@ -344,6 +389,48 @@ VkResult VulkanDefaultAllocator::BindImageMemory2(uint32_t b
return result;
}

VkResult VulkanDefaultAllocator::BindVideoSessionMemory(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_session_datas,
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties)
{
VkResult result = VK_ERROR_INITIALIZATION_FAILED;

if ((bind_infos != nullptr) && (allocator_session_datas != nullptr) && (allocator_memory_datas != nullptr) &&
(bind_memory_properties != nullptr))
{
result = functions_.bind_video_session_memory(device_, video_session, bind_info_count, bind_infos);

if (result == VK_SUCCESS)
{
for (uint32_t i = 0; i < bind_info_count; ++i)
{
auto allocator_session_data = allocator_session_datas[i];
auto allocator_memory_data = allocator_memory_datas[i];

if ((allocator_session_data != 0) && (allocator_memory_data != 0))
{
auto resource_alloc_info = reinterpret_cast<ResourceAllocInfo*>(allocator_session_data);
resource_alloc_info->bound_memory = bind_infos[i].memory;
resource_alloc_info->bound_offset = bind_infos[i].memoryOffset;

auto memory_alloc_info = reinterpret_cast<MemoryAllocInfo*>(allocator_memory_data);
bind_memory_properties[i] = memory_alloc_info->property_flags;
}
else
{
GFXRECON_LOG_WARNING("VulkanDefaultAllocator binding a VkVideoSessionKHR object to a "
"VkDeviceMemory object without allocator data");
}
}
}
}

return result;
}

VkResult VulkanDefaultAllocator::MapMemory(VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
Expand Down Expand Up @@ -513,6 +600,36 @@ void VulkanDefaultAllocator::ReportBindImage2Incompatibility(uint32_t
}
}

void VulkanDefaultAllocator::ReportBindVideoSessionIncompatibility(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_resource_datas,
const MemoryData* allocator_memory_datas)
{
GFXRECON_UNREFERENCED_PARAMETER(allocator_resource_datas);

if ((bind_infos != nullptr) && (allocator_memory_datas != nullptr))
{
uint32_t session_requirements_count = 0;
functions_.get_video_session_memory_requirements(device_, video_session, &session_requirements_count, nullptr);

VkVideoSessionMemoryRequirementsKHR reqs = {};
reqs.sType = VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR;
std::vector<VkVideoSessionMemoryRequirementsKHR> session_requirements(session_requirements_count, reqs);
functions_.get_video_session_memory_requirements(
device_, video_session, &session_requirements_count, session_requirements.data());

std::vector<VkMemoryRequirements> requirements;
for (uint32_t i = 0; i < bind_info_count; ++i)
{
auto mem_index = bind_infos[i].memoryBindIndex;
requirements.emplace_back(session_requirements[mem_index].memoryRequirements);
}

ReportBindIncompatibility(requirements.data(), allocator_memory_datas, bind_info_count);
}
}

void VulkanDefaultAllocator::ReportBindIncompatibility(const VkMemoryRequirements* requirements,
const MemoryData* allocator_memory_datas,
uint32_t resource_count)
Expand Down
25 changes: 25 additions & 0 deletions framework/decode/vulkan_default_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ class VulkanDefaultAllocator : public VulkanResourceAllocator
const VkAllocationCallbacks* allocation_callbacks,
ResourceData allocator_data) override;

virtual VkResult CreateVideoSession(const VkVideoSessionCreateInfoKHR* create_info,
const VkAllocationCallbacks* allocation_callbacks,
format::HandleId capture_id,
VkVideoSessionKHR* session,
std::vector<ResourceData>* allocator_datas) override;

virtual void DestroyVideoSession(VkVideoSessionKHR session,
const VkAllocationCallbacks* allocation_callbacks,
std::vector<ResourceData> allocator_datas) override;

virtual void GetImageSubresourceLayout(VkImage image,
const VkImageSubresource* subresource,
VkSubresourceLayout* layout,
Expand Down Expand Up @@ -118,6 +128,13 @@ class VulkanDefaultAllocator : public VulkanResourceAllocator
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties) override;

virtual VkResult BindVideoSessionMemory(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_session_datas,
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties) override;

virtual VkResult MapMemory(VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
Expand Down Expand Up @@ -158,6 +175,12 @@ class VulkanDefaultAllocator : public VulkanResourceAllocator
const ResourceData* allocator_resource_datas,
const MemoryData* allocator_memory_datas) override;

virtual void ReportBindVideoSessionIncompatibility(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_resource_datas,
const MemoryData* allocator_memory_datas) override;

// Direct allocation methods that perform memory allocation and resource creation without performing memory
// translation. These methods allow the replay tool to allocate staging resources through the resource allocator so
// that the allocator is aware of all allocations performed at replay.
Expand Down Expand Up @@ -251,6 +274,8 @@ class VulkanDefaultAllocator : public VulkanResourceAllocator

virtual bool SupportsOpaqueDeviceAddresses() override { return true; }

virtual bool SupportBindVideoSessionMemory() override { return false; }

protected:
struct ResourceAllocInfo
{
Expand Down
8 changes: 8 additions & 0 deletions framework/decode/vulkan_object_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,14 @@ struct DeferredOperationKHRInfo : public VulkanObjectInfo<VkDeferredOperationKHR
struct VideoSessionKHRInfo : VulkanObjectInfo<VkVideoSessionKHR>
{
std::unordered_map<uint32_t, size_t> array_counts;

// The following values are only used for memory portability.
std::vector<VulkanResourceAllocator::ResourceData> allocator_datas;

// This is only used when loading the initial state for trimmed files.
std::vector<VkMemoryPropertyFlags> memory_property_flags;

uint32_t queue_family_index{ 0 };
};

struct ShaderEXTInfo : VulkanObjectInfo<VkShaderEXT>
Expand Down
38 changes: 38 additions & 0 deletions framework/decode/vulkan_realign_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,44 @@ VkResult VulkanRealignAllocator::BindImageMemory2(uint32_t b
bind_memory_properties);
}

VkResult VulkanRealignAllocator::BindVideoSessionMemory(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_session_datas,
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties)
{
std::unique_ptr<VkBindVideoSessionMemoryInfoKHR[]> realign_bind_infos;

if ((allocator_session_datas != nullptr) && (bind_infos != nullptr))
{
realign_bind_infos = std::make_unique<VkBindVideoSessionMemoryInfoKHR[]>(bind_info_count);

for (uint32_t i = 0; i < bind_info_count; ++i)
{
realign_bind_infos[i] = bind_infos[i];

auto resource_info = GetResourceAllocInfo(allocator_session_datas[i]);
if (resource_info != nullptr)
{
// Update video seesion to new binding offset from first pass data collected from resource tracking.
auto tracked_session_info = tracked_object_table_->GetTrackedResourceInfo(resource_info->capture_id);
if (tracked_session_info != nullptr)
{
realign_bind_infos[i].memoryOffset = tracked_session_info->GetReplayBindOffset();
}
}
}
}

return VulkanDefaultAllocator::BindVideoSessionMemory(video_session,
bind_info_count,
realign_bind_infos.get(),
allocator_session_datas,
allocator_memory_datas,
bind_memory_properties);
}

VkResult VulkanRealignAllocator::MapMemory(VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
Expand Down
7 changes: 7 additions & 0 deletions framework/decode/vulkan_realign_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ class VulkanRealignAllocator : public VulkanDefaultAllocator
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties) override;

virtual VkResult BindVideoSessionMemory(VkVideoSessionKHR video_session,
uint32_t bind_info_count,
const VkBindVideoSessionMemoryInfoKHR* bind_infos,
const ResourceData* allocator_session_datas,
const MemoryData* allocator_memory_datas,
VkMemoryPropertyFlags* bind_memory_properties) override;

virtual VkResult MapMemory(VkDeviceMemory memory,
VkDeviceSize offset,
VkDeviceSize size,
Expand Down
Loading
Loading