initialize Metal

This commit is contained in:
Samuliak 2024-07-25 12:53:24 +02:00
parent 2477bad06b
commit 98370260d3
10 changed files with 220 additions and 26 deletions

3
.gitmodules vendored
View File

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

View File

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

@ -0,0 +1 @@
Subproject commit a63bd172ddcba73a3d87ca32032b66ad41ddb9a6

View File

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

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

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

View 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>

View File

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

View File

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

View File

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