From d0f088e7d5845d1f97a594a4dc86e4127a1d7db3 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 24 May 2021 18:53:49 -0400 Subject: [PATCH] Fix Metal rendering; HI-DPI improvements --- Runtime/CMain.cpp | 14 +++++++---- Runtime/CMakeLists.txt | 8 +++++-- extern/boo | 2 +- imgui/CMakeLists.txt | 5 ++-- imgui/ImGuiEngine.cpp | 23 ++++++++++++------- imgui/ImGuiEngine.hpp | 4 ++-- ...{ImguiShader.shader => ImGuiShader.shader} | 10 ++++---- 7 files changed, 41 insertions(+), 25 deletions(-) rename imgui/{ImguiShader.shader => ImGuiShader.shader} (92%) diff --git a/Runtime/CMain.cpp b/Runtime/CMain.cpp index d8d7439bc..8d4ffb38a 100644 --- a/Runtime/CMain.cpp +++ b/Runtime/CMain.cpp @@ -242,6 +242,7 @@ public: m_window->showWindow(); boo::SWindowRect rect = m_window->getWindowFrame(); + m_windowCallback.m_lastRect = rect; boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3); @@ -344,12 +345,14 @@ public: m_window->waitForRetrace(); + boo::SWindowRect& rect = m_windowCallback.m_lastRect; boo::IGraphicsCommandQueue* gfxQ = m_window->getCommandQueue(); if (m_windowCallback.m_rectDirty) { - boo::SWindowRect& rect = m_windowCallback.m_lastRect; gfxQ->resizeRenderTexture(m_renderTex, rect.size[0], rect.size[1]); - metaforce::CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); + CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); m_windowCallback.m_rectDirty = false; + } else if (m_firstFrame) { + CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); } if (m_windowCallback.m_fullscreenToggleRequested) { @@ -358,13 +361,14 @@ public: } boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); + float scale = m_window->getVirtualPixelFactor(); if (!g_mainMP1) { g_mainMP1.emplace(nullptr, nullptr, gfxF, gfxQ, m_renderTex.get()); g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_window.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); if (!m_noShaderWarmup) { g_mainMP1->WarmupShaders(); } - ImGuiEngine::Initialize(gfxF, m_window->getWindowFrame()); + ImGuiEngine::Initialize(gfxF, m_window->getWindowFrame(), scale); } float dt = 1 / 60.f; @@ -381,7 +385,7 @@ public: } m_prevFrameTime = now; - ImGuiEngine::Begin(realDt); + ImGuiEngine::Begin(realDt, scale); if (g_mainMP1->Proc(dt)) { m_running.store(false); @@ -391,6 +395,8 @@ public: { OPTICK_EVENT("Draw"); gfxQ->setRenderTarget(m_renderTex); + gfxQ->setViewport(rect); + gfxQ->setScissor(rect); if (g_Renderer != nullptr) { g_Renderer->BeginScene(); } diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index 8053af14b..549fb1b81 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -48,10 +48,13 @@ if(APPLE) list(APPEND PLAT_SRCS startButton.cpp CGameOptionsTouchBarMac.mm) endif() -set(RUNTIME_SOURCES_A +set(CAST_TO_SOURCES MkCastTo.py - TCastTo.hpp TCastTo.cpp + TCastTo.hpp TCastTo.cpp) + +set(RUNTIME_SOURCES_A RetroTypes.hpp RetroTypes.cpp + ${CAST_TO_SOURCES} ${MP1_SOURCES} ${AUDIO_SOURCES} ${AUTOMAPPER_SOURCES} @@ -61,6 +64,7 @@ set(RUNTIME_SOURCES_A ${GRAPHICS_SOURCES}) set(RUNTIME_SOURCES_B + ${CAST_TO_SOURCES} ${GUISYS_SOURCES} ${INPUT_SOURCES} ${PARTICLE_SOURCES} diff --git a/extern/boo b/extern/boo index d13fbda0c..8dd258fc6 160000 --- a/extern/boo +++ b/extern/boo @@ -1 +1 @@ -Subproject commit d13fbda0c0ef0a832ed31ab4a7e91a23c6167f52 +Subproject commit 8dd258fc62be57c435ce47dcac691406baab14ec diff --git a/imgui/CMakeLists.txt b/imgui/CMakeLists.txt index bd56e2514..c3ec95d1b 100644 --- a/imgui/CMakeLists.txt +++ b/imgui/CMakeLists.txt @@ -4,7 +4,6 @@ add_library(imgui ../extern/imgui/imgui_draw.cpp ../extern/imgui/imgui_tables.cpp ../extern/imgui/imgui_widgets.cpp - ../extern/imgui/backends/imgui_impl_vulkan.cpp ImGuiEngine.cpp ImGuiEngine.hpp ) @@ -12,5 +11,5 @@ target_include_directories(imgui PUBLIC ../extern/imgui ${CMAKE_CURRENT_SOURCE_D target_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imconfig_user.h") target_link_libraries(imgui PRIVATE boo hecl-light RetroDataSpec) -add_shader(ImguiShader) -target_link_libraries(shader_ImguiShader PRIVATE hecl-light) +add_shader(ImGuiShader) +target_link_libraries(shader_ImGuiShader PRIVATE hecl-light) diff --git a/imgui/ImGuiEngine.cpp b/imgui/ImGuiEngine.cpp index 5883356d6..0311ad67f 100644 --- a/imgui/ImGuiEngine.cpp +++ b/imgui/ImGuiEngine.cpp @@ -26,7 +26,7 @@ struct Uniform { static size_t VertexBufferSize = 5000; static size_t IndexBufferSize = 5000; -void ImGuiEngine::Initialize(boo::IGraphicsDataFactory* factory, const boo::SWindowRect& rect) { +void ImGuiEngine::Initialize(boo::IGraphicsDataFactory* factory, const boo::SWindowRect& rect, float scale) { m_factory = factory; WindowRect = rect; @@ -60,7 +60,7 @@ void ImGuiEngine::Initialize(boo::IGraphicsDataFactory* factory, const boo::SWin unsigned char* pixels = nullptr; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { - ShaderPipeline = hecl::conv->convert(Shader_ImguiShader{}); + ShaderPipeline = hecl::conv->convert(Shader_ImGuiShader{}); ImGuiAtlas = ctx.newStaticTexture(width, height, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::ClampToEdge, pixels, width * height * 4); VertexBuffer = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(ImDrawVert), VertexBufferSize); @@ -77,13 +77,13 @@ void ImGuiEngine::Shutdown() { ShaderPipeline.reset(); } -void ImGuiEngine::Begin(float dt) { +void ImGuiEngine::Begin(float dt, float scale) { ImGuiIO& io = ImGui::GetIO(); io.DeltaTime = dt; io.DisplaySize.x = WindowRect.size[0]; io.DisplaySize.y = WindowRect.size[1]; - // TODO - // io.DisplayFramebufferScale = ImVec2{1.f, 1.f}; + io.DisplayFramebufferScale = ImVec2{scale, scale}; + io.FontGlobalScale = scale; if (Input.m_mouseIn) { io.MousePos = ImVec2{static_cast(Input.m_mousePos.pixel[0]), static_cast(WindowRect.size[1] - Input.m_mousePos.pixel[1])}; @@ -91,8 +91,14 @@ void ImGuiEngine::Begin(float dt) { io.MousePos = ImVec2{-FLT_MAX, -FLT_MAX}; } memcpy(io.MouseDown, Input.m_mouseButtons.data(), sizeof(io.MouseDown)); - io.MouseWheel = static_cast(Input.m_scrollDelta.delta[1]); - io.MouseWheelH = static_cast(Input.m_scrollDelta.delta[0]); + float scrollDelta = Input.m_scrollDelta.delta[1] / scale; + float scrollDeltaH = Input.m_scrollDelta.delta[0] / scale; + if (Input.m_scrollDelta.isAccelerated) { + scrollDelta /= 10.f; + scrollDeltaH /= 10.f; + } + io.MouseWheel = static_cast(scrollDelta); + io.MouseWheelH = static_cast(scrollDeltaH); Input.m_scrollDelta.zeroOut(); io.KeyCtrl = True(Input.m_modifiers & boo::EModifierKey::Ctrl); io.KeyShift = True(Input.m_modifiers & boo::EModifierKey::Shift); @@ -199,7 +205,8 @@ void ImGuiEngine::Draw(boo::IGraphicsCommandQueue* gfxQ) { int clipW = static_cast(drawCmd.ClipRect.z - pos.x) - clipX; int clipH = static_cast(drawCmd.ClipRect.w - pos.y) - clipY; boo::SWindowRect clipRect{clipX, clipY, clipW, clipH}; - if (m_factory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan) { + if (m_factory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan + || m_factory->platform() == boo::IGraphicsDataFactory::Platform::Metal) { clipRect.location[1] = viewportHeight - clipRect.location[1] - clipRect.size[1]; } gfxQ->setScissor(clipRect); diff --git a/imgui/ImGuiEngine.hpp b/imgui/ImGuiEngine.hpp index ff5e31642..cacc8122f 100644 --- a/imgui/ImGuiEngine.hpp +++ b/imgui/ImGuiEngine.hpp @@ -18,10 +18,10 @@ public: bool m_mouseIn = true; } Input; - static void Initialize(boo::IGraphicsDataFactory* factory, const boo::SWindowRect &rect); + static void Initialize(boo::IGraphicsDataFactory* factory, const boo::SWindowRect &rect, float scale); static void Shutdown(); - static void Begin(float dt); + static void Begin(float dt, float scale); static void End(); static void Draw(boo::IGraphicsCommandQueue* gfxQ); diff --git a/imgui/ImguiShader.shader b/imgui/ImGuiShader.shader similarity index 92% rename from imgui/ImguiShader.shader rename to imgui/ImGuiShader.shader index 256eb3b44..32bfcea75 100644 --- a/imgui/ImguiShader.shader +++ b/imgui/ImGuiShader.shader @@ -1,4 +1,4 @@ -#shader ImguiShader +#shader ImGuiShader #attribute position2 #attribute uv2 #attribute colorunorm @@ -14,7 +14,7 @@ layout (location = 0) in vec2 pos; layout (location = 1) in vec2 uv; layout (location = 2) in vec4 color; -UBINDING0 uniform ImguiShaderUniform +UBINDING0 uniform ImGuiShaderUniform { mat4 xf; }; @@ -49,7 +49,7 @@ void main() #vertex hlsl -cbuffer ImguiShaderUniform : register(b0) +cbuffer ImGuiShaderUniform : register(b0) { float4x4 xf; }; @@ -94,7 +94,7 @@ float4 main(in VertToFrag vtf) : SV_Target0 #vertex metal -struct ImguiShaderUniform { +struct ImGuiShaderUniform { float4x4 xf; }; @@ -111,7 +111,7 @@ struct VertToFrag { }; vertex VertToFrag vmain(VertexIn v [[stage_in]], - constant ImguiShaderUniform& u [[buffer(2)]]) { + constant ImGuiShaderUniform& u [[buffer(2)]]) { VertToFrag vtf; vtf.position = u.xf * float4(v.position, 0, 1); vtf.texCoords = v.texCoords;