Decouple Imgui from Prdp

This commit is contained in:
SimoneN64
2024-09-20 15:42:44 +02:00
parent d1ccaa6667
commit c2743c8537
7 changed files with 108 additions and 102 deletions

View File

@@ -23,14 +23,6 @@ void ParallelRDP::SetFramerateUnlocked(bool unlocked) const {
Program *fullscreen_quad_program; 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> &instanceFactory, void ParallelRDP::LoadWSIPlatform(const std::shared_ptr<InstanceFactory> &instanceFactory,
const std::shared_ptr<WSIPlatform> &wsi_platform, const std::shared_ptr<WSIPlatform> &wsi_platform,
const std::shared_ptr<WindowInfo> &newWindowInfo) { const std::shared_ptr<WindowInfo> &newWindowInfo) {
@@ -44,51 +36,6 @@ void ParallelRDP::LoadWSIPlatform(const std::shared_ptr<InstanceFactory> &instan
} }
windowInfo = newWindowInfo; 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<VkInstance>(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<InstanceFactory> &factory, const std::shared_ptr<WSIPlatform> &wsiPlatform, void ParallelRDP::Init(const std::shared_ptr<InstanceFactory> &factory, const std::shared_ptr<WSIPlatform> &wsiPlatform,
@@ -200,16 +147,6 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr<Image> image) const {
cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly)); cmd->begin_render_pass(wsi->get_device().get_swapchain_render_pass(SwapchainRenderPass::ColorOnly));
DrawFullscreenTexturedQuad(image, cmd); 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(); cmd->end_render_pass();
wsi->get_device().submit(cmd); wsi->get_device().submit(cmd);
wsi->end_frame(); wsi->end_frame();

View File

@@ -26,13 +26,13 @@ public:
bool IsFramerateUnlocked() const; bool IsFramerateUnlocked() const;
void SetFramerateUnlocked(bool) const; void SetFramerateUnlocked(bool) const;
std::shared_ptr<Vulkan::WSI> wsi;
std::shared_ptr<RDP::CommandProcessor> command_processor;
std::shared_ptr<WindowInfo> windowInfo;
private: private:
void LoadWSIPlatform(const std::shared_ptr<Vulkan::InstanceFactory> &, const std::shared_ptr<Vulkan::WSIPlatform> &, void LoadWSIPlatform(const std::shared_ptr<Vulkan::InstanceFactory> &, const std::shared_ptr<Vulkan::WSIPlatform> &,
const std::shared_ptr<WindowInfo> &); const std::shared_ptr<WindowInfo> &);
void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Vulkan::Image>, Util::IntrusivePtr<Vulkan::CommandBuffer>) const; void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Vulkan::Image>, Util::IntrusivePtr<Vulkan::CommandBuffer>) const;
void UpdateScreen(Util::IntrusivePtr<Vulkan::Image>) const; void UpdateScreen(Util::IntrusivePtr<Vulkan::Image>) const;
std::shared_ptr<Vulkan::WSI> wsi;
std::shared_ptr<RDP::CommandProcessor> command_processor;
std::shared_ptr<WindowInfo> windowInfo;
}; };

View File

