Fix Metal rendering; HI-DPI improvements

This commit is contained in:
Luke Street 2021-05-24 18:53:49 -04:00
parent 647895316d
commit d0f088e7d5
7 changed files with 41 additions and 25 deletions

View File

@ -242,6 +242,7 @@ public:
m_window->showWindow(); m_window->showWindow();
boo::SWindowRect rect = m_window->getWindowFrame(); boo::SWindowRect rect = m_window->getWindowFrame();
m_windowCallback.m_lastRect = rect;
boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory();
gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) {
m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3); m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3);
@ -344,12 +345,14 @@ public:
m_window->waitForRetrace(); m_window->waitForRetrace();
boo::SWindowRect& rect = m_windowCallback.m_lastRect;
boo::IGraphicsCommandQueue* gfxQ = m_window->getCommandQueue(); boo::IGraphicsCommandQueue* gfxQ = m_window->getCommandQueue();
if (m_windowCallback.m_rectDirty) { if (m_windowCallback.m_rectDirty) {
boo::SWindowRect& rect = m_windowCallback.m_lastRect;
gfxQ->resizeRenderTexture(m_renderTex, rect.size[0], rect.size[1]); 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; m_windowCallback.m_rectDirty = false;
} else if (m_firstFrame) {
CGraphics::SetViewportResolution({rect.size[0], rect.size[1]});
} }
if (m_windowCallback.m_fullscreenToggleRequested) { if (m_windowCallback.m_fullscreenToggleRequested) {
@ -358,13 +361,14 @@ public:
} }
boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory();
float scale = m_window->getVirtualPixelFactor();
if (!g_mainMP1) { if (!g_mainMP1) {
g_mainMP1.emplace(nullptr, nullptr, gfxF, gfxQ, m_renderTex.get()); 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); g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_window.get(), m_voiceEngine.get(), *m_amuseAllocWrapper);
if (!m_noShaderWarmup) { if (!m_noShaderWarmup) {
g_mainMP1->WarmupShaders(); g_mainMP1->WarmupShaders();
} }
ImGuiEngine::Initialize(gfxF, m_window->getWindowFrame()); ImGuiEngine::Initialize(gfxF, m_window->getWindowFrame(), scale);
} }
float dt = 1 / 60.f; float dt = 1 / 60.f;
@ -381,7 +385,7 @@ public:
} }
m_prevFrameTime = now; m_prevFrameTime = now;
ImGuiEngine::Begin(realDt); ImGuiEngine::Begin(realDt, scale);
if (g_mainMP1->Proc(dt)) { if (g_mainMP1->Proc(dt)) {
m_running.store(false); m_running.store(false);
@ -391,6 +395,8 @@ public:
{ {
OPTICK_EVENT("Draw"); OPTICK_EVENT("Draw");
gfxQ->setRenderTarget(m_renderTex); gfxQ->setRenderTarget(m_renderTex);
gfxQ->setViewport(rect);
gfxQ->setScissor(rect);
if (g_Renderer != nullptr) { if (g_Renderer != nullptr) {
g_Renderer->BeginScene(); g_Renderer->BeginScene();
} }

View File

@ -48,10 +48,13 @@ if(APPLE)
list(APPEND PLAT_SRCS startButton.cpp CGameOptionsTouchBarMac.mm) list(APPEND PLAT_SRCS startButton.cpp CGameOptionsTouchBarMac.mm)
endif() endif()
set(RUNTIME_SOURCES_A set(CAST_TO_SOURCES
MkCastTo.py MkCastTo.py
TCastTo.hpp TCastTo.cpp TCastTo.hpp TCastTo.cpp)
set(RUNTIME_SOURCES_A
RetroTypes.hpp RetroTypes.cpp RetroTypes.hpp RetroTypes.cpp
${CAST_TO_SOURCES}
${MP1_SOURCES} ${MP1_SOURCES}
${AUDIO_SOURCES} ${AUDIO_SOURCES}
${AUTOMAPPER_SOURCES} ${AUTOMAPPER_SOURCES}
@ -61,6 +64,7 @@ set(RUNTIME_SOURCES_A
${GRAPHICS_SOURCES}) ${GRAPHICS_SOURCES})
set(RUNTIME_SOURCES_B set(RUNTIME_SOURCES_B
${CAST_TO_SOURCES}
${GUISYS_SOURCES} ${GUISYS_SOURCES}
${INPUT_SOURCES} ${INPUT_SOURCES}
${PARTICLE_SOURCES} ${PARTICLE_SOURCES}

2
extern/boo vendored

@ -1 +1 @@
Subproject commit d13fbda0c0ef0a832ed31ab4a7e91a23c6167f52 Subproject commit 8dd258fc62be57c435ce47dcac691406baab14ec

View File

@ -4,7 +4,6 @@ add_library(imgui
../extern/imgui/imgui_draw.cpp ../extern/imgui/imgui_draw.cpp
../extern/imgui/imgui_tables.cpp ../extern/imgui/imgui_tables.cpp
../extern/imgui/imgui_widgets.cpp ../extern/imgui/imgui_widgets.cpp
../extern/imgui/backends/imgui_impl_vulkan.cpp
ImGuiEngine.cpp ImGuiEngine.cpp
ImGuiEngine.hpp 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_compile_definitions(imgui PUBLIC IMGUI_USER_CONFIG="imconfig_user.h")
target_link_libraries(imgui PRIVATE boo hecl-light RetroDataSpec) target_link_libraries(imgui PRIVATE boo hecl-light RetroDataSpec)
add_shader(ImguiShader) add_shader(ImGuiShader)
target_link_libraries(shader_ImguiShader PRIVATE hecl-light) target_link_libraries(shader_ImGuiShader PRIVATE hecl-light)

View File

@ -26,7 +26,7 @@ struct Uniform {
static size_t VertexBufferSize = 5000; static size_t VertexBufferSize = 5000;
static size_t IndexBufferSize = 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; m_factory = factory;
WindowRect = rect; WindowRect = rect;
@ -60,7 +60,7 @@ void ImGuiEngine::Initialize(boo::IGraphicsDataFactory* factory, const boo::SWin
unsigned char* pixels = nullptr; unsigned char* pixels = nullptr;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { 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, ImGuiAtlas = ctx.newStaticTexture(width, height, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::ClampToEdge,
pixels, width * height * 4); pixels, width * height * 4);
VertexBuffer = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(ImDrawVert), VertexBufferSize); VertexBuffer = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(ImDrawVert), VertexBufferSize);
@ -77,13 +77,13 @@ void ImGuiEngine::Shutdown() {
ShaderPipeline.reset(); ShaderPipeline.reset();
} }
void ImGuiEngine::Begin(float dt) { void ImGuiEngine::Begin(float dt, float scale) {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = dt; io.DeltaTime = dt;
io.DisplaySize.x = WindowRect.size[0]; io.DisplaySize.x = WindowRect.size[0];
io.DisplaySize.y = WindowRect.size[1]; io.DisplaySize.y = WindowRect.size[1];
// TODO io.DisplayFramebufferScale = ImVec2{scale, scale};
// io.DisplayFramebufferScale = ImVec2{1.f, 1.f}; io.FontGlobalScale = scale;
if (Input.m_mouseIn) { if (Input.m_mouseIn) {
io.MousePos = ImVec2{static_cast<float>(Input.m_mousePos.pixel[0]), io.MousePos = ImVec2{static_cast<float>(Input.m_mousePos.pixel[0]),
static_cast<float>(WindowRect.size[1] - Input.m_mousePos.pixel[1])}; static_cast<float>(WindowRect.size[1] - Input.m_mousePos.pixel[1])};
@ -91,8 +91,14 @@ void ImGuiEngine::Begin(float dt) {
io.MousePos = ImVec2{-FLT_MAX, -FLT_MAX}; io.MousePos = ImVec2{-FLT_MAX, -FLT_MAX};
} }
memcpy(io.MouseDown, Input.m_mouseButtons.data(), sizeof(io.MouseDown)); memcpy(io.MouseDown, Input.m_mouseButtons.data(), sizeof(io.MouseDown));
io.MouseWheel = static_cast<float>(Input.m_scrollDelta.delta[1]); float scrollDelta = Input.m_scrollDelta.delta[1] / scale;
io.MouseWheelH = static_cast<float>(Input.m_scrollDelta.delta[0]); float scrollDeltaH = Input.m_scrollDelta.delta[0] / scale;
if (Input.m_scrollDelta.isAccelerated) {
scrollDelta /= 10.f;
scrollDeltaH /= 10.f;
}
io.MouseWheel = static_cast<float>(scrollDelta);
io.MouseWheelH = static_cast<float>(scrollDeltaH);
Input.m_scrollDelta.zeroOut(); Input.m_scrollDelta.zeroOut();
io.KeyCtrl = True(Input.m_modifiers & boo::EModifierKey::Ctrl); io.KeyCtrl = True(Input.m_modifiers & boo::EModifierKey::Ctrl);
io.KeyShift = True(Input.m_modifiers & boo::EModifierKey::Shift); io.KeyShift = True(Input.m_modifiers & boo::EModifierKey::Shift);
@ -199,7 +205,8 @@ void ImGuiEngine::Draw(boo::IGraphicsCommandQueue* gfxQ) {
int clipW = static_cast<int>(drawCmd.ClipRect.z - pos.x) - clipX; int clipW = static_cast<int>(drawCmd.ClipRect.z - pos.x) - clipX;
int clipH = static_cast<int>(drawCmd.ClipRect.w - pos.y) - clipY; int clipH = static_cast<int>(drawCmd.ClipRect.w - pos.y) - clipY;
boo::SWindowRect clipRect{clipX, clipY, clipW, clipH}; 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]; clipRect.location[1] = viewportHeight - clipRect.location[1] - clipRect.size[1];
} }
gfxQ->setScissor(clipRect); gfxQ->setScissor(clipRect);

View File

@ -18,10 +18,10 @@ public:
bool m_mouseIn = true; bool m_mouseIn = true;
} Input; } 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 Shutdown();
static void Begin(float dt); static void Begin(float dt, float scale);
static void End(); static void End();
static void Draw(boo::IGraphicsCommandQueue* gfxQ); static void Draw(boo::IGraphicsCommandQueue* gfxQ);

View File

@ -1,4 +1,4 @@
#shader ImguiShader #shader ImGuiShader
#attribute position2 #attribute position2
#attribute uv2 #attribute uv2
#attribute colorunorm #attribute colorunorm
@ -14,7 +14,7 @@
layout (location = 0) in vec2 pos; layout (location = 0) in vec2 pos;
layout (location = 1) in vec2 uv; layout (location = 1) in vec2 uv;
layout (location = 2) in vec4 color; layout (location = 2) in vec4 color;
UBINDING0 uniform ImguiShaderUniform UBINDING0 uniform ImGuiShaderUniform
{ {
mat4 xf; mat4 xf;
}; };
@ -49,7 +49,7 @@ void main()
#vertex hlsl #vertex hlsl
cbuffer ImguiShaderUniform : register(b0) cbuffer ImGuiShaderUniform : register(b0)
{ {
float4x4 xf; float4x4 xf;
}; };
@ -94,7 +94,7 @@ float4 main(in VertToFrag vtf) : SV_Target0
#vertex metal #vertex metal
struct ImguiShaderUniform { struct ImGuiShaderUniform {
float4x4 xf; float4x4 xf;
}; };
@ -111,7 +111,7 @@ struct VertToFrag {
}; };
vertex VertToFrag vmain(VertexIn v [[stage_in]], vertex VertToFrag vmain(VertexIn v [[stage_in]],
constant ImguiShaderUniform& u [[buffer(2)]]) { constant ImGuiShaderUniform& u [[buffer(2)]]) {
VertToFrag vtf; VertToFrag vtf;
vtf.position = u.xf * float4(v.position, 0, 1); vtf.position = u.xf * float4(v.position, 0, 1);
vtf.texCoords = v.texCoords; vtf.texCoords = v.texCoords;