From 3813af2f3c4536e14950b95b8211788b9a6b243f Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 25 Dec 2019 18:12:17 -0300 Subject: vk_staging_buffer_pool: Add a staging pool for temporary operations The job of this abstraction is to provide staging buffers for temporary operations. Think of image uploads or buffer uploads to device memory. It automatically deletes unused buffers. --- .../renderer_vulkan/vk_staging_buffer_pool.h | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/video_core/renderer_vulkan/vk_staging_buffer_pool.h (limited to 'src/video_core/renderer_vulkan/vk_staging_buffer_pool.h') diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h new file mode 100644 index 000000000..4530749f0 --- /dev/null +++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h @@ -0,0 +1,83 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include + +#include "common/common_types.h" + +#include "video_core/renderer_vulkan/declarations.h" +#include "video_core/renderer_vulkan/vk_memory_manager.h" + +namespace Vulkan { + +class VKDevice; +class VKFenceWatch; +class VKScheduler; + +struct VKBuffer final { + UniqueBuffer handle; + VKMemoryCommit commit; +}; + +class VKStagingBufferPool final { +public: + explicit VKStagingBufferPool(const VKDevice& device, VKMemoryManager& memory_manager, + VKScheduler& scheduler); + ~VKStagingBufferPool(); + + VKBuffer& GetUnusedBuffer(std::size_t size, bool host_visible); + + void TickFrame(); + +private: + struct StagingBuffer final { + explicit StagingBuffer(std::unique_ptr buffer, VKFence& fence, u64 last_epoch); + StagingBuffer(StagingBuffer&& rhs) noexcept; + StagingBuffer(const StagingBuffer&) = delete; + ~StagingBuffer(); + + StagingBuffer& operator=(StagingBuffer&& rhs) noexcept; + + std::unique_ptr buffer; + VKFenceWatch watch; + u64 last_epoch; + }; + + struct StagingBuffers final { + std::vector entries; + std::size_t delete_index = 0; + }; + + static constexpr std::size_t NumLevels = sizeof(std::size_t) * CHAR_BIT; + using StagingBuffersCache = std::array; + + VKBuffer* TryGetReservedBuffer(std::size_t size, bool host_visible); + + VKBuffer& CreateStagingBuffer(std::size_t size, bool host_visible); + + StagingBuffersCache& GetCache(bool host_visible); + + void ReleaseCache(bool host_visible); + + u64 ReleaseLevel(StagingBuffersCache& cache, std::size_t log2); + + const VKDevice& device; + VKMemoryManager& memory_manager; + VKScheduler& scheduler; + const bool is_device_integrated; + + StagingBuffersCache host_staging_buffers; + StagingBuffersCache device_staging_buffers; + + u64 epoch = 0; + + std::size_t current_delete_level = 0; +}; + +} // namespace Vulkan -- cgit v1.2.3