// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include "common/common_types.h" #include "common/polyfill_thread.h" #include "video_core/vulkan_common/vulkan_memory_allocator.h" #include "video_core/vulkan_common/vulkan_wrapper.h" namespace Core::Frontend { class EmuWindow; } // namespace Core::Frontend namespace Vulkan { class Device; class Scheduler; class Swapchain; struct Frame { u32 width; u32 height; bool is_srgb; vk::Image image; vk::ImageView image_view; vk::Framebuffer framebuffer; MemoryCommit image_commit; vk::CommandBuffer cmdbuf; vk::Semaphore render_ready; vk::Fence present_done; }; class PresentManager { public: PresentManager(const vk::Instance& instance, Core::Frontend::EmuWindow& render_window, const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler, Swapchain& swapchain, vk::SurfaceKHR& surface); ~PresentManager(); /// Returns the last used presentation frame Frame* GetRenderFrame(); /// Pushes a frame for presentation void Present(Frame* frame); /// Recreates the present frame to match the provided parameters void RecreateFrame(Frame* frame, u32 width, u32 height, bool is_srgb, VkFormat image_view_format, VkRenderPass rd); /// Waits for the present thread to finish presenting all queued frames. void WaitPresent(); /// This is called to notify the rendering backend of a surface change void NotifySurfaceChanged(); private: void PresentThread(std::stop_token token); void CopyToSwapchain(Frame* frame); private: const vk::Instance& instance; Core::Frontend::EmuWindow& render_window; const Device& device; MemoryAllocator& memory_allocator; Scheduler& scheduler; Swapchain& swapchain; vk::SurfaceKHR& surface; vk::CommandPool cmdpool; std::vector frames; std::queue present_queue; std::queue free_queue; std::condition_variable_any frame_cv; std::condition_variable free_cv; std::condition_variable recreate_surface_cv; std::mutex swapchain_mutex; std::mutex recreate_surface_mutex; std::mutex queue_mutex; std::mutex free_mutex; std::jthread present_thread; bool blit_supported; bool use_present_thread; std::size_t image_count{}; void* last_render_surface{}; }; } // namespace Vulkan