diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 53c4e6a1c..df3e5411a 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -183,8 +183,8 @@ if (ENABLE_VULKAN) renderer_vulkan/vk_platform.h renderer_vulkan/vk_present_window.cpp renderer_vulkan/vk_present_window.h - renderer_vulkan/vk_renderpass_cache.cpp - renderer_vulkan/vk_renderpass_cache.h + renderer_vulkan/vk_render_manager.cpp + renderer_vulkan/vk_render_manager.h renderer_vulkan/vk_shader_util.cpp renderer_vulkan/vk_shader_util.h renderer_vulkan/vk_stream_buffer.cpp diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 98f8b23f2..2241c45fe 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -54,8 +54,7 @@ RendererVulkan::RendererVulkan(Core::System& system, Pica::PicaCore& pica_, Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window) : RendererBase{system, window, secondary_window}, memory{system.Memory()}, pica{pica_}, instance{window, Settings::values.physical_device.GetValue()}, scheduler{instance}, - renderpass_cache{instance, scheduler}, pool{instance}, main_window{window, instance, - scheduler}, + render_manager{instance, scheduler}, pool{instance}, main_window{window, instance, scheduler}, vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer, VERTEX_BUFFER_SIZE}, rasterizer{memory, @@ -66,7 +65,7 @@ RendererVulkan::RendererVulkan(Core::System& system, Pica::PicaCore& pica_, instance, scheduler, pool, - renderpass_cache, + render_manager, main_window.ImageCount()}, present_set_provider{instance, pool, PRESENT_BINDINGS} { CompileShaders(); @@ -135,7 +134,7 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& const auto descriptor_set = present_set_provider.Acquire(present_textures); - renderpass_cache.EndRendering(); + render_manager.EndRendering(); scheduler.Record([this, layout, frame, descriptor_set, renderpass = main_window.Renderpass(), index = current_pipeline](vk::CommandBuffer cmdbuf) { const vk::Viewport viewport = { @@ -470,7 +469,7 @@ void RendererVulkan::FillScreen(Common::Vec3 color, const TextureInfo& textu }, }; - renderpass_cache.EndRendering(); + render_manager.EndRendering(); scheduler.Record([image = texture.image, clear_color](vk::CommandBuffer cmdbuf) { const vk::ImageSubresourceRange range = { .aspectMask = vk::ImageAspectFlagBits::eColor, diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index f50db92bb..cb3bd2227 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -11,7 +11,7 @@ #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_present_window.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" namespace Core { @@ -118,7 +118,7 @@ private: Instance instance; Scheduler scheduler; - RenderpassCache renderpass_cache; + RenderManager render_manager; DescriptorPool pool; PresentWindow main_window; StreamBuffer vertex_buffer; diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.cpp b/src/video_core/renderer_vulkan/vk_blit_helper.cpp index 3f50cb044..651d38437 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_helper.cpp @@ -5,7 +5,7 @@ #include "common/vector_math.h" #include "video_core/renderer_vulkan/vk_blit_helper.h" #include "video_core/renderer_vulkan/vk_instance.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" @@ -178,8 +178,8 @@ constexpr vk::PipelineShaderStageCreateInfo MakeStages(vk::ShaderModule compute_ } // Anonymous namespace BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_, DescriptorPool& pool, - RenderpassCache& renderpass_cache_) - : instance{instance_}, scheduler{scheduler_}, renderpass_cache{renderpass_cache_}, + RenderManager& render_manager_) + : instance{instance_}, scheduler{scheduler_}, render_manager{render_manager_}, device{instance.GetDevice()}, compute_provider{instance, pool, COMPUTE_BINDINGS}, compute_buffer_provider{instance, pool, COMPUTE_BUFFER_BINDINGS}, two_textures_provider{instance, pool, TWO_TEXTURES_BINDINGS}, @@ -303,10 +303,10 @@ bool BlitHelper::BlitDepthStencil(Surface& source, Surface& dest, const RenderPass depth_pass = { .framebuffer = dest.Framebuffer(), .render_pass = - renderpass_cache.GetRenderpass(PixelFormat::Invalid, dest.pixel_format, false), + render_manager.GetRenderpass(PixelFormat::Invalid, dest.pixel_format, false), .render_area = dst_render_area, }; - renderpass_cache.BeginRendering(depth_pass); + render_manager.BeginRendering(depth_pass); scheduler.Record([blit, descriptor_set, this](vk::CommandBuffer cmdbuf) { const vk::PipelineLayout layout = two_textures_pipeline_layout; @@ -338,7 +338,7 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest, const auto descriptor_set = compute_provider.Acquire(textures); - renderpass_cache.EndRendering(); + render_manager.EndRendering(); scheduler.Record([this, descriptor_set, copy, src_image = source.Image(), dst_image = dest.Image()](vk::CommandBuffer cmdbuf) { const std::array pre_barriers = { @@ -461,7 +461,7 @@ bool BlitHelper::DepthToBuffer(Surface& source, vk::Buffer buffer, const auto descriptor_set = compute_buffer_provider.Acquire(textures); - renderpass_cache.EndRendering(); + render_manager.EndRendering(); scheduler.Record([this, descriptor_set, copy, src_image = source.Image(), extent = source.RealExtent(false)](vk::CommandBuffer cmdbuf) { const vk::ImageMemoryBarrier pre_barrier = { @@ -547,7 +547,7 @@ vk::Pipeline BlitHelper::MakeDepthStencilBlitPipeline() { } const std::array stages = MakeStages(full_screen_vert, blit_depth_stencil_frag); - const auto renderpass = renderpass_cache.GetRenderpass(VideoCore::PixelFormat::Invalid, + const auto renderpass = render_manager.GetRenderpass(VideoCore::PixelFormat::Invalid, VideoCore::PixelFormat::D24S8, false); vk::GraphicsPipelineCreateInfo depth_stencil_info = { .stageCount = static_cast(stages.size()), diff --git a/src/video_core/renderer_vulkan/vk_blit_helper.h b/src/video_core/renderer_vulkan/vk_blit_helper.h index 8060a225b..c8d2751ed 100644 --- a/src/video_core/renderer_vulkan/vk_blit_helper.h +++ b/src/video_core/renderer_vulkan/vk_blit_helper.h @@ -15,7 +15,7 @@ struct BufferTextureCopy; namespace Vulkan { class Instance; -class RenderpassCache; +class RenderManager; class Scheduler; class Surface; @@ -24,7 +24,7 @@ class BlitHelper { public: BlitHelper(const Instance& instance, Scheduler& scheduler, DescriptorPool& pool, - RenderpassCache& renderpass_cache); + RenderManager& render_manager); ~BlitHelper(); bool BlitDepthStencil(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit); @@ -41,7 +41,7 @@ private: private: const Instance& instance; Scheduler& scheduler; - RenderpassCache& renderpass_cache; + RenderManager& render_manager; vk::Device device; vk::RenderPass r32_renderpass; diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index 5ef3eb513..12d000bf0 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -9,7 +9,7 @@ #include "video_core/renderer_vulkan/pica_to_vk.h" #include "video_core/renderer_vulkan/vk_graphics_pipeline.h" #include "video_core/renderer_vulkan/vk_instance.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_shader_util.h" namespace Vulkan { @@ -64,11 +64,11 @@ Shader::~Shader() { } } -GraphicsPipeline::GraphicsPipeline(const Instance& instance_, RenderpassCache& renderpass_cache_, +GraphicsPipeline::GraphicsPipeline(const Instance& instance_, RenderManager& render_manager_, const PipelineInfo& info_, vk::PipelineCache pipeline_cache_, vk::PipelineLayout layout_, std::array stages_, Common::ThreadWorker* worker_) - : instance{instance_}, renderpass_cache{renderpass_cache_}, worker{worker_}, + : instance{instance_}, render_manager{render_manager_}, worker{worker_}, pipeline_layout{layout_}, pipeline_cache{pipeline_cache_}, info{info_}, stages{stages_} {} GraphicsPipeline::~GraphicsPipeline() = default; @@ -265,7 +265,7 @@ bool GraphicsPipeline::Build(bool fail_on_compile_required) { .pDynamicState = &dynamic_info, .layout = pipeline_layout, .renderPass = - renderpass_cache.GetRenderpass(info.attachments.color, info.attachments.depth, false), + render_manager.GetRenderpass(info.attachments.color, info.attachments.depth, false), }; if (fail_on_compile_required) { diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 93a4ebd48..c0df5d681 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -40,7 +40,7 @@ private: namespace Vulkan { class Instance; -class RenderpassCache; +class RenderManager; constexpr u32 MAX_SHADER_STAGES = 3; constexpr u32 MAX_VERTEX_ATTRIBUTES = 16; @@ -165,7 +165,7 @@ struct Shader : public Common::AsyncHandle { class GraphicsPipeline : public Common::AsyncHandle { public: - explicit GraphicsPipeline(const Instance& instance, RenderpassCache& renderpass_cache, + explicit GraphicsPipeline(const Instance& instance, RenderManager& render_manager, const PipelineInfo& info, vk::PipelineCache pipeline_cache, vk::PipelineLayout layout, std::array stages, Common::ThreadWorker* worker); @@ -181,7 +181,7 @@ public: private: const Instance& instance; - RenderpassCache& renderpass_cache; + RenderManager& render_manager; Common::ThreadWorker* worker; vk::UniquePipeline pipeline; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 05468777e..c10e74949 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -13,7 +13,7 @@ #include "video_core/renderer_vulkan/pica_to_vk.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_shader_util.h" #include "video_core/shader/generator/glsl_fs_shader_gen.h" @@ -80,9 +80,9 @@ constexpr std::array SHADOW_BINDINGS = {{ }}; PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, - RenderpassCache& renderpass_cache_, DescriptorPool& pool_) - : instance{instance_}, scheduler{scheduler_}, renderpass_cache{renderpass_cache_}, pool{pool_}, - num_worker_threads{std::max(std::thread::hardware_concurrency() >> 1, 2U)}, + RenderManager& render_manager_, DescriptorPool& pool_) + : instance{instance_}, scheduler{scheduler_}, render_manager{render_manager_}, pool{pool_}, + num_worker_threads{std::max(std::thread::hardware_concurrency(), 2U)}, workers{num_worker_threads, "Pipeline workers"}, descriptor_set_providers{DescriptorSetProvider{instance, pool, BUFFER_BINDINGS}, DescriptorSetProvider{instance, pool, TEXTURE_BINDINGS}, @@ -205,7 +205,7 @@ bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) { auto [it, new_pipeline] = graphics_pipelines.try_emplace(pipeline_hash); if (new_pipeline) { it.value() = - std::make_unique(instance, renderpass_cache, info, *pipeline_cache, + std::make_unique(instance, render_manager, info, *pipeline_cache, *pipeline_layout, current_shaders, &workers); } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 2c57d2d52..f4f6e163d 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -22,7 +22,7 @@ namespace Vulkan { class Instance; class Scheduler; -class RenderpassCache; +class RenderManager; class DescriptorPool; constexpr u32 NUM_RASTERIZER_SETS = 3; @@ -34,7 +34,7 @@ constexpr u32 NUM_DYNAMIC_OFFSETS = 3; class PipelineCache { public: explicit PipelineCache(const Instance& instance, Scheduler& scheduler, - RenderpassCache& renderpass_cache, DescriptorPool& pool); + RenderManager& render_manager, DescriptorPool& pool); ~PipelineCache(); [[nodiscard]] DescriptorSetProvider& TextureProvider() noexcept { @@ -97,7 +97,7 @@ private: private: const Instance& instance; Scheduler& scheduler; - RenderpassCache& renderpass_cache; + RenderManager& render_manager; DescriptorPool& pool; Pica::Shader::Profile profile{}; diff --git a/src/video_core/renderer_vulkan/vk_present_window.h b/src/video_core/renderer_vulkan/vk_present_window.h index f5e9844e7..1e4b1e12a 100644 --- a/src/video_core/renderer_vulkan/vk_present_window.h +++ b/src/video_core/renderer_vulkan/vk_present_window.h @@ -20,7 +20,7 @@ namespace Vulkan { class Instance; class Swapchain; class Scheduler; -class RenderpassCache; +class RenderManager; struct Frame { u32 width; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 0208c8cde..95d33e222 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -59,11 +59,11 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore& VideoCore::RendererBase& renderer, Frontend::EmuWindow& emu_window, const Instance& instance, Scheduler& scheduler, DescriptorPool& pool, - RenderpassCache& renderpass_cache, u32 image_count) + RenderManager& render_manager, u32 image_count) : RasterizerAccelerated{memory, pica}, instance{instance}, scheduler{scheduler}, - renderpass_cache{renderpass_cache}, pipeline_cache{instance, scheduler, renderpass_cache, + render_manager{render_manager}, pipeline_cache{instance, scheduler, render_manager, pool}, - runtime{instance, scheduler, renderpass_cache, pool, pipeline_cache.TextureProvider(), + runtime{instance, scheduler, render_manager, pool, pipeline_cache.TextureProvider(), image_count}, res_cache{memory, custom_tex_manager, runtime, regs, renderer}, stream_buffer{instance, scheduler, BUFFER_USAGE, STREAM_BUFFER_SIZE}, @@ -77,6 +77,7 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore& vertex_buffers.fill(stream_buffer.Handle()); + // Query uniform buffer alignment. uniform_buffer_alignment = instance.UniformMinAlignment(); uniform_size_aligned_vs_pica = Common::AlignUp(sizeof(VSPicaUniformData), uniform_buffer_alignment); @@ -107,6 +108,10 @@ RasterizerVulkan::RasterizerVulkan(Memory::MemorySystem& memory, Pica::PicaCore& .range = VK_WHOLE_SIZE, }); + scheduler.RegisterOnSubmit([&render_manager] { + render_manager.EndRendering(); + }); + // Since we don't have access to VK_EXT_descriptor_indexing we need to intiallize // all descriptor sets even the ones we don't use. pipeline_cache.BindBuffer(0, uniform_buffer.Handle(), 0, sizeof(VSPicaUniformData)); @@ -514,7 +519,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { // Begin rendering const auto draw_rect = fb_helper.DrawRect(); - renderpass_cache.BeginRendering(framebuffer, draw_rect); + render_manager.BeginRendering(framebuffer, draw_rect); // Configure viewport and scissor const auto viewport = fb_helper.Viewport(); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 5cd795ecf..7fb4780ec 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -6,7 +6,7 @@ #include "video_core/rasterizer_accelerated.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" @@ -31,7 +31,7 @@ struct ScreenInfo; class Instance; class Scheduler; -class RenderpassCache; +class RenderManager; class DescriptorPool; class RasterizerVulkan : public VideoCore::RasterizerAccelerated { @@ -40,7 +40,7 @@ public: VideoCore::CustomTexManager& custom_tex_manager, VideoCore::RendererBase& renderer, Frontend::EmuWindow& emu_window, const Instance& instance, Scheduler& scheduler, DescriptorPool& pool, - RenderpassCache& renderpass_cache, u32 image_count); + RenderManager& render_manager, u32 image_count); ~RasterizerVulkan() override; void TickFrame(); @@ -145,7 +145,7 @@ private: private: const Instance& instance; Scheduler& scheduler; - RenderpassCache& renderpass_cache; + RenderManager& render_manager; PipelineCache pipeline_cache; TextureRuntime runtime; RasterizerCache res_cache; diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp b/src/video_core/renderer_vulkan/vk_render_manager.cpp similarity index 93% rename from src/video_core/renderer_vulkan/vk_renderpass_cache.cpp rename to src/video_core/renderer_vulkan/vk_render_manager.cpp index f9fc22bc5..238bf0dc1 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_render_manager.cpp @@ -6,7 +6,7 @@ #include "common/assert.h" #include "video_core/rasterizer_cache/pixel_format.h" #include "video_core/renderer_vulkan/vk_instance.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" @@ -17,12 +17,12 @@ constexpr u32 MIN_DRAWS_TO_FLUSH = 20; using VideoCore::PixelFormat; using VideoCore::SurfaceType; -RenderpassCache::RenderpassCache(const Instance& instance, Scheduler& scheduler) +RenderManager::RenderManager(const Instance& instance, Scheduler& scheduler) : instance{instance}, scheduler{scheduler} {} -RenderpassCache::~RenderpassCache() = default; +RenderManager::~RenderManager() = default; -void RenderpassCache::BeginRendering(const Framebuffer* framebuffer, +void RenderManager::BeginRendering(const Framebuffer* framebuffer, Common::Rectangle draw_rect) { const vk::Rect2D render_area = { .offset{ @@ -46,7 +46,7 @@ void RenderpassCache::BeginRendering(const Framebuffer* framebuffer, BeginRendering(new_pass); } -void RenderpassCache::BeginRendering(const RenderPass& new_pass) { +void RenderManager::BeginRendering(const RenderPass& new_pass) { if (pass == new_pass) [[likely]] { num_draws++; return; @@ -67,12 +67,11 @@ void RenderpassCache::BeginRendering(const RenderPass& new_pass) { pass = new_pass; } -void RenderpassCache::EndRendering() { +void RenderManager::EndRendering() { if (!pass.render_pass) { return; } - pass.render_pass = vk::RenderPass{}; scheduler.Record([images = images, aspects = aspects](vk::CommandBuffer cmdbuf) { u32 num_barriers = 0; vk::PipelineStageFlags pipeline_flags{}; @@ -115,6 +114,11 @@ void RenderpassCache::EndRendering() { num_barriers, barriers.data()); }); + // Reset state. + pass.render_pass = vk::RenderPass{}; + images = {}; + aspects = {}; + // The Mali guide recommends flushing at the end of each major renderpass // Testing has shown this has a significant effect on rendering performance if (num_draws > MIN_DRAWS_TO_FLUSH && instance.ShouldFlush()) { @@ -123,7 +127,7 @@ void RenderpassCache::EndRendering() { } } -vk::RenderPass RenderpassCache::GetRenderpass(VideoCore::PixelFormat color, +vk::RenderPass RenderManager::GetRenderpass(VideoCore::PixelFormat color, VideoCore::PixelFormat depth, bool is_clear) { std::scoped_lock lock{cache_mutex}; @@ -148,7 +152,7 @@ vk::RenderPass RenderpassCache::GetRenderpass(VideoCore::PixelFormat color, return *renderpass; } -vk::UniqueRenderPass RenderpassCache::CreateRenderPass(vk::Format color, vk::Format depth, +vk::UniqueRenderPass RenderManager::CreateRenderPass(vk::Format color, vk::Format depth, vk::AttachmentLoadOp load_op) const { u32 attachment_count = 0; std::array attachments; diff --git a/src/video_core/renderer_vulkan/vk_renderpass_cache.h b/src/video_core/renderer_vulkan/vk_render_manager.h similarity index 81% rename from src/video_core/renderer_vulkan/vk_renderpass_cache.h rename to src/video_core/renderer_vulkan/vk_render_manager.h index 3763d9898..64e71b580 100644 --- a/src/video_core/renderer_vulkan/vk_renderpass_cache.h +++ b/src/video_core/renderer_vulkan/vk_render_manager.h @@ -24,23 +24,20 @@ struct RenderPass { vk::RenderPass render_pass; vk::Rect2D render_area; vk::ClearValue clear; - bool do_clear; + u32 do_clear; bool operator==(const RenderPass& other) const noexcept { - return std::tie(framebuffer, render_pass, render_area, do_clear) == - std::tie(other.framebuffer, other.render_pass, other.render_area, - other.do_clear) && - std::memcmp(&clear, &other.clear, sizeof(vk::ClearValue)) == 0; + return std::memcmp(this, &other, sizeof(RenderPass)) == 0; } }; -class RenderpassCache { +class RenderManager { static constexpr std::size_t MAX_COLOR_FORMATS = 13; static constexpr std::size_t MAX_DEPTH_FORMATS = 4; public: - explicit RenderpassCache(const Instance& instance, Scheduler& scheduler); - ~RenderpassCache(); + explicit RenderManager(const Instance& instance, Scheduler& scheduler); + ~RenderManager(); /// Begins a new renderpass with the provided framebuffer as render target. void BeginRendering(const Framebuffer* framebuffer, Common::Rectangle draw_rect); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 315fe0ea7..e6285d6cd 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -8,7 +8,7 @@ #include "common/settings.h" #include "common/thread.h" #include "video_core/renderer_vulkan/vk_instance.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" MICROPROFILE_DEFINE(Vulkan_WaitForWorker, "Vulkan", "Wait for worker", MP_RGB(255, 192, 192)); @@ -98,6 +98,8 @@ void Scheduler::DispatchWork() { return; } + //on_dispatch(); + { std::scoped_lock ql{queue_mutex}; work_queue.push(std::move(chunk)); @@ -173,6 +175,8 @@ void Scheduler::SubmitExecution(vk::Semaphore signal_semaphore, vk::Semaphore wa state = StateFlags::AllDirty; const u64 signal_value = master_semaphore->NextTick(); + on_submit(); + Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) { MICROPROFILE_SCOPE(Vulkan_Submit); std::scoped_lock lock{submit_mutex}; diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 82a14addd..20d55a4b9 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -6,6 +6,7 @@ #include #include +#include #include "common/alignment.h" #include "common/common_funcs.h" #include "common/polyfill_thread.h" @@ -49,11 +50,6 @@ public: /// Records the command to the current chunk. template void Record(T&& command) { - if (!use_worker_thread) { - command(current_cmdbuf); - return; - } - if (chunk->Record(command)) { return; } @@ -76,6 +72,16 @@ public: return False(state & flag); } + /// Registers a callback to perform on queue submission. + void RegisterOnSubmit(std::function&& func) { + on_submit = std::move(func); + } + + /// Registers a callback to perform on queue submission. + void RegisterOnDispatch(std::function&& func) { + on_dispatch = std::move(func); + } + /// Returns the current command buffer tick. [[nodiscard]] u64 CurrentTick() const noexcept { return master_semaphore->CurrentTick(); @@ -194,6 +200,8 @@ private: std::vector> chunk_reserve; vk::CommandBuffer current_cmdbuf; StateFlags state{}; + std::function on_submit; + std::function on_dispatch; std::mutex execution_mutex; std::mutex reserve_mutex; std::mutex queue_mutex; diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index deb34a121..4cc819e02 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -14,7 +14,7 @@ #include "video_core/renderer_vulkan/pica_to_vk.h" #include "video_core/renderer_vulkan/vk_descriptor_pool.h" #include "video_core/renderer_vulkan/vk_instance.h" -#include "video_core/renderer_vulkan/vk_renderpass_cache.h" +#include "video_core/renderer_vulkan/vk_render_manager.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" @@ -249,10 +249,10 @@ constexpr u64 DOWNLOAD_BUFFER_SIZE = 16_MiB; } // Anonymous namespace TextureRuntime::TextureRuntime(const Instance& instance, Scheduler& scheduler, - RenderpassCache& renderpass_cache, DescriptorPool& pool, + RenderManager& render_manager, DescriptorPool& pool, DescriptorSetProvider& texture_provider_, u32 num_swapchain_images_) - : instance{instance}, scheduler{scheduler}, renderpass_cache{renderpass_cache}, - texture_provider{texture_provider_}, blit_helper{instance, scheduler, pool, renderpass_cache}, + : instance{instance}, scheduler{scheduler}, render_manager{render_manager}, + texture_provider{texture_provider_}, blit_helper{instance, scheduler, pool, render_manager}, upload_buffer{instance, scheduler, vk::BufferUsageFlagBits::eTransferSrc, UPLOAD_BUFFER_SIZE, BufferType::Upload}, download_buffer{instance, scheduler, @@ -305,7 +305,7 @@ bool TextureRuntime::Reinterpret(Surface& source, Surface& dest, } bool TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClear& clear) { - renderpass_cache.EndRendering(); + render_manager.EndRendering(); const RecordParams params = { .aspect = surface.Aspect(), @@ -377,7 +377,7 @@ void TextureRuntime::ClearTextureWithRenderpass(Surface& surface, const auto color_format = is_color ? surface.pixel_format : PixelFormat::Invalid; const auto depth_format = is_color ? PixelFormat::Invalid : surface.pixel_format; - const auto render_pass = renderpass_cache.GetRenderpass(color_format, depth_format, true); + const auto render_pass = render_manager.GetRenderpass(color_format, depth_format, true); const RecordParams params = { .aspect = surface.Aspect(), @@ -454,7 +454,7 @@ void TextureRuntime::ClearTextureWithRenderpass(Surface& surface, bool TextureRuntime::CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy) { - renderpass_cache.EndRendering(); + render_manager.EndRendering(); const RecordParams params = { .aspect = source.Aspect(), @@ -559,7 +559,7 @@ bool TextureRuntime::BlitTextures(Surface& source, Surface& dest, return blit_helper.BlitDepthStencil(source, dest, blit); } - renderpass_cache.EndRendering(); + render_manager.EndRendering(); const RecordParams params = { .aspect = source.Aspect(), @@ -667,7 +667,7 @@ void TextureRuntime::GenerateMipmaps(Surface& surface) { return; } - renderpass_cache.EndRendering(); + render_manager.EndRendering(); auto [width, height] = surface.RealExtent(); const u32 levels = surface.levels; @@ -737,9 +737,9 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceParams& param raw_images.emplace_back(handles[1].image); } - runtime->renderpass_cache.EndRendering(); - scheduler->Record([raw_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { - const auto barriers = MakeInitBarriers(aspect, raw_images); + runtime->render_manager.EndRendering(); + scheduler->Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { + const auto barriers = MakeInitBarriers(aspect, raw_images, num_images); cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe, vk::DependencyFlagBits::eByRegion, {}, {}, barriers); @@ -781,9 +781,9 @@ Surface::Surface(TextureRuntime& runtime_, const VideoCore::SurfaceBase& surface raw_images.emplace_back(handles[2].image); } - runtime->renderpass_cache.EndRendering(); - scheduler->Record([raw_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { - const auto barriers = MakeInitBarriers(aspect, raw_images); + runtime->render_manager.EndRendering(); + scheduler->Record([raw_images, num_images, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { + const auto barriers = MakeInitBarriers(aspect, raw_images, num_images); cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe, vk::DependencyFlagBits::eByRegion, {}, {}, barriers); @@ -812,7 +812,7 @@ Surface::~Surface() { void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const VideoCore::StagingData& staging) { - runtime->renderpass_cache.EndRendering(); + runtime->render_manager.EndRendering(); const RecordParams params = { .aspect = Aspect(), @@ -980,7 +980,7 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, runtime->download_buffer.Commit(staging.size); }); - runtime->renderpass_cache.EndRendering(); + runtime->render_manager.EndRendering(); if (pixel_format == PixelFormat::D24S8) { runtime->blit_helper.DepthToBuffer(*this, runtime->download_buffer.Handle(), download); @@ -1080,7 +1080,7 @@ void Surface::ScaleUp(u32 new_scale) { MakeHandle(instance, GetScaledWidth(), GetScaledHeight(), levels, texture_type, traits.native, traits.usage, flags, traits.aspect, false, DebugName(true)); - runtime->renderpass_cache.EndRendering(); + runtime->render_manager.EndRendering(); scheduler->Record( [raw_images = std::array{Image()}, aspect = traits.aspect](vk::CommandBuffer cmdbuf) { const auto barriers = MakeInitBarriers(aspect, raw_images); @@ -1158,7 +1158,7 @@ vk::ImageView Surface::CopyImageView() noexcept { copy_layout = vk::ImageLayout::eUndefined; } - runtime->renderpass_cache.EndRendering(); + runtime->render_manager.EndRendering(); const RecordParams params = { .aspect = Aspect(), @@ -1346,7 +1346,7 @@ vk::Framebuffer Surface::Framebuffer() noexcept { const auto color_format = is_depth ? PixelFormat::Invalid : pixel_format; const auto depth_format = is_depth ? pixel_format : PixelFormat::Invalid; const auto render_pass = - runtime->renderpass_cache.GetRenderpass(color_format, depth_format, false); + runtime->render_manager.GetRenderpass(color_format, depth_format, false); const auto attachments = std::array{ImageView()}; framebuffers[index] = MakeFramebuffer(instance->GetDevice(), render_pass, GetScaledWidth(), GetScaledHeight(), attachments); @@ -1460,7 +1460,7 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa Surface* color, Surface* depth) : VideoCore::FramebufferParams{params}, res_scale{color ? color->res_scale : (depth ? depth->res_scale : 1u)} { - auto& renderpass_cache = runtime.GetRenderpassCache(); + auto& render_manager = runtime.GetRenderpassCache(); if (shadow_rendering && !color) { return; } @@ -1494,12 +1494,13 @@ Framebuffer::Framebuffer(TextureRuntime& runtime, const VideoCore::FramebufferPa const vk::Device device = runtime.GetInstance().GetDevice(); if (shadow_rendering) { render_pass = - renderpass_cache.GetRenderpass(PixelFormat::Invalid, PixelFormat::Invalid, false); + render_manager.GetRenderpass(PixelFormat::Invalid, PixelFormat::Invalid, false); framebuffer = MakeFramebuffer(device, render_pass, color->GetScaledWidth(), color->GetScaledHeight(), {}); } else { - render_pass = renderpass_cache.GetRenderpass(formats[0], formats[1], false); - framebuffer = MakeFramebuffer(device, render_pass, width, height, attachments); + render_pass = render_manager.GetRenderpass(formats[0], formats[1], false); + framebuffer = + MakeFramebuffer(device, render_pass, width, height, attachments, num_attachments); } } diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.h b/src/video_core/renderer_vulkan/vk_texture_runtime.h index 2bef63dab..fa7c188ab 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.h +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.h @@ -22,7 +22,7 @@ struct Material; namespace Vulkan { class Instance; -class RenderpassCache; +class RenderManager; class DescriptorPool; class DescriptorSetProvider; class Surface; @@ -42,7 +42,7 @@ class TextureRuntime { public: explicit TextureRuntime(const Instance& instance, Scheduler& scheduler, - RenderpassCache& renderpass_cache, DescriptorPool& pool, + RenderManager& render_manager, DescriptorPool& pool, DescriptorSetProvider& texture_provider, u32 num_swapchain_images); ~TextureRuntime(); @@ -54,8 +54,8 @@ public: return scheduler; } - RenderpassCache& GetRenderpassCache() { - return renderpass_cache; + RenderManager& GetRenderpassCache() { + return render_manager; } /// Returns the removal threshold ticks for the garbage collector @@ -95,7 +95,7 @@ private: private: const Instance& instance; Scheduler& scheduler; - RenderpassCache& renderpass_cache; + RenderManager& render_manager; DescriptorSetProvider& texture_provider; BlitHelper blit_helper; StreamBuffer upload_buffer;