Dear ImGui Implementation (#598)

* added imgui as dependency

* imgui renderer/basic input implementation

* imgui: add layers system

Add video info layer to show fps. Press F10 to toggle it.

* imgui: add custom imgui config

* imgui: gamepad capture, stopping propagation

* imgui: changed config & log file path to use portable dir

* videoout: render blank frame when video output is closed

required to render imgui even when game has no video output

- fixed merge compile-error
This commit is contained in:
Vinicius Rangel 2024-09-08 16:50:32 -03:00 committed by GitHub
parent f1becb2507
commit 035cb3eeaa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 2386 additions and 8 deletions

View file

@ -6,6 +6,7 @@
#include "common/singleton.h"
#include "core/file_format/splash.h"
#include "core/libraries/system/systemservice.h"
#include "imgui/renderer/imgui_core.h"
#include "sdl_window.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/renderer_vulkan/vk_rasterizer.h"
@ -73,7 +74,7 @@ RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool*
draw_scheduler{instance}, present_scheduler{instance}, flip_scheduler{instance},
swapchain{instance, window},
rasterizer{std::make_unique<Rasterizer>(instance, draw_scheduler, liverpool)},
texture_cache{rasterizer->GetTextureCache()} {
texture_cache{rasterizer->GetTextureCache()}, video_info_ui{this} {
const u32 num_images = swapchain.GetImageCount();
const vk::Device device = instance.GetDevice();
@ -84,9 +85,14 @@ RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool*
frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled});
free_queue.push(&frame);
}
// Setup ImGui
ImGui::Core::Initialize(instance, window, num_images, swapchain.GetSurfaceFormat().format);
ImGui::Layer::AddLayer(&video_info_ui);
}
RendererVulkan::~RendererVulkan() {
ImGui::Layer::RemoveLayer(&video_info_ui);
draw_scheduler.Finish();
const vk::Device device = instance.GetDevice();
for (auto& frame : present_frames) {
@ -94,6 +100,7 @@ RendererVulkan::~RendererVulkan() {
device.destroyImageView(frame.image_view);
device.destroyFence(frame.present_done);
}
ImGui::Core::Shutdown(device);
}
void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
@ -254,6 +261,8 @@ Frame* RendererVulkan::PrepareFrameInternal(VideoCore::Image& image, bool is_eop
}
void RendererVulkan::Present(Frame* frame) {
ImGui::Core::NewFrame();
swapchain.AcquireNextImage();
const vk::Image swapchain_image = swapchain.Image();
@ -286,7 +295,7 @@ void RendererVulkan::Present(Frame* frame) {
vk::ImageMemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite,
.dstAccessMask = vk::AccessFlagBits::eTransferRead,
.oldLayout = vk::ImageLayout::eGeneral,
.oldLayout = vk::ImageLayout::eUndefined,
.newLayout = vk::ImageLayout::eTransferSrcOptimal,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@ -317,6 +326,8 @@ void RendererVulkan::Present(Frame* frame) {
},
};
ImGui::Core::Render(cmdbuf, frame);
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eColorAttachmentOutput,
vk::PipelineStageFlagBits::eTransfer,
vk::DependencyFlagBits::eByRegion, {}, {}, pre_barriers);

View file

@ -4,6 +4,8 @@
#pragma once
#include <condition_variable>
#include "imgui/layer/video_info.h"
#include "video_core/amdgpu/liverpool.h"
#include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_scheduler.h"
@ -103,6 +105,8 @@ private:
std::condition_variable_any frame_cv;
std::optional<VideoCore::Image> splash_img;
std::vector<VAddr> vo_buffers_addr;
ImGui::Layers::VideoInfo video_info_ui;
};
} // namespace Vulkan