Skip to content

Commit 6d34d24

Browse files
committed
fix: missing color attachments & bind some other state
1 parent a38ddb5 commit 6d34d24

File tree

4 files changed

+58
-9
lines changed

4 files changed

+58
-9
lines changed

src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ namespace LatteDecompiler
221221
{
222222
auto* src = shaderContext->shaderSource;
223223

224-
src->add("#define GET_FRAGCOORD() vec4(in.position.xy * supportBuffer.fragCoordScale.xy, in.position.z, 1.0 / in.position.w)" _CRLF);
224+
src->add("#define GET_FRAGCOORD() float4(in.position.xy * supportBuffer.fragCoordScale.xy, in.position.z, 1.0 / in.position.w)" _CRLF);
225225

226226
src->add("struct FragmentIn {" _CRLF);
227227
src->add("float4 position [[position]];" _CRLF);

src/Cafe/HW/Latte/Renderer/Metal/LatteTextureMtl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM
6767
auto formatInfo = GetMtlPixelFormatInfo(format, isDepth);
6868
desc->setPixelFormat(formatInfo.pixelFormat);
6969

70-
// TODO: is write needed?
70+
// HACK: even though the textures are never written to from a shader, we still need to use `ShaderWrite` usage to prevent pink lines over the screen
7171
MTL::TextureUsage usage = MTL::TextureUsageShaderRead | MTL::TextureUsageShaderWrite;
7272
// TODO: add more conditions
7373
if (!Latte::IsCompressedFormat(format))

src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Cemu/Logging/CemuDebugLogging.h"
1717
#include "HW/Latte/Core/Latte.h"
1818
#include "HW/Latte/ISA/LatteReg.h"
19+
#include "Metal/MTLRenderCommandEncoder.hpp"
1920
#include "Metal/MTLResource.hpp"
2021
#include "Metal/MTLTypes.hpp"
2122
#include "gui/guiWrapper.h"
@@ -600,7 +601,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
600601
const auto fetchShader = LatteSHRC_GetActiveFetchShader();
601602

602603
// Render pipeline state
603-
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.activeFBO, LatteGPUState.contextNew);
604+
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.lastUsedFBO, LatteGPUState.contextNew);
604605
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
605606

606607
// Depth stencil state
@@ -620,9 +621,54 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
620621
renderCommandEncoder->setStencilReferenceValue(stencilRefFront);
621622
}
622623

623-
// Primitive type
624-
const LattePrimitiveMode primitiveMode = static_cast<LattePrimitiveMode>(LatteGPUState.contextRegister[mmVGT_PRIMITIVE_TYPE]);
625-
auto mtlPrimitiveType = GetMtlPrimitiveType(primitiveMode);
624+
// Primitive type
625+
const LattePrimitiveMode primitiveMode = static_cast<LattePrimitiveMode>(LatteGPUState.contextRegister[mmVGT_PRIMITIVE_TYPE]);
626+
auto mtlPrimitiveType = GetMtlPrimitiveType(primitiveMode);
627+
bool isPrimitiveRect = (primitiveMode == Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS);
628+
629+
// Blend color
630+
float* blendColorConstant = (float*)LatteGPUState.contextRegister + Latte::REGADDR::CB_BLEND_RED;
631+
renderCommandEncoder->setBlendColor(blendColorConstant[0], blendColorConstant[1], blendColorConstant[2], blendColorConstant[3]);
632+
633+
// polygon control
634+
const auto& polygonControlReg = LatteGPUState.contextNew.PA_SU_SC_MODE_CNTL;
635+
const auto frontFace = polygonControlReg.get_FRONT_FACE();
636+
uint32 cullFront = polygonControlReg.get_CULL_FRONT();
637+
uint32 cullBack = polygonControlReg.get_CULL_BACK();
638+
uint32 polyOffsetFrontEnable = polygonControlReg.get_OFFSET_FRONT_ENABLED();
639+
640+
// TODO
641+
//cemu_assert_debug(LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_NEAR_DISABLE() == LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_FAR_DISABLE()); // near or far clipping can be disabled individually
642+
//bool zClipEnable = LatteGPUState.contextNew.PA_CL_CLIP_CNTL.get_ZCLIP_FAR_DISABLE() == false;
643+
644+
if (polyOffsetFrontEnable)
645+
{
646+
// TODO: set depth bias
647+
}
648+
649+
// todo - how does culling behave with rects?
650+
// right now we just assume that their winding is always CW
651+
if (isPrimitiveRect)
652+
{
653+
if (frontFace == Latte::LATTE_PA_SU_SC_MODE_CNTL::E_FRONTFACE::CW)
654+
cullFront = cullBack;
655+
else
656+
cullBack = cullFront;
657+
}
658+
659+
if (cullFront && cullBack)
660+
return; // We can just skip the draw (TODO: can we?)
661+
else if (cullFront)
662+
renderCommandEncoder->setCullMode(MTL::CullModeFront);
663+
else if (cullBack)
664+
renderCommandEncoder->setCullMode(MTL::CullModeBack);
665+
else
666+
renderCommandEncoder->setCullMode(MTL::CullModeNone);
667+
668+
if (frontFace == Latte::LATTE_PA_SU_SC_MODE_CNTL::E_FRONTFACE::CCW)
669+
renderCommandEncoder->setFrontFacingWinding(MTL::WindingCounterClockwise);
670+
else
671+
renderCommandEncoder->setFrontFacingWinding(MTL::WindingClockwise);
626672

627673
// Resources
628674

@@ -708,7 +754,7 @@ void MetalRenderer::EnsureCommandBuffer()
708754
if (!m_commandBuffer)
709755
{
710756
// Debug
711-
m_commandQueue->insertDebugCaptureBoundary();
757+
//m_commandQueue->insertDebugCaptureBoundary();
712758

713759
m_commandBuffer = m_commandQueue->commandBuffer();
714760
}
@@ -755,6 +801,7 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
755801
}
756802

757803
// Update state
804+
m_state.lastUsedFBO = m_state.activeFBO;
758805
for (uint8 i = 0; i < 8; i++)
759806
{
760807
m_state.colorRenderTargets[i] = colorRenderTargets[i];
@@ -836,7 +883,7 @@ void MetalRenderer::CommitCommandBuffer()
836883
LatteTextureReadback_UpdateFinishedTransfers(false);
837884

838885
// Debug
839-
m_commandQueue->insertDebugCaptureBoundary();
886+
//m_commandQueue->insertDebugCaptureBoundary();
840887
}
841888
}
842889

src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct MetalState
3131
{
3232
bool skipDrawSequence = false;
3333
class CachedFBOMtl* activeFBO = nullptr;
34+
// If the FBO changes, but it's the same FBO as the last one with some omitted attachments, this FBO doesn't change'
35+
class CachedFBOMtl* lastUsedFBO = nullptr;
3436
MetalBoundBuffer vertexBuffers[MAX_MTL_BUFFERS] = {{}};
3537
// TODO: find out what is the max number of bound textures on the Wii U
3638
class LatteTextureViewMtl* textures[64] = {nullptr};
@@ -58,7 +60,7 @@ class LatteQueryObjectMtl : public LatteQueryObject
5860
bool getResult(uint64& numSamplesPassed) override
5961
{
6062
cemuLog_log(LogType::MetalLogging, "LatteQueryObjectMtl::getResult: occlusion queries are not yet supported on Metal");
61-
return false;
63+
return true;
6264
}
6365

6466
void begin() override

0 commit comments

Comments
 (0)