From 1ba6b81901dfa1ebaf070e392c063bd1cbc75dbc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 25 Sep 2024 17:35:30 +0200 Subject: [PATCH] [dxvk] Reimplement imported buffers --- src/dxvk/dxvk_buffer.cpp | 11 +++++++++-- src/dxvk/dxvk_buffer.h | 20 ++------------------ src/dxvk/dxvk_device.cpp | 3 ++- src/dxvk/dxvk_memory.cpp | 17 +++++++++++++++++ src/dxvk/dxvk_memory.h | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index 159f97066..86fe9b2b2 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -25,13 +25,20 @@ namespace dxvk { DxvkDevice* device, const DxvkBufferCreateInfo& createInfo, const DxvkBufferImportInfo& importInfo, + DxvkMemoryAllocator& allocator, VkMemoryPropertyFlags memFlags) : m_vkd (device->vkd()), + m_allocator (&allocator), m_properties (memFlags), m_shaderStages (util::shaderStages(createInfo.stages)), - m_info (createInfo), - m_import (importInfo) { + m_info (createInfo) { + VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + info.flags = m_info.flags; + info.usage = m_info.usage; + info.size = m_info.size; + info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + assignSlice(allocator.importBufferResource(info, importInfo)); } diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 5be696d6e..4e8ebb0eb 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -59,22 +59,6 @@ namespace dxvk { VkBufferUsageFlags usage = 0u; }; - - /** - * \brief Buffer import info - * - * Used to import an existing Vulkan buffer. Note - * that imported buffers must not be renamed. - */ - struct DxvkBufferImportInfo { - /// Buffer handle - VkBuffer buffer = VK_NULL_HANDLE; - /// Buffer offset - VkDeviceSize offset = 0; - /// Pointer to mapped memory region - void* mapPtr = nullptr; - }; - /** * \brief Buffer slice info @@ -213,6 +197,7 @@ namespace dxvk { DxvkDevice* device, const DxvkBufferCreateInfo& createInfo, const DxvkBufferImportInfo& importInfo, + DxvkMemoryAllocator& memAlloc, VkMemoryPropertyFlags memFlags); ~DxvkBuffer(); @@ -387,7 +372,7 @@ namespace dxvk { * \returns \c true if the buffer is imported */ bool isForeign() const { - return m_import.buffer != VK_NULL_HANDLE; + return m_storage->flags().test(DxvkAllocationFlag::Imported); } /** @@ -407,7 +392,6 @@ namespace dxvk { VkShaderStageFlags m_shaderStages = 0u; DxvkBufferCreateInfo m_info = { }; - DxvkBufferImportInfo m_import = { }; uint32_t m_xfbStride = 0u; uint32_t m_version = 0u; diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 436c8fae4..7da493c40 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -218,7 +218,8 @@ namespace dxvk { const DxvkBufferCreateInfo& createInfo, const DxvkBufferImportInfo& importInfo, VkMemoryPropertyFlags memoryType) { - return new DxvkBuffer(this, createInfo, importInfo, memoryType); + return new DxvkBuffer(this, createInfo, + importInfo, m_objects.memoryManager(), memoryType); } diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index f69b4d74c..d2b447765 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -907,6 +907,23 @@ namespace dxvk { } + Rc DxvkMemoryAllocator::importBufferResource( + const VkBufferCreateInfo& createInfo, + const DxvkBufferImportInfo& importInfo) { + Rc allocation = m_allocationPool.create(this, nullptr); + allocation->m_flags.set(DxvkAllocationFlag::Imported); + allocation->m_size = createInfo.size; + allocation->m_mapPtr = importInfo.mapPtr; + allocation->m_buffer = importInfo.buffer; + allocation->m_bufferOffset = importInfo.offset; + + if (createInfo.usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT) + allocation->m_bufferAddress = getBufferDeviceAddress(importInfo.buffer) + importInfo.offset; + + return allocation; + } + + DxvkDeviceMemory DxvkMemoryAllocator::allocateDeviceMemory( DxvkMemoryType& type, VkDeviceSize size, diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index a4e8e9258..bae1196d5 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -424,6 +424,7 @@ namespace dxvk { OwnsBuffer = 1, OwnsImage = 2, Cacheable = 3, + Imported = 4, }; using DxvkAllocationFlags = Flags; @@ -504,6 +505,14 @@ namespace dxvk { return cur >= getIncrement(access); } + /** + * \brief Queries allocation flags + * \returns Allocation flags + */ + DxvkAllocationFlags flags() const { + return m_flags; + } + /** * \brief Queries mapped memory region * \returns Mapped memory region @@ -988,6 +997,22 @@ namespace dxvk { }; + /** + * \brief Buffer import info + * + * Used to import an existing Vulkan buffer. Note + * that imported buffers must not be renamed. + */ + struct DxvkBufferImportInfo { + /// Buffer handle + VkBuffer buffer = VK_NULL_HANDLE; + /// Buffer offset + VkDeviceSize offset = 0; + /// Pointer to mapped memory region + void* mapPtr = nullptr; + }; + + /** * \brief Memory allocator * @@ -1106,6 +1131,17 @@ namespace dxvk { VkBufferUsageFlags bufferUsage, VkMemoryPropertyFlags properties); + /** + * \brief Imports existing buffer resource + * + * \param [in] createInfo Buffer create info + * \param [in] importInfo Buffer import info + * \returns Buffer resource + */ + Rc importBufferResource( + const VkBufferCreateInfo& createInfo, + const DxvkBufferImportInfo& importInfo); + /** * \brief Queries memory stats *