diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-02-14 17:39:12 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-02-14 22:44:26 +0100 |
commit | ae6c052ed9f7e3baed13e1e88e759a3a11d2c928 (patch) | |
tree | e9b6fe1189c7e7877bae4bc2cb21f3380e2f78c1 | |
parent | vk_resource_manager: Add VKFencedPool interface (diff) | |
download | yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar.gz yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar.bz2 yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar.lz yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar.xz yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.tar.zst yuzu-ae6c052ed9f7e3baed13e1e88e759a3a11d2c928.zip |
-rw-r--r-- | src/video_core/renderer_vulkan/vk_resource_manager.cpp | 52 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_resource_manager.h | 8 |
2 files changed, 59 insertions, 1 deletions
diff --git a/src/video_core/renderer_vulkan/vk_resource_manager.cpp b/src/video_core/renderer_vulkan/vk_resource_manager.cpp index e98ddba58..1678463c7 100644 --- a/src/video_core/renderer_vulkan/vk_resource_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_resource_manager.cpp @@ -13,8 +13,55 @@ namespace Vulkan { // TODO(Rodrigo): Fine tune these numbers. +constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 0x1000; constexpr std::size_t FENCES_GROW_STEP = 0x40; +class CommandBufferPool final : public VKFencedPool { +public: + CommandBufferPool(const VKDevice& device) + : VKFencedPool(COMMAND_BUFFER_POOL_SIZE), device{device} {} + + void Allocate(std::size_t begin, std::size_t end) { + const auto dev = device.GetLogical(); + const auto& dld = device.GetDispatchLoader(); + const u32 graphics_family = device.GetGraphicsFamily(); + + auto pool = std::make_unique<Pool>(); + + // Command buffers are going to be commited, recorded, executed every single usage cycle. + // They are also going to be reseted when commited. + const auto pool_flags = vk::CommandPoolCreateFlagBits::eTransient | + vk::CommandPoolCreateFlagBits::eResetCommandBuffer; + const vk::CommandPoolCreateInfo cmdbuf_pool_ci(pool_flags, graphics_family); + pool->handle = dev.createCommandPoolUnique(cmdbuf_pool_ci, nullptr, dld); + + const vk::CommandBufferAllocateInfo cmdbuf_ai(*pool->handle, + vk::CommandBufferLevel::ePrimary, + static_cast<u32>(COMMAND_BUFFER_POOL_SIZE)); + pool->cmdbufs = + dev.allocateCommandBuffersUnique<std::allocator<UniqueCommandBuffer>>(cmdbuf_ai, dld); + + pools.push_back(std::move(pool)); + } + + vk::CommandBuffer Commit(VKFence& fence) { + const std::size_t index = CommitResource(fence); + const auto pool_index = index / COMMAND_BUFFER_POOL_SIZE; + const auto sub_index = index % COMMAND_BUFFER_POOL_SIZE; + return *pools[pool_index]->cmdbufs[sub_index]; + } + +private: + struct Pool { + UniqueCommandPool handle; + std::vector<UniqueCommandBuffer> cmdbufs; + }; + + const VKDevice& device; + + std::vector<std::unique_ptr<Pool>> pools; +}; + VKResource::VKResource() = default; VKResource::~VKResource() = default; @@ -174,6 +221,7 @@ void VKFencedPool::Grow() { VKResourceManager::VKResourceManager(const VKDevice& device) : device{device} { GrowFences(FENCES_GROW_STEP); + command_buffer_pool = std::make_unique<CommandBufferPool>(device); } VKResourceManager::~VKResourceManager() = default; @@ -217,6 +265,10 @@ VKFence& VKResourceManager::CommitFence() { return *found_fence; } +vk::CommandBuffer VKResourceManager::CommitCommandBuffer(VKFence& fence) { + return command_buffer_pool->Commit(fence); +} + void VKResourceManager::GrowFences(std::size_t new_fences_count) { const auto dev = device.GetLogical(); const auto& dld = device.GetDispatchLoader(); diff --git a/src/video_core/renderer_vulkan/vk_resource_manager.h b/src/video_core/renderer_vulkan/vk_resource_manager.h index 1fd68bb4c..5018dfa44 100644 --- a/src/video_core/renderer_vulkan/vk_resource_manager.h +++ b/src/video_core/renderer_vulkan/vk_resource_manager.h @@ -15,6 +15,8 @@ class VKDevice; class VKFence; class VKResourceManager; +class CommandBufferPool; + /// Interface for a Vulkan resource class VKResource { public: @@ -162,13 +164,17 @@ public: /// Commits a fence. It has to be sent to a queue and released. VKFence& CommitFence(); + /// Commits an unused command buffer and protects it with a fence. + vk::CommandBuffer CommitCommandBuffer(VKFence& fence); + private: /// Allocates new fences. void GrowFences(std::size_t new_fences_count); const VKDevice& device; ///< Device handler. std::size_t fences_iterator = 0; ///< Index where a free fence is likely to be found. - std::vector<std::unique_ptr<VKFence>> fences; ///< Pool of fences. + std::vector<std::unique_ptr<VKFence>> fences; ///< Pool of fences. + std::unique_ptr<CommandBufferPool> command_buffer_pool; ///< Pool of command buffers. }; } // namespace Vulkan |