diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 65893de52..db43f9090 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -73,50 +73,6 @@ namespace dxvk { } - Rc DxvkDevice::allocStagingBuffer(VkDeviceSize size) { - // In case we need a standard-size staging buffer, try - // to recycle an old one that has been returned earlier - if (size <= DefaultStagingBufferSize) { - const Rc buffer - = m_recycledStagingBuffers.retrieveObject(); - - if (buffer != nullptr) - return buffer; - } - - // Staging buffers only need to be able to handle transfer - // operations, and they need to be in host-visible memory. - DxvkBufferCreateInfo info; - info.size = size; - info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT - | VK_PIPELINE_STAGE_HOST_BIT; - info.access = VK_ACCESS_TRANSFER_READ_BIT - | VK_ACCESS_HOST_WRITE_BIT; - - VkMemoryPropertyFlags memFlags - = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT - | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - - // Don't create buffers that are too small. A staging - // buffer should be able to serve multiple uploads. - if (info.size < DefaultStagingBufferSize) - info.size = DefaultStagingBufferSize; - - return new DxvkStagingBuffer(this->createBuffer(info, memFlags)); - } - - - void DxvkDevice::recycleStagingBuffer(const Rc& buffer) { - // Drop staging buffers that are bigger than the - // standard ones to save memory, recycle the rest - if (buffer->size() == DefaultStagingBufferSize) { - m_recycledStagingBuffers.returnObject(buffer); - buffer->reset(); - } - } - - Rc DxvkDevice::createCommandList() { Rc cmdList = m_recycledCommandLists.retrieveObject(); diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index f612c9d78..962c557dc 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -58,8 +58,6 @@ namespace dxvk { friend class DxvkContext; friend class DxvkSubmissionQueue; friend class DxvkDescriptorPoolTracker; - - constexpr static VkDeviceSize DefaultStagingBufferSize = 4 * 1024 * 1024; public: DxvkDevice( @@ -153,29 +151,6 @@ namespace dxvk { */ DxvkDeviceOptions options() const; - /** - * \brief Allocates a staging buffer - * - * Returns a staging buffer that is at least as large - * as the requested size. It is usually bigger so that - * a single staging buffer may serve multiple allocations. - * \param [in] size Minimum buffer size - * \returns The staging buffer - */ - Rc allocStagingBuffer( - VkDeviceSize size); - - /** - * \brief Recycles a staging buffer - * - * When a staging buffer is no longer needed, it should - * be returned to the device so that it can be reused - * for subsequent allocations. - * \param [in] buffer The buffer - */ - void recycleStagingBuffer( - const Rc& buffer); - /** * \brief Creates a command list * \returns The command list @@ -437,7 +412,6 @@ namespace dxvk { DxvkRecycler m_recycledCommandLists; DxvkRecycler m_recycledDescriptorPools; - DxvkRecycler m_recycledStagingBuffers; DxvkSubmissionQueue m_submissionQueue; diff --git a/src/dxvk/dxvk_staging.cpp b/src/dxvk/dxvk_staging.cpp index 4ea8a66ff..1c0892288 100644 --- a/src/dxvk/dxvk_staging.cpp +++ b/src/dxvk/dxvk_staging.cpp @@ -3,94 +3,6 @@ namespace dxvk { - DxvkStagingBuffer::DxvkStagingBuffer( - const Rc& buffer) - : m_buffer(buffer), m_bufferSize(buffer->info().size){ - - } - - - DxvkStagingBuffer::~DxvkStagingBuffer() { - - } - - - VkDeviceSize DxvkStagingBuffer::size() const { - return m_bufferSize; - } - - - VkDeviceSize DxvkStagingBuffer::freeBytes() const { - return m_bufferSize >= m_bufferOffset - ? m_bufferSize - m_bufferOffset - : VkDeviceSize(0); - } - - - bool DxvkStagingBuffer::alloc( - VkDeviceSize size, - DxvkStagingBufferSlice& slice) { - if (m_bufferOffset + size > m_bufferSize) - return false; - - auto physSlice = m_buffer->getSliceHandle(m_bufferOffset, size); - slice.buffer = physSlice.handle; - slice.offset = physSlice.offset; - slice.mapPtr = physSlice.mapPtr; - - m_bufferOffset = align(m_bufferOffset + size, 64); - return true; - } - - - void DxvkStagingBuffer::reset() { - m_bufferOffset = 0; - } - - - DxvkStagingAlloc::DxvkStagingAlloc(DxvkDevice* device) - : m_device(device) { } - - - DxvkStagingAlloc::~DxvkStagingAlloc() { - this->reset(); - } - - - DxvkStagingBufferSlice DxvkStagingAlloc::alloc(VkDeviceSize size) { - Rc selectedBuffer; - - // Try a worst-fit allocation strategy on the existing staging - // buffers first. This should keep the amount of wasted space - // small, especially if there are large allocations. - for (const auto& buf : m_stagingBuffers) { - if (selectedBuffer == nullptr || (buf->freeBytes() > selectedBuffer->freeBytes())) - selectedBuffer = buf; - } - - // If we have no suitable buffer, allocate one from the device - // that is *at least* as large as the amount of data we need - // to upload. Usually it will be bigger. - DxvkStagingBufferSlice slice; - - if ((selectedBuffer == nullptr) || (!selectedBuffer->alloc(size, slice))) { - selectedBuffer = m_device->allocStagingBuffer(size); - selectedBuffer->alloc(size, slice); - m_stagingBuffers.push_back(selectedBuffer); - } - - return slice; - } - - - void DxvkStagingAlloc::reset() { - for (const auto& buf : m_stagingBuffers) - m_device->recycleStagingBuffer(buf); - - m_stagingBuffers.resize(0); - } - - DxvkStagingDataAlloc::DxvkStagingDataAlloc(const Rc& device) : m_device(device) { diff --git a/src/dxvk/dxvk_staging.h b/src/dxvk/dxvk_staging.h index f76c9ecf5..8bff39cb4 100644 --- a/src/dxvk/dxvk_staging.h +++ b/src/dxvk/dxvk_staging.h @@ -7,120 +7,6 @@ namespace dxvk { class DxvkDevice; - - /** - * \brief Staging buffer slice - * - * Provides the application with a - * pointer to the mapped buffer. - */ - struct DxvkStagingBufferSlice { - VkBuffer buffer = VK_NULL_HANDLE; - VkDeviceSize offset = 0; - void* mapPtr = nullptr; - }; - - - /** - * \brief Staging uffer - * - * A mapped buffer that can be used for fast data - * transfer operations from the host to the GPU. - * Implements a linear sub-allocator for staging - * buffer slices. - */ - class DxvkStagingBuffer : public RcObject { - - public: - - DxvkStagingBuffer( - const Rc& buffer); - ~DxvkStagingBuffer(); - - /** - * \brief Buffer size, in bytes - * \returns Buffer size, in bytes - */ - VkDeviceSize size() const; - - /** - * \brief Number of bytes still available - * \returns Number of bytes still available - */ - VkDeviceSize freeBytes() const; - - /** - * \brief Allocates a staging buffer slice - * - * This may fail if the amount of data requested is - * larger than the amount of data still available. - * \param [in] size Requested allocation size - * \param [out] slice Allocated staging buffer slice - * \returns \c true on success, \c false on failure - */ - bool alloc( - VkDeviceSize size, - DxvkStagingBufferSlice& slice); - - /** - * \brief Resets staging buffer - * - * Resets the allocator and thus frees - * all slices allocated from the buffer. - */ - void reset(); - - private: - - Rc m_buffer; - - VkDeviceSize m_bufferSize = 0; - VkDeviceSize m_bufferOffset = 0; - - }; - - - /** - * \brief Staging buffer allocator - * - * Convenient allocator for staging buffer slices - * which creates new staging buffers on demand. - */ - class DxvkStagingAlloc { - - public: - - DxvkStagingAlloc(DxvkDevice* device); - ~DxvkStagingAlloc(); - - /** - * \brief Allocates a staging buffer slice - * - * This \e may create a new staging buffer - * if needed. This method should not fail. - * \param [in] size Required amount of memory - * \returns Allocated staging buffer slice - */ - DxvkStagingBufferSlice alloc( - VkDeviceSize size); - - /** - * \brief Resets staging buffer allocator - * - * Returns all buffers to the device so that - * they can be recycled. Buffers must not be - * in use when this is called. - */ - void reset(); - - private: - - DxvkDevice* const m_device; - - std::vector> m_stagingBuffers; - - }; - /** * \brief Staging data allocator