diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 3efd383e..68132441 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -66,8 +66,10 @@ namespace dxvk { 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) + if (buffer->size() == DefaultStagingBufferSize) { m_recycledStagingBuffers.returnObject(buffer); + buffer->reset(); + } } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index df1414ca..84961dec 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -141,6 +141,12 @@ namespace dxvk { return m_info; } + /** + * \brief Size of a mipmap level + * + * \param [in] level Mip level + * \returns Size of that level + */ VkExtent3D mipLevelExtent(uint32_t level) const { VkExtent3D size = m_info.extent; size.width = std::max(1u, size.width >> level); diff --git a/src/dxvk/dxvk_staging.h b/src/dxvk/dxvk_staging.h index dae02f4e..6d876dc9 100644 --- a/src/dxvk/dxvk_staging.h +++ b/src/dxvk/dxvk_staging.h @@ -6,6 +6,12 @@ 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; @@ -13,23 +19,53 @@ namespace dxvk { }; + /** + * \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: @@ -42,6 +78,12 @@ namespace dxvk { }; + /** + * \brief Staging buffer allocator + * + * Convenient allocator for staging buffer slices + * which creates new staging buffers on demand. + */ class DxvkStagingAlloc { public: @@ -49,9 +91,24 @@ namespace dxvk { 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: