diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index 3158779d..b65c8f50 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -23,14 +23,6 @@ void ParallelRDP::SetFramerateUnlocked(bool unlocked) const { Program *fullscreen_quad_program; -static void check_vk_result(VkResult err) { - if (err == 0) - return; - fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); - if (err < 0) - abort(); -} - void ParallelRDP::LoadWSIPlatform(const std::shared_ptr &instanceFactory, const std::shared_ptr &wsi_platform, const std::shared_ptr &newWindowInfo) { @@ -44,51 +36,6 @@ void ParallelRDP::LoadWSIPlatform(const std::shared_ptr &instan } windowInfo = newWindowInfo; - - auto instance = wsi->get_context().get_instance(); - - volkInitialize(); - volkLoadInstance(instance); - - ImGui_ImplVulkan_LoadFunctions( - [](const char *function_name, void *instance) { - return vkGetInstanceProcAddr(static_cast(instance), function_name); - }, - instance); - - ImGui_ImplVulkan_InitInfo init_info = {}; - init_info.Instance = instance; - init_info.PhysicalDevice = wsi->get_device().get_physical_device(); - init_info.Device = wsi->get_device().get_device(); - init_info.QueueFamily = wsi->get_context().get_queue_info().family_indices[QUEUE_INDEX_GRAPHICS]; - init_info.Queue = wsi->get_context().get_queue_info().queues[QUEUE_INDEX_GRAPHICS]; - init_info.PipelineCache = nullptr; - { - VkDescriptorPoolSize pool_sizes[] = { - {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1}, - }; - VkDescriptorPoolCreateInfo pool_info = {}; - pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; - pool_info.maxSets = 1; - pool_info.poolSizeCount = IM_ARRAYSIZE(pool_sizes); - pool_info.pPoolSizes = pool_sizes; - auto err = wsi->get_device().get_device_table().vkCreateDescriptorPool(wsi->get_device().get_device(), &pool_info, - nullptr, &init_info.DescriptorPool); - check_vk_result(err); - } - - init_info.RenderPass = - wsi->get_device() - .request_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly), false) - .get_render_pass(); - init_info.Subpass = 0; - init_info.MinImageCount = 2; - init_info.ImageCount = 2; - init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; - init_info.Allocator = nullptr; - init_info.CheckVkResultFn = check_vk_result; - ImGui_ImplVulkan_Init(&init_info); } void ParallelRDP::Init(const std::shared_ptr &factory, const std::shared_ptr &wsiPlatform, @@ -200,16 +147,6 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr image) const { cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); DrawFullscreenTexturedQuad(image, cmd); - ImGui_ImplVulkan_NewFrame(); - ImGui_ImplSDL3_NewFrame(); - ImGui::NewFrame(); - - ImGui::Render(); - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->get_command_buffer()); - - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - cmd->end_render_pass(); wsi->get_device().submit(cmd); wsi->end_frame(); diff --git a/external/parallel-rdp/ParallelRDPWrapper.hpp b/external/parallel-rdp/ParallelRDPWrapper.hpp index bed15a66..80211d34 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.hpp +++ b/external/parallel-rdp/ParallelRDPWrapper.hpp @@ -26,13 +26,13 @@ public: bool IsFramerateUnlocked() const; void SetFramerateUnlocked(bool) const; + std::shared_ptr wsi; + std::shared_ptr command_processor; + std::shared_ptr windowInfo; + private: void LoadWSIPlatform(const std::shared_ptr &, const std::shared_ptr &, const std::shared_ptr &); void DrawFullscreenTexturedQuad(Util::IntrusivePtr, Util::IntrusivePtr) const; void UpdateScreen(Util::IntrusivePtr) const; - - std::shared_ptr wsi; - std::shared_ptr command_processor; - std::shared_ptr windowInfo; }; diff --git a/src/frontend/EmuThread.cpp b/src/frontend/EmuThread.cpp index 7b0ee1fa..d32bd9a2 100644 --- a/src/frontend/EmuThread.cpp +++ b/src/frontend/EmuThread.cpp @@ -1,13 +1,13 @@ #include #include -EmuThread::EmuThread(const std::shared_ptr &instance_, - const std::shared_ptr &wsiPlatform_, - const std::shared_ptr &windowInfo_, SettingsWindow &settings) noexcept : - instance(instance_), wsiPlatform(wsiPlatform_), windowInfo(windowInfo_), core(parallel), settings(settings) {} +EmuThread::EmuThread(RenderWidget& renderWidget, SettingsWindow &settings) noexcept : + renderWidget(renderWidget), core(parallel), settings(settings) {} [[noreturn]] void EmuThread::run() noexcept { - parallel.Init(instance, wsiPlatform, windowInfo, core.cpu->GetMem().GetRDRAMPtr()); + parallel.Init(renderWidget.instance, renderWidget.wsiPlatform, renderWidget.windowInfo, + core.cpu->GetMem().GetRDRAMPtr()); + renderWidget.InitImgui(parallel.wsi); SDL_InitSubSystem(SDL_INIT_GAMEPAD); bool controllerConnected = false; diff --git a/src/frontend/EmuThread.hpp b/src/frontend/EmuThread.hpp index a0a5d0d5..12524c74 100644 --- a/src/frontend/EmuThread.hpp +++ b/src/frontend/EmuThread.hpp @@ -9,14 +9,10 @@ class EmuThread : public QThread { Q_OBJECT - std::shared_ptr instance; - std::shared_ptr wsiPlatform; - std::shared_ptr windowInfo; + RenderWidget &renderWidget; public: - explicit EmuThread(const std::shared_ptr &instance, - const std::shared_ptr &wsiPlatform, - const std::shared_ptr &windowInfo, SettingsWindow &) noexcept; + explicit EmuThread(RenderWidget &, SettingsWindow &) noexcept; [[noreturn]] void run() noexcept override; diff --git a/src/frontend/KaizenQt.cpp b/src/frontend/KaizenQt.cpp index 50335231..89df71a3 100644 --- a/src/frontend/KaizenQt.cpp +++ b/src/frontend/KaizenQt.cpp @@ -10,9 +10,7 @@ namespace fs = std::filesystem; KaizenQt::KaizenQt() noexcept : QWidget(nullptr) { mainWindow = std::make_unique(); settingsWindow = std::make_unique(); - emuThread = std::make_unique(std::move(mainWindow->view.vulkanWidget->instance), - std::move(mainWindow->view.vulkanWidget->wsiPlatform), - std::move(mainWindow->view.vulkanWidget->windowInfo), *settingsWindow); + emuThread = std::make_unique(*mainWindow->view.vulkanWidget, *settingsWindow); ConnectMainWindowSignalsToSlots(); Util::RPC::GetInstance().Update(Util::RPC::Idling); diff --git a/src/frontend/RenderWidget.cpp b/src/frontend/RenderWidget.cpp index 8a129a7b..235cb58f 100644 --- a/src/frontend/RenderWidget.cpp +++ b/src/frontend/RenderWidget.cpp @@ -4,6 +4,80 @@ #include #include +static void check_vk_result(VkResult err) { + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); + if (err < 0) + abort(); +} + +void RenderWidget::InitImgui(std::shared_ptr& wsi) { + this->wsi = wsi; + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO &io = ImGui::GetIO(); + (void)io; + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; + + ImGui::StyleColorsDark(); + ImGuiStyle &style = ImGui::GetStyle(); + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; + + ImGui_ImplSDL3_InitForVulkan(sdlWindow); + + auto myVkInstance = instance->qVkInstance.vkInstance(); + + volkInitialize(); + volkLoadInstance(myVkInstance); + + ImGui_ImplVulkan_LoadFunctions( + [](const char *function_name, void *instance) { + return vkGetInstanceProcAddr(static_cast(instance), function_name); + }, + myVkInstance); + + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Instance = myVkInstance; + init_info.PhysicalDevice = wsi->get_device().get_physical_device(); + init_info.Device = wsi->get_device().get_device(); + init_info.QueueFamily = wsi->get_context().get_queue_info().family_indices[Vulkan::QUEUE_INDEX_GRAPHICS]; + init_info.Queue = wsi->get_context().get_queue_info().queues[Vulkan::QUEUE_INDEX_GRAPHICS]; + init_info.PipelineCache = nullptr; + { + VkDescriptorPoolSize pool_sizes[] = { + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1}, + }; + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1; + pool_info.poolSizeCount = IM_ARRAYSIZE(pool_sizes); + pool_info.pPoolSizes = pool_sizes; + auto err = wsi->get_device().get_device_table().vkCreateDescriptorPool(wsi->get_device().get_device(), &pool_info, + nullptr, &init_info.DescriptorPool); + check_vk_result(err); + } + + init_info.RenderPass = + wsi->get_device() + .request_render_pass(wsi->get_device().get_swapchain_render_pass(Vulkan::SwapchainRenderPass::ColorOnly), false) + .get_render_pass(); + init_info.Subpass = 0; + init_info.MinImageCount = 2; + init_info.ImageCount = 2; + init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + init_info.Allocator = nullptr; + init_info.CheckVkResultFn = check_vk_result; + ImGui_ImplVulkan_Init(&init_info); + + connect(&timer, &QTimer::timeout, this, &RenderWidget::UpdateEvents); + timer.setInterval(16); + timer.start(); +} + RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); @@ -21,12 +95,12 @@ RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent) { Util::panic("Could not initialize Vulkan ICD"); } - instance = std::make_unique(); + instance = std::make_shared(); windowHandle()->setVulkanInstance(&instance->qVkInstance); windowHandle()->create(); - wsiPlatform = std::make_unique(windowHandle()); - windowInfo = std::make_unique(windowHandle()); + wsiPlatform = std::make_shared(windowHandle()); + windowInfo = std::make_shared(windowHandle()); auto winPtr = reinterpret_cast(winId()); auto props = SDL_CreateProperties(); @@ -39,21 +113,6 @@ RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent) { SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER, winPtr); #endif sdlWindow = SDL_CreateWindowWithProperties(props); - - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO &io = ImGui::GetIO(); - (void)io; - io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; - - ImGui::StyleColorsDark(); - - ImGui_ImplSDL3_InitForVulkan(sdlWindow); - - connect(&timer, &QTimer::timeout, this, &RenderWidget::UpdateEvents); - timer.setInterval(16); - timer.start(); } void RenderWidget::UpdateEvents() { @@ -61,4 +120,18 @@ void RenderWidget::UpdateEvents() { while (SDL_PollEvent(&event)) { ImGui_ImplSDL3_ProcessEvent(&event); } + + Util::IntrusivePtr cmd = wsi->get_device().request_command_buffer(); + + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + + ImGui::ShowDemoWindow(); + + ImGui::Render(); + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd->get_command_buffer()); + + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); } diff --git a/src/frontend/RenderWidget.hpp b/src/frontend/RenderWidget.hpp index 476c92eb..6df316ec 100644 --- a/src/frontend/RenderWidget.hpp +++ b/src/frontend/RenderWidget.hpp @@ -84,15 +84,17 @@ class RenderWidget : public QWidget { SDL_Window *sdlWindow; QTimer timer; void UpdateEvents(); + std::shared_ptr wsi; public: explicit RenderWidget(QWidget *parent); + void InitImgui(std::shared_ptr &wsi); [[nodiscard]] QPaintEngine *paintEngine() const override { return nullptr; } - std::unique_ptr windowInfo; - std::unique_ptr wsiPlatform; - std::unique_ptr instance; + std::shared_ptr windowInfo; + std::shared_ptr wsiPlatform; + std::shared_ptr instance; Q_SIGNALS: void Show() { show(); } void Hide() { hide(); }