Skip to content

Commit 5e9537c

Browse files
committed
fix: render pass mess
1 parent 4b7c01e commit 5e9537c

File tree

3 files changed

+50
-43
lines changed

3 files changed

+50
-43
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ uint64 MetalPipelineCache::CalculatePipelineHash(const LatteFetchShader* fetchSh
169169
{
170170
// Hash
171171
uint64 stateHash = 0;
172+
for (int i = 0; i < Latte::GPU_LIMITS::NUM_COLOR_ATTACHMENTS; ++i)
173+
{
174+
auto textureView = static_cast<LatteTextureViewMtl*>(activeFBO->colorBuffer[i].texture);
175+
if (!textureView)
176+
continue;
177+
178+
stateHash += textureView->GetRGBAView()->pixelFormat() + i * 31;
179+
stateHash = std::rotl<uint64>(stateHash, 7);
180+
}
181+
172182
for (auto& group : fetchShader->bufferGroups)
173183
{
174184
uint32 bufferStride = group.getCurrentBufferStride(lcr.GetRawView());

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

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "Cafe/HW/Latte/Core/LatteIndices.h"
1717
#include "Cemu/Logging/CemuDebugLogging.h"
1818
#include "Common/precompiled.h"
19+
#include "Metal/MTLRenderPass.hpp"
1920
#include "gui/guiWrapper.h"
2021

2122
#define COMMIT_TRESHOLD 256
@@ -214,10 +215,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
214215
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
215216
colorAttachment->setStoreAction(MTL::StoreActionStore);
216217

217-
MTL::Texture* colorRenderTargets[8] = {nullptr};
218-
colorRenderTargets[0] = m_drawable->texture();
219-
// If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
220-
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, clearBackground, false);
218+
auto renderCommandEncoder = GetTemporaryRenderCommandEncoder(renderPassDescriptor);
221219
renderPassDescriptor->release();
222220

223221
// Draw to Metal layer
@@ -226,6 +224,8 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
226224
renderCommandEncoder->setFragmentSamplerState((useLinearTexFilter ? m_linearSampler : m_nearestSampler), 0);
227225

228226
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3));
227+
228+
EndEncoding();
229229
}
230230

231231
bool MetalRenderer::BeginFrame(bool mainWindow)
@@ -367,9 +367,9 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
367367
stencilAttachment->setLevel(mipIndex);
368368
}
369369

370-
MTL::Texture* colorRenderTargets[8] = {nullptr};
371-
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true);
370+
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
372371
renderPassDescriptor->release();
372+
EndEncoding();
373373
}
374374

375375
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)
@@ -676,23 +676,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
676676
return;
677677
}
678678

679-
auto renderPassDescriptor = m_state.m_activeFBO->GetRenderPassDescriptor();
680-
MTL::Texture* colorRenderTargets[8] = {nullptr};
681-
MTL::Texture* depthRenderTarget = nullptr;
682-
for (uint32 i = 0; i < 8; i++)
683-
{
684-
auto colorTexture = static_cast<LatteTextureViewMtl*>(m_state.m_activeFBO->colorBuffer[i].texture);
685-
if (colorTexture)
686-
{
687-
colorRenderTargets[i] = colorTexture->GetRGBAView();
688-
}
689-
}
690-
auto depthTexture = static_cast<LatteTextureViewMtl*>(m_state.m_activeFBO->depthBuffer.texture);
691-
if (depthTexture)
692-
{
693-
depthRenderTarget = depthTexture->GetRGBAView();
694-
}
695-
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, depthRenderTarget);
679+
auto renderCommandEncoder = GetRenderCommandEncoder();
696680

697681
// Shaders
698682
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
@@ -705,7 +689,8 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
705689
const auto fetchShader = LatteSHRC_GetActiveFetchShader();
706690

707691
// Render pipeline state
708-
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO, LatteGPUState.contextNew);
692+
// TODO: use `m_lastUsedFBO` instead of `m_activeFBO`
693+
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_activeFBO, LatteGPUState.contextNew);
709694
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
710695

711696
// Depth stencil state
@@ -886,8 +871,21 @@ void MetalRenderer::WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBu
886871
commandBuffer->waitUntilCompleted();
887872
}
888873

