mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 21:44:17 +01:00
initialize Metal
This commit is contained in:
parent
2477bad06b
commit
98370260d3
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -16,3 +16,6 @@
|
|||||||
[submodule "dependencies/imgui"]
|
[submodule "dependencies/imgui"]
|
||||||
path = dependencies/imgui
|
path = dependencies/imgui
|
||||||
url = https://github.com/ocornut/imgui
|
url = https://github.com/ocornut/imgui
|
||||||
|
[submodule "dependencies/metal-cpp"]
|
||||||
|
path = dependencies/metal-cpp
|
||||||
|
url = https://github.com/bkaradzic/metal-cpp.git
|
||||||
|
@ -166,6 +166,11 @@ if (ENABLE_OPENGL)
|
|||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# TODO: handle this differently?
|
||||||
|
if (ENABLE_METAL AND APPLE)
|
||||||
|
include_directories(${CMAKE_SOURCE_DIR}/dependencies/metal-cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ENABLE_DISCORD_RPC)
|
if (ENABLE_DISCORD_RPC)
|
||||||
add_compile_definitions(ENABLE_DISCORD_RPC)
|
add_compile_definitions(ENABLE_DISCORD_RPC)
|
||||||
add_subdirectory(dependencies/discord-rpc EXCLUDE_FROM_ALL)
|
add_subdirectory(dependencies/discord-rpc EXCLUDE_FROM_ALL)
|
||||||
|
1
dependencies/metal-cpp
vendored
Submodule
1
dependencies/metal-cpp
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a63bd172ddcba73a3d87ca32032b66ad41ddb9a6
|
@ -528,7 +528,16 @@ if(ENABLE_METAL)
|
|||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_sources(CemuCafe PRIVATE
|
target_sources(CemuCafe PRIVATE
|
||||||
HW/Latte/Renderer/Metal/MetalRenderer.cpp
|
HW/Latte/Renderer/Metal/MetalRenderer.cpp
|
||||||
|
HW/Latte/Renderer/Metal/MetalRenderer.h
|
||||||
|
HW/Latte/Renderer/Metal/MetalCppImpl.cpp
|
||||||
|
HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
|
||||||
|
HW/Latte/Renderer/Metal/LatteTextureMtl.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#target_link_libraries(CemuCafe PRIVATE
|
||||||
|
# "-framework Metal"
|
||||||
|
# "-framework QuartzCore"
|
||||||
|
#)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Metal is only supported on macOS")
|
message(FATAL_ERROR "Metal is only supported on macOS")
|
||||||
endif()
|
endif()
|
||||||
|
92
src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
Normal file
92
src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
|
||||||
|
//#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
|
||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||||
|
|
||||||
|
LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, 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)
|
||||||
|
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_mtlr(mtlRenderer)
|
||||||
|
{
|
||||||
|
MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
||||||
|
sint32 effectiveBaseWidth = width;
|
||||||
|
sint32 effectiveBaseHeight = height;
|
||||||
|
sint32 effectiveBaseDepth = depth;
|
||||||
|
if (overwriteInfo.hasResolutionOverwrite)
|
||||||
|
{
|
||||||
|
effectiveBaseWidth = overwriteInfo.width;
|
||||||
|
effectiveBaseHeight = overwriteInfo.height;
|
||||||
|
effectiveBaseDepth = overwriteInfo.depth;
|
||||||
|
}
|
||||||
|
effectiveBaseDepth = std::max(1, effectiveBaseDepth);
|
||||||
|
|
||||||
|
desc->setWidth(effectiveBaseWidth);
|
||||||
|
desc->setHeight(effectiveBaseHeight);
|
||||||
|
desc->setMipmapLevelCount(mipLevels);
|
||||||
|
|
||||||
|
if (dim == Latte::E_DIM::DIM_3D)
|
||||||
|
{
|
||||||
|
desc->setDepth(effectiveBaseDepth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desc->setArrayLength(effectiveBaseDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: uncomment
|
||||||
|
//MetalRenderer::FormatInfoMTL texFormatInfo;
|
||||||
|
//mtlRenderer->GetTextureFormatInfoMTL(format, isDepth, dim, effectiveBaseWidth, effectiveBaseHeight, &texFormatInfo);
|
||||||
|
//cemu_assert_debug(hasStencil == ((texFormatInfo.vkImageAspect & VK_IMAGE_ASPECT_STENCIL_BIT) != 0));
|
||||||
|
//imageInfo.format = texFormatInfo.mtlPixelFormat;
|
||||||
|
desc->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
||||||
|
|
||||||
|
// TODO: is write needed?
|
||||||
|
MTL::TextureUsage usage = MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite;
|
||||||
|
// TODO: add more conditions
|
||||||
|
if (Latte::IsCompressedFormat(format) == false)
|
||||||
|
{
|
||||||
|
usage |= MTL::TextureUsageRenderTarget;
|
||||||
|
}
|
||||||
|
desc->setUsage(usage);
|
||||||
|
|
||||||
|
if (dim == Latte::E_DIM::DIM_2D)
|
||||||
|
desc->setTextureType(MTL::TextureType2D);
|
||||||
|
else if (dim == Latte::E_DIM::DIM_1D)
|
||||||
|
desc->setTextureType(MTL::TextureType1D);
|
||||||
|
else if (dim == Latte::E_DIM::DIM_3D)
|
||||||
|
desc->setTextureType(MTL::TextureType3D);
|
||||||
|
else if (dim == Latte::E_DIM::DIM_2D_ARRAY)
|
||||||
|
desc->setTextureType(MTL::TextureType2DArray);
|
||||||
|
else if (dim == Latte::E_DIM::DIM_CUBEMAP)
|
||||||
|
desc->setTextureType(MTL::TextureTypeCube); // TODO: is this correct?
|
||||||
|
else if (dim == Latte::E_DIM::DIM_2D_MSAA)
|
||||||
|
desc->setTextureType(MTL::TextureType2D);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cemu_assert_unimplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_texture = mtlRenderer->GetDevice()->newTexture(desc);
|
||||||
|
desc->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
LatteTextureMtl::~LatteTextureMtl()
|
||||||
|
{
|
||||||
|
m_texture->release();
|
||||||
|
}
|
||||||
|
|
||||||
|
LatteTextureView* LatteTextureMtl::CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
|
||||||
|
{
|
||||||
|
cemu_assert_debug(mipCount > 0);
|
||||||
|
cemu_assert_debug(sliceCount > 0);
|
||||||
|
cemu_assert_debug((firstMip + mipCount) <= this->mipLevels);
|
||||||
|
cemu_assert_debug((firstSlice + sliceCount) <= this->depth);
|
||||||
|
|
||||||
|
//return new LatteTextureViewMtl(m_mtlr, this, dim, format, firstMip, mipCount, firstSlice, sliceCount);
|
||||||
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LatteTextureMtl::AllocateOnHost()
|
||||||
|
{
|
||||||
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
}
|
33
src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h
Normal file
33
src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Metal/Metal.hpp>
|
||||||
|
|
||||||
|
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||||
|
#include "util/ChunkedHeap/ChunkedHeap.h"
|
||||||
|
|
||||||
|
class LatteTextureMtl : public LatteTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LatteTextureMtl(class MetalRenderer* vkRenderer, 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);
|
||||||
|
|
||||||
|
~LatteTextureMtl();
|
||||||
|
|
||||||
|
void AllocateOnHost() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LatteTextureView* CreateView(Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount) override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
uint64 m_vkFlushIndex{}; // used to track read-write dependencies within the same renderpass
|
||||||
|
|
||||||
|
uint64 m_vkFlushIndex_read{};
|
||||||
|
uint64 m_vkFlushIndex_write{};
|
||||||
|
|
||||||
|
uint32 m_collisionCheckIndex{}; // used to track if texture is being both sampled and output to during drawcall
|
||||||
|
|
||||||
|
private:
|
||||||
|
class MetalRenderer* m_mtlr;
|
||||||
|
|
||||||
|
MTL::Texture* m_texture;
|
||||||
|
};
|
6
src/Cafe/HW/Latte/Renderer/Metal/MetalCppImpl.cpp
Normal file
6
src/Cafe/HW/Latte/Renderer/Metal/MetalCppImpl.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#define NS_PRIVATE_IMPLEMENTATION
|
||||||
|
#define CA_PRIVATE_IMPLEMENTATION
|
||||||
|
#define MTL_PRIVATE_IMPLEMENTATION
|
||||||
|
#include <Foundation/Foundation.hpp>
|
||||||
|
#include <QuartzCore/QuartzCore.hpp>
|
||||||
|
#include <Metal/Metal.hpp>
|
@ -1,5 +1,7 @@
|
|||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||||
|
|
||||||
|
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.h"
|
||||||
|
|
||||||
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) {
|
void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) {
|
||||||
/*
|
/*
|
||||||
const auto& windowInfo = gui_getWindowInfo().window_main;
|
const auto& windowInfo = gui_getWindowInfo().window_main;
|
||||||
@ -21,7 +23,8 @@ void MetalRenderer::InitializeLayer(const Vector2i& size, bool mainWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::Initialize() {
|
void MetalRenderer::Initialize() {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
m_device = MTL::CreateSystemDefaultDevice();
|
||||||
|
m_commandQueue = m_device->newCommandQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::Shutdown() {
|
void MetalRenderer::Shutdown() {
|
||||||
@ -30,10 +33,17 @@ void MetalRenderer::Shutdown() {
|
|||||||
|
|
||||||
bool MetalRenderer::IsPadWindowActive() {
|
bool MetalRenderer::IsPadWindowActive() {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const {
|
bool MetalRenderer::GetVRAMInfo(int& usageInMB, int& totalInMB) const {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
usageInMB = 1024;
|
||||||
|
totalInMB = 1024;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::ClearColorbuffer(bool padView) {
|
void MetalRenderer::ClearColorbuffer(bool padView) {
|
||||||
@ -55,6 +65,8 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
|||||||
}
|
}
|
||||||
bool MetalRenderer::BeginFrame(bool mainWindow) {
|
bool MetalRenderer::BeginFrame(bool mainWindow) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::Flush(bool waitIdle) {
|
void MetalRenderer::Flush(bool waitIdle) {
|
||||||
@ -79,6 +91,8 @@ void MetalRenderer::renderTarget_setScissor(sint32 scissorX, sint32 scissorY, si
|
|||||||
|
|
||||||
LatteCachedFBO* MetalRenderer::rendertarget_createCachedFBO(uint64 key) {
|
LatteCachedFBO* MetalRenderer::rendertarget_createCachedFBO(uint64 key) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::rendertarget_deleteCachedFBO(LatteCachedFBO* fbo) {
|
void MetalRenderer::rendertarget_deleteCachedFBO(LatteCachedFBO* fbo) {
|
||||||
@ -91,6 +105,8 @@ void MetalRenderer::rendertarget_bindFramebufferObject(LatteCachedFBO* cfbo) {
|
|||||||
|
|
||||||
void* MetalRenderer::texture_acquireTextureUploadBuffer(uint32 size) {
|
void* MetalRenderer::texture_acquireTextureUploadBuffer(uint32 size) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::texture_releaseTextureUploadBuffer(uint8* mem) {
|
void MetalRenderer::texture_releaseTextureUploadBuffer(uint8* mem) {
|
||||||
@ -99,6 +115,8 @@ void MetalRenderer::texture_releaseTextureUploadBuffer(uint8* mem) {
|
|||||||
|
|
||||||
TextureDecoder* MetalRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) {
|
TextureDecoder* MetalRenderer::texture_chooseDecodedFormat(Latte::E_GX2SURFFMT format, bool isDepth, Latte::E_DIM dim, uint32 width, uint32 height) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) {
|
void MetalRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex) {
|
||||||
@ -118,7 +136,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
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");
|
return new LatteTextureMtl(this, dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) {
|
void MetalRenderer::texture_setLatteTexture(LatteTextureView* textureView, uint32 textureUnit) {
|
||||||
@ -131,6 +149,8 @@ void MetalRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, s
|
|||||||
|
|
||||||
LatteTextureReadbackInfo* MetalRenderer::texture_createReadback(LatteTextureView* textureView) {
|
LatteTextureReadbackInfo* MetalRenderer::texture_createReadback(LatteTextureView* textureView) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* sourceTexture, sint32 srcMip, sint32 srcSlice, LatteTexture* destinationTexture, sint32 dstMip, sint32 dstSlice, sint32 width, sint32 height) {
|
void MetalRenderer::surfaceCopy_copySurfaceWithFormatConversion(LatteTexture* sourceTexture, sint32 srcMip, sint32 srcSlice, LatteTexture* destinationTexture, sint32 dstMip, sint32 dstSlice, sint32 width, sint32 height) {
|
||||||
@ -163,6 +183,8 @@ void MetalRenderer::buffer_bindUniformBuffer(LatteConst::ShaderType shaderType,
|
|||||||
|
|
||||||
RendererShader* MetalRenderer::shader_create(RendererShader::ShaderType type, uint64 baseHash, uint64 auxHash, const std::string& source, bool compileAsync, bool isGfxPackSource) {
|
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");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) {
|
void MetalRenderer::streamout_setupXfbBuffer(uint32 bufferIndex, sint32 ringBufferOffset, uint32 rangeAddr, uint32 rangeSize) {
|
||||||
@ -191,6 +213,8 @@ void MetalRenderer::draw_endSequence() {
|
|||||||
|
|
||||||
void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) {
|
void* MetalRenderer::indexData_reserveIndexMemory(uint32 size, uint32& offset, uint32& bufferIndex) {
|
||||||
cemuLog_logDebug(LogType::Force, "not implemented");
|
cemuLog_logDebug(LogType::Force, "not implemented");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalRenderer::indexData_uploadIndexMemory(uint32 offset, uint32 size) {
|
void MetalRenderer::indexData_uploadIndexMemory(uint32 offset, uint32 size) {
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#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"
|
||||||
|
|
||||||
class MetalRenderer : public Renderer
|
class MetalRenderer : public Renderer
|
||||||
@ -16,6 +20,11 @@ public:
|
|||||||
return static_cast<MetalRenderer*>(g_renderer.get());
|
return static_cast<MetalRenderer*>(g_renderer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
MTL::Device* GetDevice() const {
|
||||||
|
return m_device;
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeLayer(const Vector2i& size, bool mainWindow);
|
void InitializeLayer(const Vector2i& size, bool mainWindow);
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
@ -44,6 +53,8 @@ public:
|
|||||||
// imgui
|
// imgui
|
||||||
bool ImguiBegin(bool mainWindow) override {
|
bool ImguiBegin(bool mainWindow) override {
|
||||||
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
|
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
|
||||||
|
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ImguiEnd() override {
|
void ImguiEnd() override {
|
||||||
@ -52,6 +63,8 @@ public:
|
|||||||
|
|
||||||
ImTextureID GenerateTexture(const std::vector<uint8>& data, const Vector2i& size) override {
|
ImTextureID GenerateTexture(const std::vector<uint8>& data, const Vector2i& size) override {
|
||||||
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
|
cemuLog_logDebug(LogType::Force, "Imgui is not yet supported on Metal");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DeleteTexture(ImTextureID id) override {
|
void DeleteTexture(ImTextureID id) override {
|
||||||
@ -122,6 +135,8 @@ public:
|
|||||||
// occlusion queries
|
// occlusion queries
|
||||||
LatteQueryObject* occlusionQuery_create() override {
|
LatteQueryObject* occlusionQuery_create() override {
|
||||||
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
|
cemuLog_logDebug(LogType::Force, "Occlusion queries are not yet supported on Metal");
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void occlusionQuery_destroy(LatteQueryObject* queryObj) override {
|
void occlusionQuery_destroy(LatteQueryObject* queryObj) override {
|
||||||
@ -137,6 +152,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
//CA::MetalLayer* m_metalLayer;
|
CA::MetalLayer* m_metalLayer;
|
||||||
|
|
||||||
|
// Metal objects
|
||||||
|
MTL::Device* m_device;
|
||||||
|
MTL::CommandQueue* m_commandQueue;
|
||||||
};
|
};
|
||||||
|
@ -83,7 +83,7 @@ void main(){
|
|||||||
const std::string RendererOutputShader::s_hermite_shader_source =
|
const std::string RendererOutputShader::s_hermite_shader_source =
|
||||||
R"(#version 420
|
R"(#version 420
|
||||||
|
|
||||||
in vec4 gl_FragCoord;
|
in vec4 gl_FragCoord;
|
||||||
in vec2 passUV;
|
in vec2 passUV;
|
||||||
layout(binding=0) uniform sampler2D textureSrc;
|
layout(binding=0) uniform sampler2D textureSrc;
|
||||||
uniform vec2 textureSrcResolution;
|
uniform vec2 textureSrcResolution;
|
||||||
@ -100,7 +100,7 @@ vec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)
|
|||||||
vec3 b = A - (5.0*B)/2.0 + 2.0*C - D / 2.0;
|
vec3 b = A - (5.0*B)/2.0 + 2.0*C - D / 2.0;
|
||||||
vec3 c = -A/2.0 + C/2.0;
|
vec3 c = -A/2.0 + C/2.0;
|
||||||
vec3 d = B;
|
vec3 d = B;
|
||||||
|
|
||||||
return a*t3 + b*t2 + c*t + d;
|
return a*t3 + b*t2 + c*t + d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,36 +108,36 @@ vec3 CubicHermite (vec3 A, vec3 B, vec3 C, vec3 D, float t)
|
|||||||
vec3 BicubicHermiteTexture(vec2 uv, vec4 texelSize)
|
vec3 BicubicHermiteTexture(vec2 uv, vec4 texelSize)
|
||||||
{
|
{
|
||||||
vec2 pixel = uv*texelSize.zw + 0.5;
|
vec2 pixel = uv*texelSize.zw + 0.5;
|
||||||
vec2 frac = fract(pixel);
|
vec2 frac = fract(pixel);
|
||||||
pixel = floor(pixel) / texelSize.zw - vec2(texelSize.xy/2.0);
|
pixel = floor(pixel) / texelSize.zw - vec2(texelSize.xy/2.0);
|
||||||
|
|
||||||
vec4 doubleSize = texelSize*texelSize;
|
vec4 doubleSize = texelSize*texelSize;
|
||||||
|
|
||||||
vec3 C00 = texture(textureSrc, pixel + vec2(-texelSize.x ,-texelSize.y)).rgb;
|
vec3 C00 = texture(textureSrc, pixel + vec2(-texelSize.x ,-texelSize.y)).rgb;
|
||||||
vec3 C10 = texture(textureSrc, pixel + vec2( 0.0 ,-texelSize.y)).rgb;
|
vec3 C10 = texture(textureSrc, pixel + vec2( 0.0 ,-texelSize.y)).rgb;
|
||||||
vec3 C20 = texture(textureSrc, pixel + vec2( texelSize.x ,-texelSize.y)).rgb;
|
vec3 C20 = texture(textureSrc, pixel + vec2( texelSize.x ,-texelSize.y)).rgb;
|
||||||
vec3 C30 = texture(textureSrc, pixel + vec2( doubleSize.x,-texelSize.y)).rgb;
|
vec3 C30 = texture(textureSrc, pixel + vec2( doubleSize.x,-texelSize.y)).rgb;
|
||||||
|
|
||||||
vec3 C01 = texture(textureSrc, pixel + vec2(-texelSize.x , 0.0)).rgb;
|
vec3 C01 = texture(textureSrc, pixel + vec2(-texelSize.x , 0.0)).rgb;
|
||||||
vec3 C11 = texture(textureSrc, pixel + vec2( 0.0 , 0.0)).rgb;
|
vec3 C11 = texture(textureSrc, pixel + vec2( 0.0 , 0.0)).rgb;
|
||||||
vec3 C21 = texture(textureSrc, pixel + vec2( texelSize.x , 0.0)).rgb;
|
vec3 C21 = texture(textureSrc, pixel + vec2( texelSize.x , 0.0)).rgb;
|
||||||
vec3 C31 = texture(textureSrc, pixel + vec2( doubleSize.x, 0.0)).rgb;
|
vec3 C31 = texture(textureSrc, pixel + vec2( doubleSize.x, 0.0)).rgb;
|
||||||
|
|
||||||
vec3 C02 = texture(textureSrc, pixel + vec2(-texelSize.x , texelSize.y)).rgb;
|
vec3 C02 = texture(textureSrc, pixel + vec2(-texelSize.x , texelSize.y)).rgb;
|
||||||
vec3 C12 = texture(textureSrc, pixel + vec2( 0.0 , texelSize.y)).rgb;
|
vec3 C12 = texture(textureSrc, pixel + vec2( 0.0 , texelSize.y)).rgb;
|
||||||
vec3 C22 = texture(textureSrc, pixel + vec2( texelSize.x , texelSize.y)).rgb;
|
vec3 C22 = texture(textureSrc, pixel + vec2( texelSize.x , texelSize.y)).rgb;
|
||||||
vec3 C32 = texture(textureSrc, pixel + vec2( doubleSize.x, texelSize.y)).rgb;
|
vec3 C32 = texture(textureSrc, pixel + vec2( doubleSize.x, texelSize.y)).rgb;
|
||||||
|
|
||||||
vec3 C03 = texture(textureSrc, pixel + vec2(-texelSize.x , doubleSize.y)).rgb;
|
vec3 C03 = texture(textureSrc, pixel + vec2(-texelSize.x , doubleSize.y)).rgb;
|
||||||
vec3 C13 = texture(textureSrc, pixel + vec2( 0.0 , doubleSize.y)).rgb;
|
vec3 C13 = texture(textureSrc, pixel + vec2( 0.0 , doubleSize.y)).rgb;
|
||||||
vec3 C23 = texture(textureSrc, pixel + vec2( texelSize.x , doubleSize.y)).rgb;
|
vec3 C23 = texture(textureSrc, pixel + vec2( texelSize.x , doubleSize.y)).rgb;
|
||||||
vec3 C33 = texture(textureSrc, pixel + vec2( doubleSize.x, doubleSize.y)).rgb;
|
vec3 C33 = texture(textureSrc, pixel + vec2( doubleSize.x, doubleSize.y)).rgb;
|
||||||
|
|
||||||
vec3 CP0X = CubicHermite(C00, C10, C20, C30, frac.x);
|
vec3 CP0X = CubicHermite(C00, C10, C20, C30, frac.x);
|
||||||
vec3 CP1X = CubicHermite(C01, C11, C21, C31, frac.x);
|
vec3 CP1X = CubicHermite(C01, C11, C21, C31, frac.x);
|
||||||
vec3 CP2X = CubicHermite(C02, C12, C22, C32, frac.x);
|
vec3 CP2X = CubicHermite(C02, C12, C22, C32, frac.x);
|
||||||
vec3 CP3X = CubicHermite(C03, C13, C23, C33, frac.x);
|
vec3 CP3X = CubicHermite(C03, C13, C23, C33, frac.x);
|
||||||
|
|
||||||
return CubicHermite(CP0X, CP1X, CP2X, CP3X, frac.y);
|
return CubicHermite(CP0X, CP1X, CP2X, CP3X, frac.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ void RendererOutputShader::SetUniformParameters(const LatteTextureView& texture_
|
|||||||
float res[2];
|
float res[2];
|
||||||
// vertex shader
|
// vertex shader
|
||||||
if (m_attributes[0].m_loc_texture_src_resolution != -1)
|
if (m_attributes[0].m_loc_texture_src_resolution != -1)
|
||||||
{
|
{
|
||||||
res[0] = (float)texture_view.baseTexture->width;
|
res[0] = (float)texture_view.baseTexture->width;
|
||||||
res[1] = (float)texture_view.baseTexture->height;
|
res[1] = (float)texture_view.baseTexture->height;
|
||||||
m_vertex_shader->SetUniform2fv(m_attributes[0].m_loc_texture_src_resolution, res, 1);
|
m_vertex_shader->SetUniform2fv(m_attributes[0].m_loc_texture_src_resolution, res, 1);
|
||||||
@ -250,9 +250,9 @@ std::string RendererOutputShader::GetOpenGlVertexSource(bool render_upside_down)
|
|||||||
R"(#version 400
|
R"(#version 400
|
||||||
out vec2 passUV;
|
out vec2 passUV;
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
{
|
{
|
||||||
vec4 gl_Position;
|
vec4 gl_Position;
|
||||||
};
|
};
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
@ -286,7 +286,7 @@ void main(){
|
|||||||
|
|
||||||
vertex_source <<
|
vertex_source <<
|
||||||
R"( passUV = vUV;
|
R"( passUV = vUV;
|
||||||
gl_Position = vec4(vPos, 0.0, 1.0);
|
gl_Position = vec4(vPos, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
return vertex_source.str();
|
return vertex_source.str();
|
||||||
@ -300,9 +300,9 @@ std::string RendererOutputShader::GetVulkanVertexSource(bool render_upside_down)
|
|||||||
R"(#version 450
|
R"(#version 450
|
||||||
layout(location = 0) out vec2 passUV;
|
layout(location = 0) out vec2 passUV;
|
||||||
|
|
||||||
out gl_PerVertex
|
out gl_PerVertex
|
||||||
{
|
{
|
||||||
vec4 gl_Position;
|
vec4 gl_Position;
|
||||||
};
|
};
|
||||||
|
|
||||||
void main(){
|
void main(){
|
||||||
@ -336,7 +336,7 @@ void main(){
|
|||||||
|
|
||||||
vertex_source <<
|
vertex_source <<
|
||||||
R"( passUV = vUV;
|
R"( passUV = vUV;
|
||||||
gl_Position = vec4(vPos, 0.0, 1.0);
|
gl_Position = vec4(vPos, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
return vertex_source.str();
|
return vertex_source.str();
|
||||||
@ -359,7 +359,7 @@ void RendererOutputShader::InitializeStatic()
|
|||||||
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
||||||
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);
|
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);
|
||||||
}
|
}
|
||||||
else
|
else if (g_renderer->GetType() == RendererAPI::Vulkan)
|
||||||
{
|
{
|
||||||
vertex_source = GetVulkanVertexSource(false);
|
vertex_source = GetVulkanVertexSource(false);
|
||||||
vertex_source_ud = GetVulkanVertexSource(true);
|
vertex_source_ud = GetVulkanVertexSource(true);
|
||||||
@ -372,5 +372,7 @@ void RendererOutputShader::InitializeStatic()
|
|||||||
|
|
||||||
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
s_hermit_shader = new RendererOutputShader(vertex_source, s_hermite_shader_source);
|
||||||
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);*/
|
s_hermit_shader_ud = new RendererOutputShader(vertex_source_ud, s_hermite_shader_source);*/
|
||||||
|
} else {
|
||||||
|
cemuLog_logDebug(LogType::Force, "Output shader not implemented for Metal");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user