summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-02-14 17:39:12 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2019-02-14 22:44:26 +0100
commitae6c052ed9f7e3baed13e1e88e759a3a11d2c928 (patch)
treee9b6fe1189c7e7877bae4bc2cb21f3380e2f78c1 /src/video_core
parentvk_resource_manager: Add VKFencedPool interface (diff)
downloadyuzu-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
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_vulkan/vk_resource_manager.cpp52
-rw-r--r--src/video_core/renderer_vulkan/vk_resource_manager.h8
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