start metal backend

This commit is contained in:
Samuliak 2024-07-25 11:18:35 +02:00
parent 4b9c7c0d30
commit 2477bad06b
19 changed files with 586 additions and 129 deletions

View file

@ -0,0 +1,198 @@
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) {
/*
const auto& windowInfo = gui_getWindowInfo().window_main;
NSView* view = (NS::View*)handle;
MetalView* childView = [[MetalView alloc] initWithFrame:view.bounds];
childView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
childView.wantsLayer = YES;
[view addSubview:childView];
VkMetalSurfaceCreateInfoEXT surface;
surface.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
surface.pNext = NULL;
surface.flags = 0;
surface.pLayer = (CAMetalLayer*)childView.layer;
*/
}
void MetalRenderer::Initialize() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::Shutdown() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
bool MetalRenderer::IsPadWindowActive() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::ClearColorbuffer(bool padView) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::DrawEmptyFrame(bool mainWindow) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight,
bool padView, bool clearBackground) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
bool MetalRenderer::BeginFrame(bool mainWindow) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::Flush(bool waitIdle) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::NotifyLatteCommandProcessorIdle() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::AppendOverlayDebugInfo() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::renderTarget_setViewport(float x, float y, float width, float height, float nearZ, float farZ, bool halfZ) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::renderTarget_setScissor(sint32 scissorX, sint32 scissorY, sint32 scissorWidth, sint32 scissorHeight) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
LatteCachedFBO* MetalRenderer::rendertarget_createCachedFBO(uint64 key) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::rendertarget_deleteCachedFBO(LatteCachedFBO* fbo) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void* MetalRenderer::texture_acquireTextureUploadBuffer(uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_releaseTextureUploadBuffer(uint8* mem) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
TextureDecoder* MetalRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
LatteTexture* MetalRenderer::texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY, sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
LatteTextureReadbackInfo* MetalRenderer::texture_createReadback(LatteTextureView* textureView) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* sourceTexture, sint32 srcMip, sint32 srcSlice, LatteTexture* destinationTexture, sint32 dstMip, sint32 dstSlice, sint32 width, sint32 height) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::bufferCache_init(const sint32 bufferSize) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::bufferCache_upload(uint8* buffer, sint32 size, uint32 bufferOffset) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
RendererShader* MetalRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool compileAsync, bool isGfxPackSource) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::streamout_begin() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::streamout_rendererFinishDrawcall() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::draw_beginSequence() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::draw_endSequence() {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) {
cemuLog_logDebug(LogType::Force, "not implemented");
}
void MetalRenderer::indexData_uploadIndexMemory(uint32 offset, uint32 size) {
cemuLog_logDebug(LogType::Force, "not implemented");
}

View file

