From ae6c052ed9f7e3baed13e1e88e759a3a11d2c928 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 14 Feb 2019 13:39:12 -0300 Subject: vk_resource_manager: Implement a command buffer pool with VKFencedPool --- .../renderer_vulkan/vk_resource_manager.cpp | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'src/video_core/renderer_vulkan/vk_resource_manager.cpp') 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(); + + // 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(COMMAND_BUFFER_POOL_SIZE)); + pool->cmdbufs = + dev.allocateCommandBuffersUnique>(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 cmdbufs; + }; + + const VKDevice& device; + + std::vector> 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(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(); -- cgit v1.2.3