summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 @@
13namespace Vulkan { 13namespace Vulkan {
14 14
15// TODO(Rodrigo): Fine tune these numbers. 15// TODO(Rodrigo): Fine tune these numbers.
16constexpr std::size_t COMMAND_BUFFER_POOL_SIZE = 0x1000;
16constexpr std::size_t FENCES_GROW_STEP = 0x40; 17constexpr std::size_t FENCES_GROW_STEP = 0x40;
17 18
19class CommandBufferPool final : public VKFencedPool {
20public:
21 CommandBufferPool(const VKDevice& device)
22 : VKFencedPool(COMMAND_BUFFER_POOL_SIZE), device{device} {}
23
24 void Allocate(std::size_t begin, std::size_t end) {
25 const auto dev = device.GetLogical();
26 const auto& dld = device.GetDispatchLoader();
27 const u32 graphics_family = device.GetGraphicsFamily();
28
29 auto pool = std::make_unique<Pool>();
30
31 // Command buffers are going to be commited, recorded, executed every single usage cycle.
32 // They are also going to be reseted when commited.
33 const auto pool_flags = vk::CommandPoolCreateFlagBits::eTransient |
34 vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
35 const vk::CommandPoolCreateInfo cmdbuf_pool_ci(pool_flags, graphics_family);
36 pool->handle = dev.createCommandPoolUnique(cmdbuf_pool_ci, nullptr, dld);
37
38 const vk::CommandBufferAllocateInfo cmdbuf_ai(*pool->handle,
39 vk::CommandBufferLevel::ePrimary,
40 static_cast<u32>(COMMAND_BUFFER_POOL_SIZE));
41 pool->cmdbufs =
42 dev.allocateCommandBuffersUnique<std::allocator<UniqueCommandBuffer>>(cmdbuf_ai, dld);
43
44 pools.push_back(std::move(pool));
45 }
46
47 vk::CommandBuffer Commit(VKFence& fence) {
48 const std::size_t index = CommitResource(fence);
49 const auto pool_index = index / COMMAND_BUFFER_POOL_SIZE;
50 const auto sub_index = index % COMMAND_BUFFER_POOL_SIZE;
51 return *pools[pool_index]->cmdbufs[sub_index];
52 }
53
54private:
55 struct Pool {
56 UniqueCommandPool handle;
57 std::vector<UniqueCommandBuffer> cmdbufs;
58 };
59
60 const VKDevice& device;
61
62 std::vector<std::unique_ptr<Pool>> pools;
63};
64
18VKResource::VKResource() = default; 65VKResource::VKResource() = default;
19 66
20VKResource::~VKResource() = default; 67VKResource::~VKResource() = default;
@@ -174,6 +221,7 @@ void VKFencedPool::Grow() {
174 221
175VKResourceManager::VKResourceManager(const VKDevice& device) : device{device} { 222VKResourceManager::VKResourceManager(const VKDevice& device) : device{device} {
176 GrowFences(FENCES_GROW_STEP); 223 GrowFences(FENCES_GROW_STEP);
224 command_buffer_pool = std::make_unique<CommandBufferPool>(device);
177} 225}
178 226
179VKResourceManager::~VKResourceManager() = default; 227VKResourceManager::~VKResourceManager() = default;
@@ -217,6 +265,10 @@ VKFence& VKResourceManager::CommitFence() {
217 return *found_fence; 265 return *found_fence;
218} 266}
219 267
268vk::CommandBuffer VKResourceManager::CommitCommandBuffer(VKFence& fence) {
269 return command_buffer_pool->Commit(fence);
270}
271
220void VKResourceManager::GrowFences(std::size_t new_fences_count) { 272void VKResourceManager::GrowFences(std::size_t new_fences_count) {
221 const auto dev = device.GetLogical(); 273 const auto dev = device.GetLogical();
222 const auto& dld = device.GetDispatchLoader(); 274 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;
15class VKFence; 15class VKFence;
16class VKResourceManager; 16class VKResourceManager;
17 17
18class CommandBufferPool;
19
18/// Interface for a Vulkan resource 20/// Interface for a Vulkan resource
19class VKResource { 21class VKResource {
20public: 22public:
@@ -162,13 +164,17 @@ public:
162 /// Commits a fence. It has to be sent to a queue and released. 164 /// Commits a fence. It has to be sent to a queue and released.
163 VKFence& CommitFence(); 165 VKFence& CommitFence();
164 166
167 /// Commits an unused command buffer and protects it with a fence.
168 vk::CommandBuffer CommitCommandBuffer(VKFence& fence);
169
165private: 170private:
166 /// Allocates new fences. 171 /// Allocates new fences.
167 void GrowFences(std::size_t new_fences_count); 172 void GrowFences(std::size_t new_fences_count);
168 173
169 const VKDevice& device; ///< Device handler. 174 const VKDevice& device; ///< Device handler.
170 std::size_t fences_iterator = 0; ///< Index where a free fence is likely to be found. 175 std::size_t fences_iterator = 0; ///< Index where a free fence is likely to be found.
171 std::vector<std::unique_ptr<VKFence>> fences; ///< Pool of fences. 176 std::vector<std::unique_ptr<VKFence>> fences; ///< Pool of fences.
177 std::unique_ptr<CommandBufferPool> command_buffer_pool; ///< Pool of command buffers.
172}; 178};
173 179
174} // namespace Vulkan 180} // namespace Vulkan