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"
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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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 <cstddef>
#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();
GetLayer(mainWindow).PresentDrawable(commandBuffer);
}
void MetalRenderer::EnsureImGuiBackend()

View File

@ -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;

View File

@ -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);
}