diff --git a/src/dxvk/dxvk_buffer.cpp b/src/dxvk/dxvk_buffer.cpp index c086d57ad..1f71da961 100644 --- a/src/dxvk/dxvk_buffer.cpp +++ b/src/dxvk/dxvk_buffer.cpp @@ -77,5 +77,27 @@ namespace dxvk { DxvkSparsePageTable* DxvkBuffer::getSparsePageTable() { return m_storage->getSparsePageTable(); } + + + Rc DxvkBuffer::relocateStorage( + DxvkAllocationModes mode) { + // The resource may become non-relocatable even after we allocate new + // backing storage, but if it already is then don't waste memory. + if (!canRelocate()) + return nullptr; + + DxvkAllocationInfo allocationInfo = { }; + allocationInfo.resourceCookie = cookie(); + allocationInfo.properties = m_properties; + allocationInfo.mode = mode; + + VkBufferCreateInfo info = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; + info.flags = m_info.flags; + info.usage = m_info.usage; + info.size = m_info.size; + m_sharingMode.fill(info); + + return m_allocator->createBufferResource(info, allocationInfo, nullptr); + } } diff --git a/src/dxvk/dxvk_buffer.h b/src/dxvk/dxvk_buffer.h index 3d7ffd479..8cd0bc5fe 100644 --- a/src/dxvk/dxvk_buffer.h +++ b/src/dxvk/dxvk_buffer.h @@ -397,6 +397,15 @@ namespace dxvk { */ DxvkSparsePageTable* getSparsePageTable(); + /** + * \brief Allocates new backing storage with constraints + * + * \param [in] mode Allocation mode flags + * \returns Operation status and allocation + */ + Rc relocateStorage( + DxvkAllocationModes mode); + private: Rc m_vkd; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index a8db1d9fe..567781094 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1586,7 +1586,7 @@ namespace dxvk { DxvkImageUsageInfo usage = usageInfo; usage.flags |= createFlags; - auto storage = image->allocateStorageWithUsage(usage); + auto storage = image->allocateStorageWithUsage(usage, 0u); DxvkRelocateImageInfo relocateInfo; relocateInfo.image = image; diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 800fcf72a..9476fcc4b 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -108,6 +108,15 @@ namespace dxvk { } + Rc DxvkImage::relocateStorage( + DxvkAllocationModes mode) { + if (!canRelocate()) + return nullptr; + + return allocateStorageWithUsage(DxvkImageUsageInfo(), mode); + } + + Rc DxvkImage::createView( const DxvkImageViewKey& info) { std::unique_lock lock(m_viewMutex); @@ -120,11 +129,13 @@ namespace dxvk { Rc DxvkImage::allocateStorage() { - return allocateStorageWithUsage(DxvkImageUsageInfo()); + return allocateStorageWithUsage(DxvkImageUsageInfo(), 0u); } - Rc DxvkImage::allocateStorageWithUsage(const DxvkImageUsageInfo& usageInfo) { + Rc DxvkImage::allocateStorageWithUsage( + const DxvkImageUsageInfo& usageInfo, + DxvkAllocationModes mode) { const DxvkFormatInfo* formatInfo = lookupFormatInfo(m_info.format); small_vector localViewFormats; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index f28ac4ee2..784416db2 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -515,6 +515,15 @@ namespace dxvk { */ DxvkSparsePageTable* getSparsePageTable(); + /** + * \brief Allocates new backing storage with constraints + * + * \param [in] mode Allocation mode flags + * \returns Operation status and allocation + */ + Rc relocateStorage( + DxvkAllocationModes mode); + /** * \brief Creates image resource * @@ -529,10 +538,12 @@ namespace dxvk { * Creates new backing storage with additional usage flags * enabled. Useful to expand on usage flags after creation. * \param [in] usage Usage flags to add + * \param [in] mode Allocation constraints * \returns New underlying image resource */ Rc allocateStorageWithUsage( - const DxvkImageUsageInfo& usage); + const DxvkImageUsageInfo& usage, + DxvkAllocationModes mode); /** * \brief Assigns backing storage to the image diff --git a/src/dxvk/dxvk_sparse.h b/src/dxvk/dxvk_sparse.h index 04bef8e9a..ee026a7b5 100644 --- a/src/dxvk/dxvk_sparse.h +++ b/src/dxvk/dxvk_sparse.h @@ -522,6 +522,21 @@ namespace dxvk { */ virtual DxvkSparsePageTable* getSparsePageTable() = 0; + /** + * \brief Allocates new backing storage with constraints + * + * \param [in] mode Allocation mode flags to control behaviour. + * When relocating the resource to a preferred memory type, + * \c NoFallback should be set, when defragmenting device + * memory then \c NoAllocation should also be set. + * \returns \c true in the first field if the operation is + * considered successful, i.e. if an new backing allocation + * was successfully created or is unnecessary. The second + * field will contain the new allocation itself. + */ + virtual Rc relocateStorage( + DxvkAllocationModes mode) = 0; + private: std::atomic m_useCount = { 0u };