@@ -1,13 +1,13 @@
#include <EmuThread.hpp> #include <EmuThread.hpp>
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
EmuThread::EmuThread(const std::shared_ptr<QtInstanceFactory> &instance_, EmuThread::EmuThread(RenderWidget& renderWidget, SettingsWindow &settings) noexcept :
const std::shared_ptr<Vulkan::WSIPlatform> &wsiPlatform_, renderWidget(renderWidget), core(parallel), settings(settings) {}
const std::shared_ptr<ParallelRDP::WindowInfo> &windowInfo_, SettingsWindow &settings) noexcept :
instance(instance_), wsiPlatform(wsiPlatform_), windowInfo(windowInfo_), core(parallel), settings(settings) {}
[[noreturn]] void EmuThread::run() noexcept { [[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); SDL_InitSubSystem(SDL_INIT_GAMEPAD);
bool controllerConnected = false; bool controllerConnected = false;

View File

@@ -9,14 +9,10 @@
class EmuThread : public QThread { class EmuThread : public QThread {
Q_OBJECT Q_OBJECT
std::shared_ptr<QtInstanceFactory> instance; RenderWidget &renderWidget;
std::shared_ptr<Vulkan::WSIPlatform> wsiPlatform;
std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
public: public:
explicit EmuThread(const std::shared_ptr<QtInstanceFactory> &instance, explicit EmuThread(RenderWidget &, SettingsWindow &) noexcept;
const std::shared_ptr<Vulkan::WSIPlatform> &wsiPlatform,
const std::shared_ptr<ParallelRDP::WindowInfo> &windowInfo, SettingsWindow &) noexcept;
[[noreturn]] void run() noexcept override; [[noreturn]] void run() noexcept override;

View File

@@ -10,9 +10,7 @@ namespace fs = std::filesystem;
KaizenQt::KaizenQt() noexcept : QWidget(nullptr) { KaizenQt::KaizenQt() noexcept : QWidget(nullptr) {
mainWindow = std::make_unique<MainWindowController>(); mainWindow = std::make_unique<MainWindowController>();
settingsWindow = std::make_unique<SettingsWindow>(); settingsWindow = std::make_unique<SettingsWindow>();
emuThread = std::make_unique<EmuThread>(std::move(mainWindow->view.vulkanWidget->instance), emuThread = std::make_unique<EmuThread>(*mainWindow->view.vulkanWidget, *settingsWindow);
std::move(mainWindow->view.vulkanWidget->wsiPlatform),
std::move(mainWindow->view.vulkanWidget->windowInfo), *settingsWindow);
ConnectMainWindowSignalsToSlots(); ConnectMainWindowSignalsToSlots();
Util::RPC::GetInstance().Update(Util::RPC::Idling); Util::RPC::GetInstance().Update(Util::RPC::Idling);

View File

@@ -4,6 +4,80 @@
#include <imgui_impl_sdl3.h> #include <imgui_impl_sdl3.h>
#include <imgui_impl_vulkan.h> #include <imgui_impl_vulkan.h>
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<Vulkan::WSI>& 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<VkInstance>(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) { RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent) {
setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_NativeWindow);
setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_PaintOnScreen);
@@ -21,12 +95,12 @@ RenderWidget::RenderWidget(QWidget *parent) : QWidget(parent) {
Util::panic("Could not initialize Vulkan ICD"); Util::panic("Could not initialize Vulkan ICD");
} }
instance = std::make_unique<QtInstanceFactory>(); instance = std::make_shared<QtInstanceFactory>();
windowHandle()->setVulkanInstance(&instance->qVkInstance); windowHandle()->setVulkanInstance(&instance->qVkInstance);
windowHandle()->create(); windowHandle()->create();
wsiPlatform = std::make_unique<QtWSIPlatform>(windowHandle()); wsiPlatform = std::make_shared<QtWSIPlatform>(windowHandle());
windowInfo = std::make_unique<QtParallelRdpWindowInfo>(windowHandle()); windowInfo = std::make_shared<QtParallelRdpWindowInfo>(windowHandle());
auto winPtr = reinterpret_cast<void *>(winId()); auto winPtr = reinterpret_cast<void *>(winId());
auto props = SDL_CreateProperties(); 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); SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER, winPtr);
#endif #endif
sdlWindow = SDL_CreateWindowWithProperties(props); 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() { void RenderWidget::UpdateEvents() {
@@ -61,4 +120,18 @@ void RenderWidget::UpdateEvents() {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
ImGui_ImplSDL3_ProcessEvent(&event); ImGui_ImplSDL3_ProcessEvent(&event);
} }
Util::IntrusivePtr<Vulkan::CommandBuffer> 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();
} }

View File

@@ -84,15 +84,17 @@ class RenderWidget : public QWidget {
SDL_Window *sdlWindow; SDL_Window *sdlWindow;
QTimer timer; QTimer timer;
void UpdateEvents(); void UpdateEvents();
std::shared_ptr<Vulkan::WSI> wsi;
public: public:
explicit RenderWidget(QWidget *parent); explicit RenderWidget(QWidget *parent);
void InitImgui(std::shared_ptr<Vulkan::WSI> &wsi);
[[nodiscard]] QPaintEngine *paintEngine() const override { return nullptr; } [[nodiscard]] QPaintEngine *paintEngine() const override { return nullptr; }
std::unique_ptr<ParallelRDP::WindowInfo> windowInfo; std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform; std::shared_ptr<Vulkan::WSIPlatform> wsiPlatform;
std::unique_ptr<QtInstanceFactory> instance; std::shared_ptr<QtInstanceFactory> instance;
Q_SIGNALS: Q_SIGNALS:
void Show() { show(); } void Show() { show(); }
void Hide() { hide(); } void Hide() { hide(); }