support game pad view in a separate window

This commit is contained in:
Samuliak 2024-08-30 08:57:50 +02:00
parent 1cfb841b5f
commit 2f822d07c7
6 changed files with 24 additions and 34 deletions

View File

@ -3,9 +3,9 @@
#include "gui/guiWrapper.h" #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 = (CA::MetalLayer*)CreateMetalLayer(windowInfo.handle, m_layerScaleX, m_layerScaleY);
m_layer->setDevice(device); m_layer->setDevice(device);
@ -32,7 +32,7 @@ bool MetalLayerHandle::AcquireDrawable()
m_drawable = m_layer->nextDrawable(); m_drawable = m_layer->nextDrawable();
if (!m_drawable) if (!m_drawable)
{ {
debug_printf("failed to acquire next drawable\n"); debug_printf("layer %p failed to acquire next drawable\n", this);
return false; return false;
} }

View File

@ -9,7 +9,7 @@ class MetalLayerHandle
{ {
public: public:
MetalLayerHandle() = default; MetalLayerHandle() = default;
MetalLayerHandle(MTL::Device* device, const Vector2i& size); MetalLayerHandle(MTL::Device* device, const Vector2i& size, bool mainWindow);
~MetalLayerHandle(); ~MetalLayerHandle();

View File

@ -334,7 +334,6 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
{ {
// Buffer stride cannot be zero, let's use the minimum stride // Buffer stride cannot be zero, let's use the minimum stride
bufferStride = minBufferStride; 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 // Additionally, constant vertex function must be used
layout->setStepFunction(MTL::VertexStepFunctionConstant); layout->setStepFunction(MTL::VertexStepFunctionConstant);

View File

@ -16,14 +16,11 @@
#include "Cafe/HW/Latte/Core/LatteShader.h" #include "Cafe/HW/Latte/Core/LatteShader.h"
#include "Cafe/HW/Latte/Core/LatteIndices.h" #include "Cafe/HW/Latte/Core/LatteIndices.h"
#include "Cemu/Logging/CemuDebugLogging.h" #include "Cemu/Logging/CemuDebugLogging.h"
#include "Common/precompiled.h"
#include "Foundation/NSTypes.hpp"
#include "HW/Latte/Core/LatteConst.h" #include "HW/Latte/Core/LatteConst.h"
#include "HW/Latte/Renderer/Metal/MetalCommon.h" #include "HW/Latte/Renderer/Metal/MetalCommon.h"
#include "HW/Latte/Renderer/Metal/MetalLayerHandle.h" #include "HW/Latte/Renderer/Metal/MetalLayerHandle.h"
#include "HW/Latte/Renderer/Renderer.h" #include "HW/Latte/Renderer/Renderer.h"
#include "imgui.h" #include "imgui.h"
#include <cstddef>
#define IMGUI_IMPL_METAL_CPP #define IMGUI_IMPL_METAL_CPP
#include "imgui/imgui_extension.h" #include "imgui/imgui_extension.h"
@ -195,10 +192,15 @@ MetalRenderer::~MetalRenderer()
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow)
{ {
auto& layer = GetLayer(mainWindow); auto& layer = GetLayer(mainWindow);
layer = MetalLayerHandle(m_device, size); layer = MetalLayerHandle(m_device, size, mainWindow);
layer.GetLayer()->setPixelFormat(MTL::PixelFormatBGRA8Unorm); layer.GetLayer()->setPixelFormat(MTL::PixelFormatBGRA8Unorm);
} }
void MetalRenderer::ShutdownLayer(bool mainWindow)
{
GetLayer(mainWindow) = MetalLayerHandle();
}
void MetalRenderer::ResizeLayer(const Vector2i& size, bool mainWindow) void MetalRenderer::ResizeLayer(const Vector2i& size, bool mainWindow)
{ {
GetLayer(mainWindow).Resize(size); GetLayer(mainWindow).Resize(size);
@ -217,16 +219,14 @@ void MetalRenderer::Shutdown()
CommitCommandBuffer(); CommitCommandBuffer();
} }
// TODO: what should this do?
bool MetalRenderer::IsPadWindowActive() bool MetalRenderer::IsPadWindowActive()
{ {
return (GetLayer(false).GetDrawable() != nullptr); return (GetLayer(false).GetLayer() != nullptr);
} }
bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const
{ {
usageInMB = m_device->currentAllocatedSize() / 1024 / 1024; 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; totalInMB = m_recommendedMaxVRAMUsage / 1024 / 1024;
return true; return true;
@ -266,6 +266,9 @@ void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
// Unlock all temporary buffers // Unlock all temporary buffers
m_memoryManager->GetTemporaryBufferAllocator().EndFrame(); m_memoryManager->GetTemporaryBufferAllocator().EndFrame();
// Debug
m_performanceMonitor.ResetPerFrameData();
} }
// TODO: use `shader` for drawing // TODO: use `shader` for drawing
@ -1546,6 +1549,8 @@ void MetalRenderer::CommitCommandBuffer()
bool MetalRenderer::AcquireDrawable(bool mainWindow) bool MetalRenderer::AcquireDrawable(bool mainWindow)
{ {
auto& layer = GetLayer(mainWindow); auto& layer = GetLayer(mainWindow);
if (!layer.GetLayer())
return false;
const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB; const bool latteBufferUsesSRGB = mainWindow ? LatteGPUState.tvBufferUsesSRGB : LatteGPUState.drcBufferUsesSRGB;
if (latteBufferUsesSRGB != m_state.m_usesSRGB) if (latteBufferUsesSRGB != m_state.m_usesSRGB)
@ -1856,22 +1861,11 @@ void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::
void MetalRenderer::SwapBuffer(bool mainWindow) void MetalRenderer::SwapBuffer(bool mainWindow)
{ {
auto& layer = GetLayer(mainWindow); if (!AcquireDrawable(mainWindow))
if (!layer.AcquireDrawable())
return; return;
if (layer.GetDrawable()) auto commandBuffer = GetCommandBuffer();
{ GetLayer(mainWindow).PresentDrawable(commandBuffer);
auto commandBuffer = GetCommandBuffer();
layer.PresentDrawable(commandBuffer);
}
else
{
debug_printf("skipped present!\n");
}
// Debug
m_performanceMonitor.ResetPerFrameData();
} }
void MetalRenderer::EnsureImGuiBackend() void MetalRenderer::EnsureImGuiBackend()

View File

@ -204,6 +204,7 @@ public:
} }
void InitializeLayer(const Vector2i& size, bool mainWindow); void InitializeLayer(const Vector2i& size, bool mainWindow);
void ShutdownLayer(bool mainWindow);
void ResizeLayer(const Vector2i& size, bool mainWindow); void ResizeLayer(const Vector2i& size, bool mainWindow);
void Initialize() override; void Initialize() override;

View File

@ -39,13 +39,9 @@ MetalCanvas::~MetalCanvas()
Unbind(wxEVT_PAINT, &MetalCanvas::OnPaint, this); Unbind(wxEVT_PAINT, &MetalCanvas::OnPaint, this);
Unbind(wxEVT_SIZE, &MetalCanvas::OnResize, this); Unbind(wxEVT_SIZE, &MetalCanvas::OnResize, this);
if(!m_is_main_window) MetalRenderer* mtlr = (MetalRenderer*)g_renderer.get();
{ if (mtlr)
// TODO mtlr->ShutdownLayer(m_is_main_window);
//MetalRenderer* vkr = (MetalRenderer*)g_renderer.get();
//if(vkr)
// vkr->StopUsingPadAndWait();
}
} }
void MetalCanvas::OnPaint(wxPaintEvent& event) void MetalCanvas::OnPaint(wxPaintEvent& event)
@ -62,5 +58,5 @@ void MetalCanvas::OnResize(wxSizeEvent& event)
RefreshRect(refreshRect, false); RefreshRect(refreshRect, false);
auto metal_renderer = MetalRenderer::GetInstance(); 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);
} }