aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorPavelBARABANOV <pavelbarabanov94@gmail.com>2026-10-08 19:02:48 +0200
committercrueter <crueter@eden-emu.dev>2026-10-08 19:02:48 +0200
commit3cdd2ce141224079ce1dc8bfb4be7edc113aca02 (patch)
treef544b148018a5080ba809e33d5e9e01f9f113d8c /src/video_core/renderer_vulkan
parent10bcd2d849843b146a79c61a21df615e1bdcfcde (diff)
[android, renderer_vulkan] Сhange default settings (#4509)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions). - [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md) - [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability. ------------------- Airplane mode: On - needed to launch many games. Nvdec: CPU - fixes most issues in cutscenes. AudioEngine: Sdl3 (only Android) - "Auto" includes Cubeb on Android, but SDL3 works better. Async GPU: On - In most games, this provides a 30% boost in performance. Async presentation: On (Remove async presentation toggle from Android, It is no longer needed). Co-authored-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4509 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.cpp26
-rw-r--r--src/video_core/renderer_vulkan/vk_present_manager.h10
3 files changed, 38 insertions, 4 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 4fd4c0233b..27ca531186 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -217,13 +217,15 @@ void RendererVulkan::Composite(std::span<const Tegra::FramebufferConfig> framebu
scheduler.RequestOutsideRenderPassOperationContext();
blit_swapchain.DrawToFrame(device, rasterizer, frame, framebuffers,
- render_window.GetFramebufferLayout(), swapchain.GetImageCount(),
+ render_window.GetFramebufferLayout(),
+ present_manager.SwapchainImageCount(),
swapchain.GetImageViewFormat());
#ifdef HAS_LSFG
void(frame_gen.WantedGenerations(present_manager.MaxExtraFrames()));
- frame_gen.Process(device, frame, swapchain.GetImageFormat(), GuestExtent(framebuffers));
+ frame_gen.Process(device, frame, present_manager.SwapchainImageFormat(),
+ GuestExtent(framebuffers));
const size_t generated_frames = frame_gen.GeneratedFrameCount();
for (size_t generation = 0; generation < generated_frames; ++generation) {
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp
index d173a3ba5f..9298764546 100644
--- a/src/video_core/renderer_vulkan/vk_present_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp
@@ -23,6 +23,7 @@ namespace Vulkan {
namespace {
constexpr size_t MAX_FRAMES_IN_FLIGHT = 7;
+constexpr u32 MAX_PRESENT_ATTEMPTS = 3;
#ifdef HAS_LSFG
static_assert(MAX_FRAMES_IN_FLIGHT <= LSFG_MAX_TARGETS);
#endif
@@ -372,12 +373,33 @@ void PresentManager::SetImageCount() {
#else
image_count = std::min<size_t>(swapchain.GetImageCount(), MAX_FRAMES_IN_FLIGHT);
#endif
+ swapchain_image_count = swapchain.GetImageCount();
+ swapchain_image_format = swapchain.GetImageFormat();
+}
+
+void PresentManager::DiscardFrame(Frame* frame) {
+ static constexpr VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+ const VkSemaphore render_ready = *frame->render_ready;
+ const VkSubmitInfo submit_info{
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .waitSemaphoreCount = 1U,
+ .pWaitSemaphores = &render_ready,
+ .pWaitDstStageMask = &wait_stage,
+ .commandBufferCount = 0U,
+ .pCommandBuffers = nullptr,
+ .signalSemaphoreCount = 0U,
+ .pSignalSemaphores = nullptr,
+ };
+
+ std::scoped_lock submit_lock{scheduler.submit_mutex};
+ void(device.GetGraphicsQueue().Submit(submit_info, *frame->present_done));
}
void PresentManager::CopyToSwapchain(Frame* frame) {
bool requires_recreation = false;
- while (true) {
+ for (u32 attempt = 0; attempt < MAX_PRESENT_ATTEMPTS; ++attempt) {
try {
// Recreate surface and swapchain if needed.
if (requires_recreation) {
@@ -397,6 +419,8 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
requires_recreation = true;
}
}
+
+ DiscardFrame(frame);
}
void PresentManager::CopyToSwapchainImpl(Frame* frame) {
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h
index 4741c55e61..ab2b76f10f 100644
--- a/src/video_core/renderer_vulkan/vk_present_manager.h
+++ b/src/video_core/renderer_vulkan/vk_present_manager.h
@@ -6,6 +6,7 @@
#pragma once
+#include <atomic>
#include <condition_variable>
#include <mutex>
#include <boost/container/deque.hpp>
@@ -68,6 +69,9 @@ public:
/// How many additional frames can be queued without stalling the render thread
[[nodiscard]] size_t MaxExtraFrames() const;
+ [[nodiscard]] std::size_t SwapchainImageCount() const { return swapchain_image_count; }
+ [[nodiscard]] VkFormat SwapchainImageFormat() const { return swapchain_image_format; }
+
private:
void PresentThread(std::stop_token token);
@@ -77,6 +81,8 @@ private:
void RecreateSwapchain(Frame* frame);
+ void DiscardFrame(Frame* frame);
+
void SetImageCount();
private:
@@ -100,7 +106,9 @@ private:
bool blit_supported;
bool storage_supported;
bool use_present_thread;
- std::size_t image_count{};
+ std::atomic<std::size_t> image_count{};
+ std::atomic<std::size_t> swapchain_image_count{};
+ std::atomic<VkFormat> swapchain_image_format{};
};
} // namespace Vulkan