From 0bc19472e8f79c1b1d4fb77d0bd4d966641e144d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 12 Feb 2022 16:45:13 +0100 Subject: [PATCH] [dxvk] Introduce DxvkStagingBuffer --- src/dxvk/dxvk_staging.cpp | 53 +++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_staging.h | 52 +++++++++++++++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_staging.cpp b/src/dxvk/dxvk_staging.cpp index dd2a1fd2..6882861f 100644 --- a/src/dxvk/dxvk_staging.cpp +++ b/src/dxvk/dxvk_staging.cpp @@ -66,5 +66,58 @@ namespace dxvk { VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); } + + + DxvkStagingBuffer::DxvkStagingBuffer( + const Rc& device, + VkDeviceSize size) + : m_device(device), m_offset(0), m_size(size) { + + } + + + DxvkStagingBuffer::~DxvkStagingBuffer() { + + } + + + DxvkBufferSlice DxvkStagingBuffer::alloc(VkDeviceSize align, VkDeviceSize size) { + DxvkBufferCreateInfo info; + info.size = size; + info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT + | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT + | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT + | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT + | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + info.access = VK_ACCESS_TRANSFER_READ_BIT + | VK_ACCESS_SHADER_READ_BIT; + + VkDeviceSize alignedSize = dxvk::align(size, align); + VkDeviceSize alignedOffset = dxvk::align(m_offset, align); + + if (alignedSize >= m_size) { + return DxvkBufferSlice(m_device->createBuffer(info, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)); + } + + if (alignedOffset + alignedSize > m_size || m_buffer == nullptr) { + info.size = m_size; + + m_buffer = m_device->createBuffer(info, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + alignedOffset = 0; + } + + DxvkBufferSlice slice(m_buffer, alignedOffset, size); + m_offset = alignedOffset + alignedSize; + return slice; + } + + + void DxvkStagingBuffer::reset() { + m_buffer = nullptr; + m_offset = 0; + } } diff --git a/src/dxvk/dxvk_staging.h b/src/dxvk/dxvk_staging.h index 8eccd4f5..b2a591ac 100644 --- a/src/dxvk/dxvk_staging.h +++ b/src/dxvk/dxvk_staging.h @@ -52,5 +52,55 @@ namespace dxvk { Rc createBuffer(VkDeviceSize size); }; - + + /** + * \brief Staging buffer + * + * Provides a simple linear staging buffer + * allocator for data uploads. + */ + class DxvkStagingBuffer { + + public: + + /** + * \brief Creates staging buffer + * + * \param [in] device DXVK device + * \param [in] size Buffer size + */ + DxvkStagingBuffer( + const Rc& device, + VkDeviceSize size); + + /** + * \brief Frees staging buffer + */ + ~DxvkStagingBuffer(); + + /** + * \brief Allocates staging buffer memory + * + * Tries to suballocate from existing buffer, + * or creates a new buffer if necessary. + * \param [in] align Minimum alignment + * \param [in] size Number of bytes to allocate + * \returns Allocated slice + */ + DxvkBufferSlice alloc(VkDeviceSize align, VkDeviceSize size); + + /** + * \brief Resets staging buffer and allocator + */ + void reset(); + + private: + + Rc m_device; + Rc m_buffer; + VkDeviceSize m_offset; + VkDeviceSize m_size; + + }; + }