From 2f822d07c73595b6787389cad936afdfda230ace Mon Sep 17 00:00:00 2001 From: Samuliak Date: Fri, 30 Aug 2024 08:57:50 +0200 Subject: [PATCH] support game pad view in a separate window --- .../Latte/Renderer/Metal/MetalLayerHandle.cpp | 6 ++-- .../Latte/Renderer/Metal/MetalLayerHandle.h | 2 +- .../Renderer/Metal/MetalPipelineCache.cpp | 1 - .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 36 ++++++++----------- .../HW/Latte/Renderer/Metal/MetalRenderer.h | 1 + src/gui/canvas/MetalCanvas.cpp | 12 +++---- 6 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp index 3a3a6b54..ad16b89a 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp @@ -3,9 +3,9 @@ #include "gui/guiWrapper.h" -MetalLayerHandle::MetalLayerHandle(MTL::Device* device, const Vector2i& size) +MetalLayerHandle::MetalLayerHandle(MTL::Device* device, const Vector2i& size, bool mainWindow) { - const auto& windowInfo = gui_getWindowInfo().window_main; + const auto& windowInfo = (mainWindow ? gui_getWindowInfo().window_main : gui_getWindowInfo().window_pad); m_layer = (CA::MetalLayer*)CreateMetalLayer(windowInfo.handle, m_layerScaleX, m_layerScaleY); m_layer->setDevice(device); @@ -32,7 +32,7 @@ bool MetalLayerHandle::AcquireDrawable() m_drawable = m_layer->nextDrawable(); if (!m_drawable) { - debug_printf("failed to acquire next drawable\n"); + debug_printf("layer %p failed to acquire next drawable\n", this); return false; } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h index 39a7cd1f..014d2d43 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h @@ -9,7 +9,7 @@ class MetalLayerHandle { public: MetalLayerHandle() = default; - MetalLayerHandle(MTL::Device* device, const Vector2i& size); + MetalLayerHandle(MTL::Device* device, const Vector2i& size, bool mainWindow); ~MetalLayerHandle(); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index 6a746515..48a048ec 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -334,7 +334,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte { // Buffer stride cannot be zero, let's use the minimum stride bufferStride = minBufferStride; - debug_printf("vertex buffer %u has a vertex stride of 0 bytes, using %u bytes instead\n", bufferIndex, bufferStride); // Additionally, constant vertex function must be used layout->setStepFunction(MTL::VertexStepFunctionConstant); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index a755ba31..392ede6d 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -16,14 +16,11 @@ #include "Cafe/HW/Latte/Core/LatteShader.h" #include "Cafe/HW/Latte/Core/LatteIndices.h" #include "Cemu/Logging/CemuDebugLogging.h" -#include "Common/precompiled.h" -#include "Foundation/NSTypes.hpp" #include "HW/Latte/Core/LatteConst.h" #include "HW/Latte/Renderer/Metal/MetalCommon.h" #include "HW/Latte/Renderer/Metal/MetalLayerHandle.h" #include "HW/Latte/Renderer/Renderer.h" #include "imgui.h" -#include #define IMGUI_IMPL_METAL_CPP #include "imgui/imgui_extension.h" @@ -195,10 +192,15 @@ MetalRenderer::~MetalRenderer() void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) { auto& layer = GetLayer(mainWindow); - layer = MetalLayerHandle(m_device, size); + layer = MetalLayerHandle(m_device, size, mainWindow); layer.GetLayer()->setPixelFormat(MTL::PixelFormatBGRA8Unorm); } +void MetalRenderer::ShutdownLayer(bool mainWindow) +{ + GetLayer(mainWindow) = MetalLayerHandle(); +} + void MetalRenderer::ResizeLayer(const Vector2i& size, bool mainWindow) { GetLayer(mainWindow).Resize(size); @@ -217,16 +219,14 @@ void MetalRenderer::Shutdown() CommitCommandBuffer(); } -// TODO: what should this do? bool MetalRenderer::IsPadWindowActive() { - return (GetLayer(false).GetDrawable() != nullptr); + return (GetLayer(false).GetLayer() != nullptr); } bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const { usageInMB = m_device->currentAllocatedSize() / 1024 / 1024; - // TODO: get the total VRAM size? Though would be pretty useless on Apple Silicon totalInMB = m_recommendedMaxVRAMUsage / 1024 / 1024; return true; @@ -266,6 +266,9 @@ void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC) // Unlock all temporary buffers m_memoryManager->GetTemporaryBufferAllocator().EndFrame(); + + // Debug + m_performanceMonitor.ResetPerFrameData(); } // TODO: use `shader` for drawing @@ -1546,6 +1549,8 @@ void MetalRenderer::CommitCommandBuffer() bool MetalRenderer::AcquireDrawable(bool mainWindow) { auto& layer = GetLayer(mainWindow); + if (!layer.GetLayer()) + return false; const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB; if (latteBufferUsesSRGB != m_state.m_usesSRGB) @@ -1856,22 +1861,11 @@ void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL:: void MetalRenderer::SwapBuffer(bool mainWindow) { - auto& layer = GetLayer(mainWindow); - if (!layer.AcquireDrawable()) + if (!AcquireDrawable(mainWindow)) return; - if (layer.GetDrawable()) - { - auto commandBuffer = GetCommandBuffer(); - layer.PresentDrawable(commandBuffer); - } - else - { - debug_printf("skipped present!\n"); - } - - // Debug - m_performanceMonitor.ResetPerFrameData(); + auto commandBuffer = GetCommandBuffer(); + GetLayer(mainWindow).PresentDrawable(commandBuffer); } void MetalRenderer::EnsureImGuiBackend() diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index e8c15133..3281ccf2 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -204,6 +204,7 @@ public: } void InitializeLayer(const Vector2i& size, bool mainWindow); + void ShutdownLayer(bool mainWindow); void ResizeLayer(const Vector2i& size, bool mainWindow); void Initialize() override; diff --git a/src/gui/canvas/MetalCanvas.cpp b/src/gui/canvas/MetalCanvas.cpp index 2c89f882..a9d1cb9d 100644 --- a/src/gui/canvas/MetalCanvas.cpp +++ b/src/gui/canvas/MetalCanvas.cpp @@ -39,13 +39,9 @@ MetalCanvas::~MetalCanvas() Unbind(wxEVT_PAINT, &MetalCanvas::OnPaint, this); Unbind(wxEVT_SIZE, &MetalCanvas::OnResize, this); - if(!m_is_main_window) - { - // TODO - //MetalRenderer* vkr = (MetalRenderer*)g_renderer.get(); - //if(vkr) - // vkr->StopUsingPadAndWait(); - } + MetalRenderer* mtlr = (MetalRenderer*)g_renderer.get(); + if (mtlr) + mtlr->ShutdownLayer(m_is_main_window); } void MetalCanvas::OnPaint(wxPaintEvent& event) @@ -62,5 +58,5 @@ void MetalCanvas::OnResize(wxSizeEvent& event) RefreshRect(refreshRect, false); auto metal_renderer = MetalRenderer::GetInstance(); - metal_renderer->InitializeLayer({size.x, size.y}, m_is_main_window); + metal_renderer->ResizeLayer({size.x, size.y}, m_is_main_window); }