874+
MTL::RenderCommandEncoder* MetalRenderer::GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor)
875+
{
876+
EndEncoding();
877+
878+
auto commandBuffer = GetCommandBuffer();
879+
880+
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
881+
m_commandEncoder = renderCommandEncoder;
882+
m_encoderType = MetalEncoderType::Render;
883+
884+
return renderCommandEncoder;
885+
}
886+
889887
// Some render passes clear the attachments, forceRecreate is supposed to be used in those cases
890-
MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate, bool rebindStateIfNewEncoder)
888+
MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecreate, bool rebindStateIfNewEncoder)
891889
{
892890
// Check if we need to begin a new render pass
893891
if (m_commandEncoder)
@@ -896,19 +894,22 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
896894
{
897895
if (m_encoderType == MetalEncoderType::Render)
898896
{
899-
bool needsNewRenderPass = false;
900-
for (uint8 i = 0; i < 8; i++)
897+
bool needsNewRenderPass = (m_state.m_lastUsedFBO == nullptr);
898+
if (!needsNewRenderPass)
901899
{
902-
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.m_colorRenderTargets[i]))
900+
for (uint8 i = 0; i < 8; i++)
903901
{
904-
needsNewRenderPass = true;
905-
break;
902+
if (m_state.m_activeFBO->colorBuffer[i].texture && m_state.m_activeFBO->colorBuffer[i].texture != m_state.m_lastUsedFBO->colorBuffer[i].texture)
903+
{
904+
needsNewRenderPass = true;
905+
break;
906+
}
906907
}
907908
}
908909

909910
if (!needsNewRenderPass)
910911
{
911-
if (depthRenderTarget && (depthRenderTarget != m_state.m_depthRenderTarget))
912+
if (m_state.m_activeFBO->depthBuffer.texture && m_state.m_activeFBO->depthBuffer.texture != m_state.m_lastUsedFBO->depthBuffer.texture)
912913
{
913914
needsNewRenderPass = true;
914915
}
@@ -928,13 +929,8 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
928929

929930
// Update state
930931
m_state.m_lastUsedFBO = m_state.m_activeFBO;
931-
for (uint8 i = 0; i < 8; i++)
932-
{
933-
m_state.m_colorRenderTargets[i] = colorRenderTargets[i];
934-
}
935-
m_state.m_depthRenderTarget = depthRenderTarget;
936932

937-
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
933+
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(m_state.m_activeFBO->GetRenderPassDescriptor());
938934
m_commandEncoder = renderCommandEncoder;
939935
m_encoderType = MetalEncoderType::Render;
940936

@@ -991,10 +987,11 @@ MTL::BlitCommandEncoder* MetalRenderer::GetBlitCommandEncoder()
991987

992988
void MetalRenderer::EndEncoding()
993989
{
994-
if (m_encoderType != MetalEncoderType::None)
990+
if (m_commandEncoder)
995991
{
996992
m_commandEncoder->endEncoding();
997993
m_commandEncoder->release();
994+
m_commandEncoder = nullptr;
998995
m_encoderType = MetalEncoderType::None;
999996

1000997
// Commit the command buffer if enough draw calls have been recorded
@@ -1427,6 +1424,7 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
14271424

14281425
MTL::Texture* colorRenderTargets[8] = {nullptr};
14291426
colorRenderTargets[0] = mtlTexture;
1430-
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true);
1427+
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
14311428
renderPassDescriptor->release();
1429+
EndEncoding();
14321430
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
1010
#include "Common/precompiled.h"
1111
#include "Metal/MTLCommandBuffer.hpp"
12+
#include "Metal/MTLRenderPass.hpp"
1213

1314
#define MAX_MTL_BUFFERS 31
1415
#define GET_MTL_VERTEX_BUFFER_INDEX(index) (MAX_MTL_BUFFERS - index - 2)
@@ -42,9 +43,6 @@ struct MetalState
4243
class LatteTextureViewMtl* m_textures[64] = {nullptr};
4344
size_t m_uniformBufferOffsets[(uint32)LatteConst::ShaderType::TotalCount][MAX_MTL_BUFFERS];
4445

45-
MTL::Texture* m_colorRenderTargets[8] = {nullptr};
46-
MTL::Texture* m_depthRenderTarget = nullptr;
47-
4846
MTL::Viewport m_viewport = {0, 0, 0, 0, 0, 0};
4947
MTL::ScissorRect m_scissor = {0, 0, 0, 0};
5048
};
@@ -249,7 +247,8 @@ class MetalRenderer : public Renderer
249247
MTL::CommandBuffer* GetCommandBuffer();
250248
bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer);
251249
void WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBuffer);
252-
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate = false, bool rebindStateIfNewEncoder = true);
250+
MTL::RenderCommandEncoder* GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor);
251+
MTL::RenderCommandEncoder* GetRenderCommandEncoder(bool forceRecreate = false, bool rebindStateIfNewEncoder = true);
253252
MTL::ComputeCommandEncoder* GetComputeCommandEncoder();
254253
MTL::BlitCommandEncoder* GetBlitCommandEncoder();
255254
void EndEncoding();

0 commit comments

Comments
 (0)