mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-07 14:26:36 +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();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
blit_swapchain.DrawToFrame(device, rasterizer, frame, framebuffers,
|
blit_swapchain.DrawToFrame(device, rasterizer, frame, framebuffers,
|
||||||
render_window.GetFramebufferLayout(), swapchain.GetImageCount(),
|
render_window.GetFramebufferLayout(),
|
||||||
|
present_manager.SwapchainImageCount(),
|
||||||
swapchain.GetImageViewFormat());
|
swapchain.GetImageViewFormat());
|
||||||
|
|
||||||
#ifdef HAS_LSFG
|
#ifdef HAS_LSFG
|
||||||
void(frame_gen.WantedGenerations(present_manager.MaxExtraFrames()));
|
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();
|
const size_t generated_frames = frame_gen.GeneratedFrameCount();
|
||||||
for (size_t generation = 0; generation < generated_frames; ++generation) {
|
for (size_t generation = 0; generation < generated_frames; ++generation) {
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace Vulkan {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr size_t MAX_FRAMES_IN_FLIGHT = 7;
|
constexpr size_t MAX_FRAMES_IN_FLIGHT = 7;
|
||||||
|
constexpr u32 MAX_PRESENT_ATTEMPTS = 3;
|
||||||
#ifdef HAS_LSFG
|
#ifdef HAS_LSFG
|
||||||
static_assert(MAX_FRAMES_IN_FLIGHT <= LSFG_MAX_TARGETS);
|
static_assert(MAX_FRAMES_IN_FLIGHT <= LSFG_MAX_TARGETS);
|
||||||
#endif
|
#endif
|
||||||
@@ -372,12 +373,33 @@ void PresentManager::SetImageCount() {
|
|||||||
#else
|
#else
|
||||||
image_count = std::min<size_t>(swapchain.GetImageCount(), MAX_FRAMES_IN_FLIGHT);
|
image_count = std::min<size_t>(swapchain.GetImageCount(), MAX_FRAMES_IN_FLIGHT);
|
||||||
#endif
|
#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) {
|
void PresentManager::CopyToSwapchain(Frame* frame) {
|
||||||
bool requires_recreation = false;
|
bool requires_recreation = false;
|
||||||
|
|
||||||
while (true) {
|
for (u32 attempt = 0; attempt < MAX_PRESENT_ATTEMPTS; ++attempt) {
|
||||||
try {
|
try {
|
||||||
// Recreate surface and swapchain if needed.
|
// Recreate surface and swapchain if needed.
|
||||||
if (requires_recreation) {
|
if (requires_recreation) {
|
||||||
@@ -397,6 +419,8 @@ void PresentManager::CopyToSwapchain(Frame* frame) {
|
|||||||
requires_recreation = true;
|
requires_recreation = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiscardFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentManager::CopyToSwapchainImpl(Frame* frame) {
|
void PresentManager::CopyToSwapchainImpl(Frame* frame) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <boost/container/deque.hpp>
|
#include <boost/container/deque.hpp>
|
||||||
@@ -68,6 +69,9 @@ public:
|
|||||||
/// How many additional frames can be queued without stalling the render thread
|
/// How many additional frames can be queued without stalling the render thread
|
||||||
[[nodiscard]] size_t MaxExtraFrames() const;
|
[[nodiscard]] size_t MaxExtraFrames() const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::size_t SwapchainImageCount() const { return swapchain_image_count; }
|
||||||
|
[[nodiscard]] VkFormat SwapchainImageFormat() const { return swapchain_image_format; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PresentThread(std::stop_token token);
|
void PresentThread(std::stop_token token);
|
||||||
|
|
||||||
@@ -77,6 +81,8 @@ private:
|
|||||||
|
|
||||||
void RecreateSwapchain(Frame* frame);
|
void RecreateSwapchain(Frame* frame);
|
||||||
|
|
||||||
|
void DiscardFrame(Frame* frame);
|
||||||
|
|
||||||
void SetImageCount();
|
void SetImageCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -100,7 +106,9 @@ private:
|
|||||||
bool blit_supported;
|
bool blit_supported;
|
||||||
bool storage_supported;
|
bool storage_supported;
|
||||||
bool use_present_thread;
|
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
|
} // namespace Vulkan
|
||||||
|
|||||||
Reference in New Issue
Block a user