mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-01-08 08:00:44 +01:00
rework the present system
This commit is contained in:
parent
6bb191212b
commit
d4a1074425
@ -542,6 +542,8 @@ if(ENABLE_METAL)
|
|||||||
HW/Latte/Renderer/Metal/MetalCppImpl.cpp
|
HW/Latte/Renderer/Metal/MetalCppImpl.cpp
|
||||||
HW/Latte/Renderer/Metal/MetalLayer.mm
|
HW/Latte/Renderer/Metal/MetalLayer.mm
|
||||||
HW/Latte/Renderer/Metal/MetalLayer.h
|
HW/Latte/Renderer/Metal/MetalLayer.h
|
||||||
|
HW/Latte/Renderer/Metal/MetalLayerHandle.cpp
|
||||||
|
HW/Latte/Renderer/Metal/MetalLayerHandle.h
|
||||||
HW/Latte/Renderer/Metal/LatteToMtl.cpp
|
HW/Latte/Renderer/Metal/LatteToMtl.cpp
|
||||||
HW/Latte/Renderer/Metal/LatteToMtl.h
|
HW/Latte/Renderer/Metal/LatteToMtl.h
|
||||||
HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
|
HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
|
||||||
|
45
src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp
Normal file
45
src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h"
|
||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalLayer.h"
|
||||||
|
|
||||||
|
#include "gui/guiWrapper.h"
|
||||||
|
|
||||||
|
MetalLayerHandle::MetalLayerHandle(MTL::Device* device, const Vector2i& size)
|
||||||
|
{
|
||||||
|
const auto& windowInfo = gui_getWindowInfo().window_main;
|
||||||
|
|
||||||
|
m_layer = (CA::MetalLayer*)CreateMetalLayer(windowInfo.handle, m_layerScaleX, m_layerScaleY);
|
||||||
|
m_layer->setDevice(device);
|
||||||
|
m_layer->setDrawableSize(CGSize{(float)size.x * m_layerScaleX, (float)size.y * m_layerScaleY});
|
||||||
|
}
|
||||||
|
|
||||||
|
MetalLayerHandle::~MetalLayerHandle()
|
||||||
|
{
|
||||||
|
if (m_layer)
|
||||||
|
m_layer->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetalLayerHandle::Resize(const Vector2i& size)
|
||||||
|
{
|
||||||
|
m_layer->setDrawableSize(CGSize{(float)size.x * m_layerScaleX, (float)size.y * m_layerScaleY});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MetalLayerHandle::AcquireDrawable()
|
||||||
|
{
|
||||||
|
if (m_drawable)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
m_drawable = m_layer->nextDrawable();
|
||||||
|
if (!m_drawable)
|
||||||
|
{
|
||||||
|
debug_printf("failed to acquire next drawable\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetalLayerHandle::PresentDrawable(MTL::CommandBuffer* commandBuffer)
|
||||||
|
{
|
||||||
|
commandBuffer->presentDrawable(m_drawable);
|
||||||
|
m_drawable = nullptr;
|
||||||
|
}
|
33
src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h
Normal file
33
src/Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QuartzCore/QuartzCore.hpp>
|
||||||
|
|
||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
|
||||||
|
#include "QuartzCore/CAMetalDrawable.hpp"
|
||||||
|
#include "QuartzCore/CAMetalLayer.hpp"
|
||||||
|
#include "util/math/vector2.h"
|
||||||
|
|
||||||
|
class MetalLayerHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MetalLayerHandle() = default;
|
||||||
|
MetalLayerHandle(MTL::Device* device, const Vector2i& size);
|
||||||
|
|
||||||
|
~MetalLayerHandle();
|
||||||
|
|
||||||
|
void Resize(const Vector2i& size);
|
||||||
|
|
||||||
|
bool AcquireDrawable();
|
||||||
|
|
||||||
|
void PresentDrawable(MTL::CommandBuffer* commandBuffer);
|
||||||
|
|
||||||
|
CA::MetalLayer* GetLayer() const { return m_layer; }
|
||||||
|
|
||||||
|
CA::MetalDrawable* GetDrawable() const { return m_drawable; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
CA::MetalLayer* m_layer = nullptr;
|
||||||
|
float m_layerScaleX, m_layerScaleY;
|
||||||
|
|
||||||
|
CA::MetalDrawable* m_drawable = nullptr;
|
||||||
|
};
|
@ -1,5 +1,4 @@
|
|||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalLayer.h"
|
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
|
||||||
@ -19,6 +18,7 @@
|
|||||||
#include "Cemu/Logging/CemuDebugLogging.h"
|
#include "Cemu/Logging/CemuDebugLogging.h"
|
||||||
#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 "gui/guiWrapper.h"
|
#include "gui/guiWrapper.h"
|
||||||
|
|
||||||
#define COMMIT_TRESHOLD 256
|
#define COMMIT_TRESHOLD 256
|
||||||
@ -174,20 +174,14 @@ MetalRenderer::~MetalRenderer()
|
|||||||
m_device->release();
|
m_device->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't ignore "mainWindow" argument
|
|
||||||
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow)
|
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow)
|
||||||
{
|
{
|
||||||
const auto& windowInfo = gui_getWindowInfo().window_main;
|
GetLayer(mainWindow) = MetalLayerHandle(m_device, size);
|
||||||
|
|
||||||
m_metalLayer = (CA::MetalLayer*)CreateMetalLayer(windowInfo.handle, m_layerScaleX, m_layerScaleY);
|
|
||||||
m_metalLayer->setDevice(m_device);
|
|
||||||
m_metalLayer->setDrawableSize(CGSize{(float)size.x * m_layerScaleX, (float)size.y * m_layerScaleY});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't ignore "mainWindow" argument
|
|
||||||
void MetalRenderer::ResizeLayer(const Vector2i& size, bool mainWindow)
|
void MetalRenderer::ResizeLayer(const Vector2i& size, bool mainWindow)
|
||||||
{
|
{
|
||||||
m_metalLayer->setDrawableSize(CGSize{(float)size.x * m_layerScaleX, (float)size.y * m_layerScaleY});
|
GetLayer(mainWindow).Resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::Initialize()
|
void MetalRenderer::Initialize()
|
||||||
@ -222,7 +216,7 @@ void MetalRenderer::ClearColorbuffer(bool padView)
|
|||||||
if (!AcquireNextDrawable(!padView))
|
if (!AcquireNextDrawable(!padView))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ClearColorTextureInternal(m_drawable->texture(), 0, 0, 0.0f, 0.0f, 0.0f, 0.0f);
|
ClearColorTextureInternal(GetLayer(!padView).GetDrawable()->texture(), 0, 0, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::DrawEmptyFrame(bool mainWindow)
|
void MetalRenderer::DrawEmptyFrame(bool mainWindow)
|
||||||
@ -234,17 +228,10 @@ void MetalRenderer::DrawEmptyFrame(bool mainWindow)
|
|||||||
|
|
||||||
void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
|
void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
|
||||||
{
|
{
|
||||||
|
if (swapTV)
|
||||||
if (m_drawable)
|
SwapBuffer(true);
|
||||||
{
|
if (swapDRC)
|
||||||
auto commandBuffer = GetCommandBuffer();
|
SwapBuffer(false);
|
||||||
commandBuffer->presentDrawable(m_drawable);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf("skipped present!\n");
|
|
||||||
}
|
|
||||||
m_drawable = nullptr;
|
|
||||||
|
|
||||||
// Release all the command buffers
|
// Release all the command buffers
|
||||||
CommitCommandBuffer();
|
CommitCommandBuffer();
|
||||||
@ -269,7 +256,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
|||||||
// Create render pass
|
// Create render pass
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
colorAttachment->setTexture(m_drawable->texture());
|
colorAttachment->setTexture(GetLayer(!padView).GetDrawable()->texture());
|
||||||
// TODO: shouldn't it be LoadActionLoad when not clearing?
|
// TODO: shouldn't it be LoadActionLoad when not clearing?
|
||||||
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
|
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
@ -1351,27 +1338,16 @@ void MetalRenderer::CommitCommandBuffer()
|
|||||||
|
|
||||||
bool MetalRenderer::AcquireNextDrawable(bool mainWindow)
|
bool MetalRenderer::AcquireNextDrawable(bool mainWindow)
|
||||||
{
|
{
|
||||||
|
auto& layer = GetLayer(mainWindow);
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
m_metalLayer->setPixelFormat(latteBufferUsesSRGB ? MTL::PixelFormatRGBA8Unorm_sRGB : MTL::PixelFormatRGBA8Unorm);
|
layer.GetLayer()->setPixelFormat(latteBufferUsesSRGB ? MTL::PixelFormatRGBA8Unorm_sRGB : MTL::PixelFormatRGBA8Unorm);
|
||||||
m_state.m_usesSRGB = latteBufferUsesSRGB;
|
m_state.m_usesSRGB = latteBufferUsesSRGB;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_drawable)
|
return layer.AcquireDrawable();
|
||||||
{
|
|
||||||
// TODO: should this be true?
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_drawable = m_metalLayer->nextDrawable();
|
|
||||||
if (!m_drawable)
|
|
||||||
{
|
|
||||||
debug_printf("failed to acquire next drawable\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalRenderer::CheckIfRenderPassNeedsFlush(LatteDecompilerShader* shader)
|
bool MetalRenderer::CheckIfRenderPassNeedsFlush(LatteDecompilerShader* shader)
|
||||||
@ -1639,3 +1615,20 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
|
|||||||
renderPassDescriptor->release();
|
renderPassDescriptor->release();
|
||||||
EndEncoding();
|
EndEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MetalRenderer::SwapBuffer(bool mainWindow)
|
||||||
|
{
|
||||||
|
auto& layer = GetLayer(mainWindow);
|
||||||
|
|
||||||
|
if (layer.GetDrawable())
|
||||||
|
{
|
||||||
|
auto commandBuffer = GetCommandBuffer();
|
||||||
|
layer.PresentDrawable(commandBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf("skipped present!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Foundation/Foundation.hpp>
|
|
||||||
#include <QuartzCore/QuartzCore.hpp>
|
|
||||||
#include <Metal/Metal.hpp>
|
|
||||||
|
|
||||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||||
|
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h"
|
||||||
#include "Metal/MTLResource.hpp"
|
|
||||||
#include "Metal/MTLSampler.hpp"
|
|
||||||
|
|
||||||
struct MetalBufferAllocation
|
struct MetalBufferAllocation
|
||||||
{
|
{
|
||||||
@ -428,8 +422,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CA::MetalLayer* m_metalLayer;
|
MetalLayerHandle m_mainLayer;
|
||||||
float m_layerScaleX, m_layerScaleY;
|
MetalLayerHandle m_padLayer;
|
||||||
|
|
||||||
// Metal objects
|
// Metal objects
|
||||||
MTL::Device* m_device;
|
MTL::Device* m_device;
|
||||||
@ -473,10 +467,16 @@ private:
|
|||||||
std::vector<MetalCommandBuffer> m_commandBuffers;
|
std::vector<MetalCommandBuffer> m_commandBuffers;
|
||||||
MetalEncoderType m_encoderType = MetalEncoderType::None;
|
MetalEncoderType m_encoderType = MetalEncoderType::None;
|
||||||
MTL::CommandEncoder* m_commandEncoder = nullptr;
|
MTL::CommandEncoder* m_commandEncoder = nullptr;
|
||||||
CA::MetalDrawable* m_drawable = nullptr;
|
|
||||||
|
|
||||||
uint32 m_recordedDrawcalls = 0;
|
uint32 m_recordedDrawcalls = 0;
|
||||||
|
|
||||||
// State
|
// State
|
||||||
MetalState m_state;
|
MetalState m_state;
|
||||||
|
|
||||||
|
MetalLayerHandle& GetLayer(bool mainWindow)
|
||||||
|
{
|
||||||
|
return (mainWindow ? m_mainLayer : m_padLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapBuffer(bool mainWindow);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user