mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-06 22:10:49 +00:00
Correcting some bugs on the vulkan async presentation thread
This commit is contained in:
committed by
PavelBARABANOV
parent
10bcd2d849
commit
a873fde17f
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user