aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2025-12-18 11:29:38 +0100
committercrueter <crueter@eden-emu.dev>2025-12-18 11:29:38 +0100
commit959f72297ded8520547604af6bf2807779cdb0b4 (patch)
treeee8b28bd9940090b9d0053f6af57e248db6cdd9c /src
parent057d566ff4df90b5f074d01025d0c969e7331838 (diff)
[vk] use boost::container::deque instead of std::queue for presentation swapchain of frames (#3120)
This may reduce total overhead (as benchmarks show boost::container::deque being better performing than std::deque, especially with the limited set of ops like push_front and pop_back May actually not help at all and be worse through, as always, performance tests are welcome Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3120 Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-by: Maufeat <sahyno1996@gmail.com> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.cpp57
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.h9
2 files changed, 32 insertions, 34 deletions
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp
index 0b29ad1389..3b5c2e3c01 100644
--- a/src/video_core/renderer_vulkan/vk_present_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp
@@ -146,7 +146,7 @@ PresentManager::PresentManager(const vk::Instance& instance_,
.pNext = nullptr,
.flags = VK_FENCE_CREATE_SIGNALED_BIT,
});
- free_queue.push(&frame);
+ free_queue.push_back(&frame);
}
if (use_present_thread) {
@@ -164,7 +164,7 @@ Frame* PresentManager::GetRenderFrame() {
// Take the frame from the queue
Frame* frame = free_queue.front();
- free_queue.pop();
+ free_queue.pop_front();
// Wait for the presentation to be finished so all frame resources are free
frame->present_done.Wait();
@@ -174,18 +174,17 @@ Frame* PresentManager::GetRenderFrame() {
}
void PresentManager::Present(Frame* frame) {
- if (!use_present_thread) {
+ if (use_present_thread) {
+ scheduler.Record([this, frame](vk::CommandBuffer) {
+ std::unique_lock lock{queue_mutex};
+ present_queue.push_back(frame);
+ frame_cv.notify_one();
+ });
+ } else {
scheduler.WaitWorker();
CopyToSwapchain(frame);
- free_queue.push(frame);
- return;
+ free_queue.push_back(frame);
}
-
- scheduler.Record([this, frame](vk::CommandBuffer) {
- std::unique_lock lock{queue_mutex};
- present_queue.push(frame);
- frame_cv.notify_one();
- });
}
void PresentManager::RecreateFrame(Frame* frame, u32 width, u32 height, VkFormat image_view_format,
@@ -277,29 +276,25 @@ void PresentManager::PresentThread(std::stop_token token) {
Common::SetCurrentThreadName("VulkanPresent");
while (!token.stop_requested()) {
std::unique_lock lock{queue_mutex};
-
// Wait for presentation frames
frame_cv.wait(lock, token, [this] { return !present_queue.empty(); });
- if (token.stop_requested()) {
- return;
+ if (!token.stop_requested()) {
+ // Take the frame and notify anyone waiting
+ Frame* frame = present_queue.front();
+ present_queue.pop_front();
+ frame_cv.notify_one();
+
+ // By exchanging the lock ownership we take the swapchain lock
+ // before the queue lock goes out of scope. This way the swapchain
+ // lock in WaitPresent is guaranteed to occur after here.
+ std::exchange(lock, std::unique_lock{swapchain_mutex});
+ CopyToSwapchain(frame);
+
+ // Free the frame for reuse
+ std::scoped_lock fl{free_mutex};
+ free_queue.push_back(frame);
+ free_cv.notify_one();
}
-
- // Take the frame and notify anyone waiting
- Frame* frame = present_queue.front();
- present_queue.pop();
- frame_cv.notify_one();
-
- // By exchanging the lock ownership we take the swapchain lock
- // before the queue lock goes out of scope. This way the swapchain
- // lock in WaitPresent is guaranteed to occur after here.
- std::exchange(lock, std::unique_lock{swapchain_mutex});
-
- CopyToSwapchain(frame);
-
- // Free the frame for reuse
- std::scoped_lock fl{free_mutex};
- free_queue.push(frame);
- free_cv.notify_one();
}
}
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h
index 5820280602..aacc9b025a 100644
--- a/src/video_core/renderer_vulkan/vk_present_manager.h
+++ b/src/video_core/renderer_vulkan/vk_present_manager.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -5,7 +8,7 @@
#include <condition_variable>
#include <mutex>
-#include <queue>
+#include <boost/container/deque.hpp>
#include "common/common_types.h"
#include "common/polyfill_thread.h"
@@ -88,8 +91,8 @@ private:
#endif
vk::CommandPool cmdpool;
std::vector<Frame> frames;
- std::queue<Frame*> present_queue;
- std::queue<Frame*> free_queue;
+ boost::container::deque<Frame*> present_queue;
+ boost::container::deque<Frame*> free_queue;
std::condition_variable_any frame_cv;
std::condition_variable free_cv;
std::mutex swapchain_mutex;