diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index 91830c65..cb8d152c 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace Vulkan; using namespace RDP; @@ -157,7 +158,7 @@ void ParallelRDP::DrawFullscreenTexturedQuad(Util::IntrusivePtr image, cmd->draw(3, 1); } -void ParallelRDP::UpdateScreen(Util::IntrusivePtr image, KaizenGui& kaizenGui) const { +void ParallelRDP::UpdateScreen(Util::IntrusivePtr image) const { wsi->begin_frame(); if (!image) { @@ -183,13 +184,15 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr image, KaizenGui& kaize cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); DrawFullscreenTexturedQuad(image, cmd); - kaizenGui.RenderUI(); + auto drawData = ImGui::GetDrawData(); + if(drawData) + ImGui_ImplVulkan_RenderDrawData(drawData, cmd->get_command_buffer()); cmd->end_render_pass(); wsi->get_device().submit(cmd); wsi->end_frame(); } -void ParallelRDP::UpdateScreen(const n64::VI &vi, KaizenGui& kaizenGui, bool playing) const { +void ParallelRDP::UpdateScreen(const n64::VI &vi, bool playing) const { if(playing) { command_processor->set_vi_register(VIRegister::Control, vi.status.raw); command_processor->set_vi_register(VIRegister::Origin, vi.origin); @@ -215,12 +218,12 @@ void ParallelRDP::UpdateScreen(const n64::VI &vi, KaizenGui& kaizenGui, bool pla opts.downscale_steps = true; opts.crop_overscan_pixels = true; Util::IntrusivePtr image = command_processor->scanout(opts); - UpdateScreen(image, kaizenGui); + UpdateScreen(image); command_processor->begin_frame_context(); return; } - UpdateScreen(static_cast>(nullptr), kaizenGui); + UpdateScreen(static_cast>(nullptr)); } void ParallelRDP::EnqueueCommand(int command_length, const u32 *buffer) const { diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index 238eba56..9ea8f064 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -7,8 +7,6 @@ namespace n64 { struct VI; } -class KaizenGui; - class ParallelRDP { public: class WindowInfo { @@ -25,7 +23,7 @@ public: const std::shared_ptr &, const u8 *); ParallelRDP() = default; - void UpdateScreen(const n64::VI &, KaizenGui&, bool = true) const; + void UpdateScreen(const n64::VI &, bool = true) const; void EnqueueCommand(int, const u32 *) const; void OnFullSync() const; bool IsFramerateUnlocked() const; @@ -38,5 +36,5 @@ public: private: void LoadWSIPlatform(const std::shared_ptr &, const std::shared_ptr &); void DrawFullscreenTexturedQuad(Util::IntrusivePtr, Util::IntrusivePtr) const; - void UpdateScreen(Util::IntrusivePtr, KaizenGui&) const; + void UpdateScreen(Util::IntrusivePtr) const; }; diff --git a/src/frontend/EmuThread.cpp b/src/frontend/EmuThread.cpp index 3461c33d..7375d0ec 100644 --- a/src/frontend/EmuThread.cpp +++ b/src/frontend/EmuThread.cpp @@ -3,10 +3,12 @@ #include EmuThread::EmuThread(const std::shared_ptr &core, double &fps, RenderWidget &renderWidget, - SettingsWindow &settings, KaizenGui& kaizenGui) noexcept : + SettingsWindow &settings) noexcept : renderWidget(renderWidget), core(core), settings(settings), fps(fps) { thread = std::thread([&]() { + core->parallel.Init(renderWidget.wsiPlatform, renderWidget.windowInfo, core->cpu->GetMem().GetRDRAMPtr()); + parallelRDPInitialized = true; isRunning = true; auto lastSample = std::chrono::high_resolution_clock::now(); @@ -18,26 +20,8 @@ EmuThread::EmuThread(const std::shared_ptr &core, double &fps, Render while (!interruptionRequested) { if(!started) { - const auto startFrameTime = std::chrono::high_resolution_clock::now(); - core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi, kaizenGui, false); - const auto endFrameTime = std::chrono::high_resolution_clock::now(); - using namespace std::chrono_literals; - const auto frameTimeMs = std::chrono::duration(endFrameTime - startFrameTime) / 1ms; - avgFps += frameTimeMs; - - sampledFps++; - - if (const auto elapsedSinceLastSample = std::chrono::duration(endFrameTime - lastSample) / 1s; - elapsedSinceLastSample >= 1.0) { - if (!oneSecondPassed) { - oneSecondPassed = true; - continue; - } - lastSample = endFrameTime; - avgFps /= sampledFps; - sampledFps = 0; - fps = 1000.0 / avgFps; - } + core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi, false); + fps = -1.0; continue; } @@ -50,7 +34,7 @@ EmuThread::EmuThread(const std::shared_ptr &core, double &fps, Render } if (core->render) { - core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi, kaizenGui); + core->parallel.UpdateScreen(core->cpu->GetMem().mmio.vi); } const auto endFrameTime = std::chrono::high_resolution_clock::now(); diff --git a/src/frontend/EmuThread.hpp b/src/frontend/EmuThread.hpp index 2f248292..84bdcd9c 100644 --- a/src/frontend/EmuThread.hpp +++ b/src/frontend/EmuThread.hpp @@ -8,13 +8,11 @@ namespace n64 { struct Core; } -class KaizenGui; - class EmuThread final { RenderWidget &renderWidget; bool started = false; public: - explicit EmuThread(const std::shared_ptr &, double &, RenderWidget &, SettingsWindow &, KaizenGui&) noexcept; + explicit EmuThread(const std::shared_ptr &, double &, RenderWidget &, SettingsWindow &) noexcept; void start() noexcept; void TogglePause() const noexcept; @@ -23,7 +21,7 @@ public: void Stop() const noexcept; void requestInterruption() { interruptionRequested = true; } - bool interruptionRequested = false, isRunning = false; + bool interruptionRequested = false, isRunning = false, parallelRDPInitialized = false; std::shared_ptr core; SettingsWindow &settings; double& fps; diff --git a/src/frontend/ImGuiImpl/GUI.hpp b/src/frontend/ImGuiImpl/GUI.hpp index bf93ccb6..6cdd77d3 100644 --- a/src/frontend/ImGuiImpl/GUI.hpp +++ b/src/frontend/ImGuiImpl/GUI.hpp @@ -6,8 +6,6 @@ #include #include -class KaizenGui; - namespace gui { static VkAllocationCallbacks* g_Allocator = NULL; static VkInstance g_Instance = VK_NULL_HANDLE; @@ -151,7 +149,5 @@ namespace gui { inline void EndFrame() { ImGui::Render(); - auto cmd = g_Wsi->get_device().request_command_buffer(); - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->get_command_buffer()); } } \ No newline at end of file diff --git a/src/frontend/KaizenGui.cpp b/src/frontend/KaizenGui.cpp index 1d2c4d96..9d511157 100644 --- a/src/frontend/KaizenGui.cpp +++ b/src/frontend/KaizenGui.cpp @@ -4,8 +4,8 @@ #include #include -KaizenGui::KaizenGui() noexcept : window("Kaizen", 1280, 720), core(std::make_shared()), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow, *this) { - core->parallel.Init(vulkanWidget.wsiPlatform, vulkanWidget.windowInfo, core->cpu->GetMem().GetRDRAMPtr()); +KaizenGui::KaizenGui() noexcept : window("Kaizen", 1280, 720), core(std::make_shared()), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow) { + while(!emuThread.parallelRDPInitialized); gui::Initialize(core->parallel.wsi, window.getHandle()); emuExitFunc = [&]() { @@ -27,7 +27,8 @@ KaizenGui::KaizenGui() noexcept : window("Kaizen", 1280, 720), core(std::make_sh }); statusBar.setFunc([&]() { - ImGui::Text("GUI FPS: %.2f, Emulation FPS: %.2f", ImGui::GetIO().Framerate, fpsCounter); + ImGui::Text("GUI FPS: %.2f, Emulation FPS: %s", ImGui::GetIO().Framerate, + fmt::format(fpsCounter > 0 ? fmt::runtime("{:.2f{0}}") : fmt::runtime("{1}"), fpsCounter, "Not playing").c_str()); }); menuBar.addMenu({"File", @@ -102,6 +103,8 @@ void KaizenGui::handleEvents() { int KaizenGui::run() { while(!quit) { handleEvents(); + + RenderUI(); } return 0; diff --git a/src/frontend/KaizenGui.hpp b/src/frontend/KaizenGui.hpp index f15dbb0f..b74b9523 100644 --- a/src/frontend/KaizenGui.hpp +++ b/src/frontend/KaizenGui.hpp @@ -20,7 +20,6 @@ public: EmuThread emuThread; gui::PopupWindow about{"About Kaizen"}; gui::StatusBar statusBar{}; - void RenderUI(); int run(); void LoadTAS(const std::string &path) const noexcept; @@ -29,4 +28,5 @@ private: bool quit = false; void handleEvents(); std::function emuExitFunc; + void RenderUI(); };