@ -0,0 +1,142 @@
#pragma once
#include "Cafe/HW/Latte/Renderer/Renderer.h"
class MetalRenderer : public Renderer
{
public:
~MetalRenderer() = default;
RendererAPI GetType() override
{
return RendererAPI::Metal;
}
static MetalRenderer* GetInstance() {
return static_cast<MetalRenderer*>(g_renderer.get());
}
void InitializeLayer(const Vector2i& size, bool mainWindow);
void Initialize() override;
void Shutdown() override;
bool IsPadWindowActive() override;
bool GetVRAMInfo(int& usageInMB, int& totalInMB) const override;
void ClearColorbuffer(bool padView) override;
void DrawEmptyFrame(bool mainWindow) override;
void SwapBuffers(bool swapTV, bool swapDRC) override;
void HandleScreenshotRequest(LatteTextureView* texView, bool padView) override {
cemuLog_logDebug(LogType::Force, "Screenshots are not yet supported on Metal");
}
void DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight,
bool padView, bool clearBackground) override;
bool BeginFrame(bool mainWindow) override;
// flush control
void Flush(bool waitIdle = false) override; // called when explicit flush is required (e.g. by imgui)
void NotifyLatteCommandProcessorIdle() override; // called when command processor has no more commands available or when stalled
// imgui
bool ImguiBegin(bool mainWindow) override {
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
};
void ImguiEnd() override {
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
};
ImTextureID GenerateTexture(const std::vector<uint8>& data, const Vector2i& size) override {
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
};
void DeleteTexture(ImTextureID id) override {
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
};
void DeleteFontTextures() override {
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
};
void AppendOverlayDebugInfo() override;
// rendertarget
void renderTarget_setViewport(float x, float y, float width, float height, float nearZ, float farZ, bool halfZ = false) override;
void renderTarget_setScissor(sint32 scissorX, sint32 scissorY, sint32 scissorWidth, sint32 scissorHeight) override;
LatteCachedFBO* rendertarget_createCachedFBO(uint64 key) override;
void rendertarget_deleteCachedFBO(LatteCachedFBO* fbo) override;
void rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) override;
// texture functions
void* texture_acquireTextureUploadBuffer(uint32 size) override;
void texture_releaseTextureUploadBuffer(uint8* mem) override;
TextureDecoder* texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) override;
void texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) override;
void texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize) override;
void texture_clearColorSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a) override;
void texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sliceIndex, sint32 mipIndex, bool clearDepth, bool clearStencil, float depthValue, uint32 stencilValue) override;
LatteTexture* texture_createTextureEx(Latte::E_DIM dim, MPTR physAddress, MPTR physMipAddress, Latte::E_GX2SURFFMT format, uint32 width, uint32 height, uint32 depth, uint32 pitch, uint32 mipLevels, uint32 swizzle, Latte::E_HWTILEMODE tileMode, bool isDepth) override;
void texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) override;
void texture_copyImageSubData(LatteTexture* src, sint32 srcMip, sint32 effectiveSrcX, sint32 effectiveSrcY, sint32 srcSlice, LatteTexture* dst, sint32 dstMip, sint32 effectiveDstX, sint32 effectiveDstY, sint32 dstSlice, sint32 effectiveCopyWidth, sint32 effectiveCopyHeight, sint32 srcDepth) override;
LatteTextureReadbackInfo* texture_createReadback(LatteTextureView* textureView) override;
// surface copy
void surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* sourceTexture, sint32 srcMip, sint32 srcSlice, LatteTexture* destinationTexture, sint32 dstMip, sint32 dstSlice, sint32 width, sint32 height) override;
// buffer cache
void bufferCache_init(const sint32 bufferSize) override;
void bufferCache_upload(uint8* buffer, sint32 size, uint32 bufferOffset) override;
void bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32 size) override;
void bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size) override;
void buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size) override;
void buffer_bindUniformBuffer(LatteConst::ShaderType shaderType, uint32 bufferIndex, uint32 offset, uint32 size) override;
// shader
RendererShader* shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool compileAsync, bool isGfxPackSource) override;
// streamout
void streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) override;
void streamout_begin() override;
void streamout_rendererFinishDrawcall() override;
// core drawing logic
void draw_beginSequence() override;
void draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 instanceCount, uint32 count, MPTR indexDataMPTR, Latte::LATTE_VGT_DMA_INDEX_TYPE::E_INDEX_TYPE indexType, bool isFirst) override;
void draw_endSequence() override;
// index
void* indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) override;
void indexData_uploadIndexMemory(uint32 offset, uint32 size) override;
// occlusion queries
LatteQueryObject* occlusionQuery_create() override {
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
}
void occlusionQuery_destroy(LatteQueryObject* queryObj) override {
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
}
void occlusionQuery_flush() override {
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
}
void occlusionQuery_updateState() override {
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
}
protected:
//CA::MetalLayer* m_metalLayer;
};

View file

@ -33,6 +33,7 @@ enum class RendererAPI
{
OpenGL,
Vulkan,
Metal,
MAX
};
@ -66,9 +67,9 @@ public:
virtual void SwapBuffers(bool swapTV, bool swapDRC) = 0;
virtual void HandleScreenshotRequest(LatteTextureView* texView, bool padView){}
virtual void DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight,
virtual void DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight,
bool padView, bool clearBackground) = 0;
virtual bool BeginFrame(bool mainWindow) = 0;