[TEST] Adjustments on CommandPools + ResetQueryPool

This commit is contained in:
CamilleLaVey
2026-07-17 07:52:45 -04:00
parent e81d170458
commit e8b1dc7c0b
4 changed files with 52 additions and 15 deletions
@@ -1,9 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <cstddef> #include <cstddef>
#include "video_core/renderer_vulkan/vk_command_pool.h" #include "video_core/renderer_vulkan/vk_command_pool.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h"
#include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -14,32 +18,52 @@ constexpr size_t COMMAND_BUFFER_POOL_SIZE = 4;
struct CommandPool::Pool { struct CommandPool::Pool {
vk::CommandPool handle; vk::CommandPool handle;
vk::CommandBuffers cmdbufs; vk::CommandBuffers cmdbufs;
u64 tick;
}; };
CommandPool::CommandPool(MasterSemaphore& master_semaphore_, const Device& device_) CommandPool::CommandPool(MasterSemaphore& master_semaphore_, const Device& device_)
: ResourcePool(master_semaphore_, COMMAND_BUFFER_POOL_SIZE), device{device_} {} : master_semaphore{master_semaphore_}, device{device_} {}
CommandPool::~CommandPool() = default; CommandPool::~CommandPool() = default;
void CommandPool::Allocate(size_t begin, size_t end) { void CommandPool::AllocatePool() {
// Command buffers are going to be committed, recorded, executed every single usage cycle.
// They are also going to be reset when committed.
Pool& pool = pools.emplace_back(); Pool& pool = pools.emplace_back();
pool.handle = device.GetLogical().CreateCommandPool({ pool.handle = device.GetLogical().CreateCommandPool({
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = device.GetGraphicsFamily(), .queueFamilyIndex = device.GetGraphicsFamily(),
}); });
pool.cmdbufs = pool.handle.Allocate(COMMAND_BUFFER_POOL_SIZE); pool.cmdbufs = pool.handle.Allocate(COMMAND_BUFFER_POOL_SIZE);
pool.tick = 0;
}
void CommandPool::AcquirePool() {
if (!pools.empty()) {
master_semaphore.Refresh();
const u64 gpu_tick = master_semaphore.KnownGpuTick();
for (size_t i = 0; i < pools.size(); ++i) {
const size_t candidate = (current_pool + 1 + i) % pools.size();
if (gpu_tick >= pools[candidate].tick) {
current_pool = candidate;
current_index = 0;
pools[current_pool].handle.Reset();
return;
}
}
}
AllocatePool();
current_pool = pools.size() - 1;
current_index = 0;
} }
VkCommandBuffer CommandPool::Commit() { VkCommandBuffer CommandPool::Commit() {
const size_t index = CommitResource(); if (pools.empty() || current_index >= COMMAND_BUFFER_POOL_SIZE) {
const auto pool_index = index / COMMAND_BUFFER_POOL_SIZE; AcquirePool();
const auto sub_index = index % COMMAND_BUFFER_POOL_SIZE; }
return pools[pool_index].cmdbufs[sub_index]; Pool& pool = pools[current_pool];
pool.tick = master_semaphore.CurrentTick();
return pool.cmdbufs[current_index++];
} }
} // namespace Vulkan } // namespace Vulkan
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -6,7 +9,7 @@
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
#include "video_core/renderer_vulkan/vk_resource_pool.h" #include "common/common_types.h"
#include "video_core/vulkan_common/vulkan_wrapper.h" #include "video_core/vulkan_common/vulkan_wrapper.h"
namespace Vulkan { namespace Vulkan {
@@ -14,20 +17,24 @@ namespace Vulkan {
class Device; class Device;
class MasterSemaphore; class MasterSemaphore;
class CommandPool final : public ResourcePool { class CommandPool final {
public: public:
explicit CommandPool(MasterSemaphore& master_semaphore_, const Device& device_); explicit CommandPool(MasterSemaphore& master_semaphore_, const Device& device_);
~CommandPool() override; ~CommandPool();
void Allocate(size_t begin, size_t end) override;
VkCommandBuffer Commit(); VkCommandBuffer Commit();
private: private:
struct Pool; struct Pool;
void AllocatePool();
void AcquirePool();
MasterSemaphore& master_semaphore;
const Device& device; const Device& device;
std::vector<Pool> pools; std::vector<Pool> pools;
size_t current_pool = 0;
size_t current_index = 0;
}; };
} // namespace Vulkan } // namespace Vulkan
@@ -232,6 +232,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkMapMemory); X(vkMapMemory);
X(vkQueueSubmit); X(vkQueueSubmit);
X(vkQueueSubmit2); X(vkQueueSubmit2);
X(vkResetCommandPool);
X(vkResetFences); X(vkResetFences);
X(vkResetQueryPool); X(vkResetQueryPool);
X(vkSetDebugUtilsObjectNameEXT); X(vkSetDebugUtilsObjectNameEXT);
@@ -348,6 +348,7 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkMapMemory vkMapMemory{}; PFN_vkMapMemory vkMapMemory{};
PFN_vkQueueSubmit vkQueueSubmit{}; PFN_vkQueueSubmit vkQueueSubmit{};
PFN_vkQueueSubmit2 vkQueueSubmit2{}; PFN_vkQueueSubmit2 vkQueueSubmit2{};
PFN_vkResetCommandPool vkResetCommandPool{};
PFN_vkResetFences vkResetFences{}; PFN_vkResetFences vkResetFences{};
PFN_vkResetQueryPool vkResetQueryPool{}; PFN_vkResetQueryPool vkResetQueryPool{};
PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{}; PFN_vkSetDebugUtilsObjectNameEXT vkSetDebugUtilsObjectNameEXT{};
@@ -927,6 +928,10 @@ public:
CommandBuffers Allocate(std::size_t num_buffers, CommandBuffers Allocate(std::size_t num_buffers,
VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY) const; VkCommandBufferLevel level = VK_COMMAND_BUFFER_LEVEL_PRIMARY) const;
void Reset(VkCommandPoolResetFlags flags = 0) const {
Check(dld->vkResetCommandPool(owner, handle, flags));
}
/// Set object name. /// Set object name.
void SetObjectNameEXT(const char* name) const; void SetObjectNameEXT(const char* name) const;
}; };