implement blending

This commit is contained in:
Samuliak 2024-08-01 20:45:24 +02:00
parent d4564c18f2
commit e4abb305ac
4 changed files with 97 additions and 8 deletions

View File

@ -1,6 +1,7 @@
#include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h"
#include "Common/precompiled.h" #include "Common/precompiled.h"
#include "Metal/MTLPixelFormat.hpp" #include "Metal/MTLPixelFormat.hpp"
#include "Metal/MTLRenderPipeline.hpp"
#include "Metal/MTLVertexDescriptor.hpp" #include "Metal/MTLVertexDescriptor.hpp"
std::map<Latte::E_GX2SURFFMT, MtlPixelFormatInfo> MTL_COLOR_FORMAT_TABLE = { std::map<Latte::E_GX2SURFFMT, MtlPixelFormatInfo> MTL_COLOR_FORMAT_TABLE = {
@ -134,7 +135,6 @@ MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode)
return MTL::PrimitiveTypeTriangleStrip; return MTL::PrimitiveTypeTriangleStrip;
default: default:
printf("unimplemented primitive type %u\n", (uint32)mode); printf("unimplemented primitive type %u\n", (uint32)mode);
cemu_assert_debug(false);
return MTL::PrimitiveTypeTriangle; return MTL::PrimitiveTypeTriangle;
} }
} }
@ -201,8 +201,58 @@ MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType)
case Renderer::INDEX_TYPE::U32: case Renderer::INDEX_TYPE::U32:
return MTL::IndexTypeUInt32; return MTL::IndexTypeUInt32;
default: default:
printf("unsupported index type %u\n", (uint32)indexType); cemu_assert_suspicious();
assert_dbg();
return MTL::IndexTypeUInt32; return MTL::IndexTypeUInt32;
} }
} }
MTL::BlendOperation GetMtlBlendOp(Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC combineFunc)
{
switch (combineFunc)
{
case Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC::DST_PLUS_SRC:
return MTL::BlendOperationAdd;
case Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC::SRC_MINUS_DST:
return MTL::BlendOperationSubtract;
case Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC::MIN_DST_SRC:
return MTL::BlendOperationMin;
case Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC::MAX_DST_SRC:
return MTL::BlendOperationMax;
case Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC::DST_MINUS_SRC:
return MTL::BlendOperationReverseSubtract;
default:
cemu_assert_suspicious();
return MTL::BlendOperationAdd;
}
}
const MTL::BlendFactor MTL_BLEND_FACTORS[] =
{
/* 0x00 */ MTL::BlendFactorZero,
/* 0x01 */ MTL::BlendFactorOne,
/* 0x02 */ MTL::BlendFactorSourceColor,
/* 0x03 */ MTL::BlendFactorOneMinusSourceColor,
/* 0x04 */ MTL::BlendFactorSourceAlpha,
/* 0x05 */ MTL::BlendFactorOneMinusSourceAlpha,
/* 0x06 */ MTL::BlendFactorDestinationAlpha,
/* 0x07 */ MTL::BlendFactorOneMinusDestinationAlpha,
/* 0x08 */ MTL::BlendFactorDestinationColor,
/* 0x09 */ MTL::BlendFactorOneMinusDestinationColor,
/* 0x0A */ MTL::BlendFactorSourceAlphaSaturated,
/* 0x0B */ MTL::BlendFactorZero, // TODO
/* 0x0C */ MTL::BlendFactorZero, // TODO
/* 0x0D */ MTL::BlendFactorBlendColor,
/* 0x0E */ MTL::BlendFactorOneMinusBlendColor,
/* 0x0F */ MTL::BlendFactorSource1Color,
/* 0x10 */ MTL::BlendFactorOneMinusSource1Color,
/* 0x11 */ MTL::BlendFactorSource1Alpha,
/* 0x12 */ MTL::BlendFactorOneMinusSource1Alpha,
/* 0x13 */ MTL::BlendFactorBlendAlpha,
/* 0x14 */ MTL::BlendFactorOneMinusBlendAlpha
};
MTL::BlendFactor GetMtlBlendFactor(Latte::LATTE_CB_BLENDN_CONTROL::E_BLENDFACTOR factor)
{
cemu_assert_debug((uint32)factor < std::size(MTL_BLEND_FACTORS));
return MTL_BLEND_FACTORS[(uint32)factor];
}

View File

