mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-09 13:36:35 +00:00
[TEST] Adjustments on CommandPools + ResetQueryPool
This commit is contained in:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user