@ -6,6 +6,7 @@
#include "Cafe/HW/Latte/Core/LatteConst.h" #include "Cafe/HW/Latte/Core/LatteConst.h"
//#include "Cafe/HW/Latte/Core/FetchShader.h" //#include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/HW/Latte/Renderer/Renderer.h" #include "Cafe/HW/Latte/Renderer/Renderer.h"
#include "Metal/MTLRenderPipeline.hpp"
struct Uvec2 { struct Uvec2 {
uint32 x; uint32 x;
@ -29,3 +30,7 @@ MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode);
MTL::VertexFormat GetMtlVertexFormat(uint8 format); MTL::VertexFormat GetMtlVertexFormat(uint8 format);
MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType); MTL::IndexType GetMtlIndexType(Renderer::INDEX_TYPE indexType);
MTL::BlendOperation GetMtlBlendOp(Latte::LATTE_CB_BLENDN_CONTROL::E_COMBINEFUNC combineFunc);
MTL::BlendFactor GetMtlBlendFactor(Latte::LATTE_CB_BLENDN_CONTROL::E_BLENDFACTOR factor);

View File

@ -560,7 +560,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
LatteSHRC_UpdateActiveShaders(); LatteSHRC_UpdateActiveShaders();
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader(); LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader(); LatteDecompilerShader* pixelShader = LatteSHRC_GetActivePixelShader();
if (!vertexShader) if (!vertexShader || !static_cast<RendererShaderMtl*>(vertexShader->shader)->GetFunction())
{ {
printf("no vertex function, skipping draw\n"); printf("no vertex function, skipping draw\n");
return; return;
@ -631,7 +631,42 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
{ {
continue; continue;
} }
renderPipelineDescriptor->colorAttachments()->object(i)->setPixelFormat(texture->GetTexture()->pixelFormat()); auto colorAttachment = renderPipelineDescriptor->colorAttachments()->object(i);
colorAttachment->setPixelFormat(texture->GetTexture()->pixelFormat());
// Blending
const Latte::LATTE_CB_COLOR_CONTROL& colorControlReg = LatteGPUState.contextNew.CB_COLOR_CONTROL;
uint32 blendEnableMask = colorControlReg.get_BLEND_MASK();
uint32 renderTargetMask = LatteGPUState.contextNew.CB_TARGET_MASK.get_MASK();
bool blendEnabled = ((blendEnableMask & (1 << i))) != 0;
if (blendEnabled)
{
colorAttachment->setBlendingEnabled(true);
const auto& blendControlReg = LatteGPUState.contextNew.CB_BLENDN_CONTROL[i];
auto rgbBlendOp = GetMtlBlendOp(blendControlReg.get_COLOR_COMB_FCN());
auto srcRgbBlendFactor = GetMtlBlendFactor(blendControlReg.get_COLOR_SRCBLEND());
auto dstRgbBlendFactor = GetMtlBlendFactor(blendControlReg.get_COLOR_DSTBLEND());
colorAttachment->setWriteMask((renderTargetMask >> (i * 4)) & 0xF);
colorAttachment->setRgbBlendOperation(rgbBlendOp);
colorAttachment->setSourceRGBBlendFactor(srcRgbBlendFactor);
colorAttachment->setDestinationRGBBlendFactor(dstRgbBlendFactor);
if (blendControlReg.get_SEPARATE_ALPHA_BLEND())
{
colorAttachment->setAlphaBlendOperation(GetMtlBlendOp(blendControlReg.get_ALPHA_COMB_FCN()));
colorAttachment->setSourceAlphaBlendFactor(GetMtlBlendFactor(blendControlReg.get_ALPHA_SRCBLEND()));
colorAttachment->setDestinationAlphaBlendFactor(GetMtlBlendFactor(blendControlReg.get_ALPHA_DSTBLEND()));
}
else
{
colorAttachment->setAlphaBlendOperation(rgbBlendOp);
colorAttachment->setSourceAlphaBlendFactor(srcRgbBlendFactor);
colorAttachment->setDestinationAlphaBlendFactor(dstRgbBlendFactor);
}
}
} }
if (m_state.activeFBO->depthBuffer.texture) if (m_state.activeFBO->depthBuffer.texture)
{ {

View File

@ -368,7 +368,8 @@ void CemuApp::OnAssertFailure(const wxChar* file, int line, const wxChar* func,
#if BOOST_OS_WINDOWS #if BOOST_OS_WINDOWS
DumpThreadStackTrace(); DumpThreadStackTrace();
#endif #endif
cemu_assert_debug(false); // HACK
//cemu_assert_debug(false);
} }
int CemuApp::FilterEvent(wxEvent& event) int CemuApp::FilterEvent(wxEvent& event)
@ -545,5 +546,3 @@ void CemuApp::ActivateApp(wxActivateEvent& event)
g_window_info.app_active = event.GetActive(); g_window_info.app_active = event.GetActive();
event.Skip(); event.Skip();
} }