mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 20:44:18 +01:00
fix: render pass mess
This commit is contained in:
parent
4b7c01ee2a
commit
5e9537c777
@ -169,6 +169,16 @@ uint64 MetalPipelineCache::CalculatePipelineHash(const LatteFetchShader* fetchSh
|
|||||||
{
|
{
|
||||||
// Hash
|
// Hash
|
||||||
uint64 stateHash = 0;
|
uint64 stateHash = 0;
|
||||||
|
for (int i = 0; i < Latte::GPU_LIMITS::NUM_COLOR_ATTACHMENTS; ++i)
|
||||||
|
{
|
||||||
|
auto textureView = static_cast<LatteTextureViewMtl*>(activeFBO->colorBuffer[i].texture);
|
||||||
|
if (!textureView)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stateHash += textureView->GetRGBAView()->pixelFormat() + i * 31;
|
||||||
|
stateHash = std::rotl<uint64>(stateHash, 7);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto& group : fetchShader->bufferGroups)
|
for (auto& group : fetchShader->bufferGroups)
|
||||||
{
|
{
|
||||||
uint32 bufferStride = group.getCurrentBufferStride(lcr.GetRawView());
|
uint32 bufferStride = group.getCurrentBufferStride(lcr.GetRawView());
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Cafe/HW/Latte/Core/LatteIndices.h"
|
#include "Cafe/HW/Latte/Core/LatteIndices.h"
|
||||||
#include "Cemu/Logging/CemuDebugLogging.h"
|
#include "Cemu/Logging/CemuDebugLogging.h"
|
||||||
#include "Common/precompiled.h"
|
#include "Common/precompiled.h"
|
||||||
|
#include "Metal/MTLRenderPass.hpp"
|
||||||
#include "gui/guiWrapper.h"
|
#include "gui/guiWrapper.h"
|
||||||
|
|
||||||
#define COMMIT_TRESHOLD 256
|
#define COMMIT_TRESHOLD 256
|
||||||
@ -214,10 +215,7 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
|||||||
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
|
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
auto renderCommandEncoder = GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
colorRenderTargets[0] = m_drawable->texture();
|
|
||||||
// If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
|
|
||||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, clearBackground, false);
|
|
||||||
renderPassDescriptor->release();
|
renderPassDescriptor->release();
|
||||||
|
|
||||||
// Draw to Metal layer
|
// Draw to Metal layer
|
||||||
@ -226,6 +224,8 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
|||||||
renderCommandEncoder->setFragmentSamplerState((useLinearTexFilter ? m_linearSampler : m_nearestSampler), 0);
|
renderCommandEncoder->setFragmentSamplerState((useLinearTexFilter ? m_linearSampler : m_nearestSampler), 0);
|
||||||
|
|
||||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3));
|
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3));
|
||||||
|
|
||||||
|
EndEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MetalRenderer::BeginFrame(bool mainWindow)
|
bool MetalRenderer::BeginFrame(bool mainWindow)
|
||||||
@ -367,9 +367,9 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
|||||||
stencilAttachment->setLevel(mipIndex);
|
stencilAttachment->setLevel(mipIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, mtlTexture, true);
|
|
||||||
renderPassDescriptor->release();
|
renderPassDescriptor->release();
|
||||||
|
EndEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -676,23 +676,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto renderPassDescriptor = m_state.m_activeFBO->GetRenderPassDescriptor();
|
auto renderCommandEncoder = GetRenderCommandEncoder();
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
|
||||||
MTL::Texture* depthRenderTarget = nullptr;
|
|
||||||
for (uint32 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
auto colorTexture = static_cast<LatteTextureViewMtl*>(m_state.m_activeFBO->colorBuffer[i].texture);
|
|
||||||
if (colorTexture)
|
|
||||||
{
|
|
||||||
colorRenderTargets[i] = colorTexture->GetRGBAView();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto depthTexture = static_cast<LatteTextureViewMtl*>(m_state.m_activeFBO->depthBuffer.texture);
|
|
||||||
if (depthTexture)
|
|
||||||
{
|
|
||||||
depthRenderTarget = depthTexture->GetRGBAView();
|
|
||||||
}
|
|
||||||
auto renderCommandEncoder = GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, depthRenderTarget);
|
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
LatteDecompilerShader* vertexShader = LatteSHRC_GetActiveVertexShader();
|
||||||
@ -705,7 +689,8 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
const auto fetchShader = LatteSHRC_GetActiveFetchShader();
|
const auto fetchShader = LatteSHRC_GetActiveFetchShader();
|
||||||
|
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO, LatteGPUState.contextNew);
|
// TODO: use `m_lastUsedFBO` instead of `m_activeFBO`
|
||||||
|
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_activeFBO, LatteGPUState.contextNew);
|
||||||
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
|
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
|
||||||
|
|
||||||
// Depth stencil state
|
// Depth stencil state
|
||||||
@ -886,8 +871,21 @@ void MetalRenderer::WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBu
|
|||||||
commandBuffer->waitUntilCompleted();
|
commandBuffer->waitUntilCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTL::RenderCommandEncoder* MetalRenderer::GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor)
|
||||||
|
{
|
||||||
|
EndEncoding();
|
||||||
|
|
||||||
|
auto commandBuffer = GetCommandBuffer();
|
||||||
|
|
||||||
|
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
||||||
|
m_commandEncoder = renderCommandEncoder;
|
||||||
|
m_encoderType = MetalEncoderType::Render;
|
||||||
|
|
||||||
|
return renderCommandEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
// Some render passes clear the attachments, forceRecreate is supposed to be used in those cases
|
// Some render passes clear the attachments, forceRecreate is supposed to be used in those cases
|
||||||
MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate, bool rebindStateIfNewEncoder)
|
MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecreate, bool rebindStateIfNewEncoder)
|
||||||
{
|
{
|
||||||
// Check if we need to begin a new render pass
|
// Check if we need to begin a new render pass
|
||||||
if (m_commandEncoder)
|
if (m_commandEncoder)
|
||||||
@ -896,19 +894,22 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
|
|||||||
{
|
{
|
||||||
if (m_encoderType == MetalEncoderType::Render)
|
if (m_encoderType == MetalEncoderType::Render)
|
||||||
{
|
{
|
||||||
bool needsNewRenderPass = false;
|
bool needsNewRenderPass = (m_state.m_lastUsedFBO == nullptr);
|
||||||
for (uint8 i = 0; i < 8; i++)
|
if (!needsNewRenderPass)
|
||||||
{
|
{
|
||||||
if (colorRenderTargets[i] && (colorRenderTargets[i] != m_state.m_colorRenderTargets[i]))
|
for (uint8 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
needsNewRenderPass = true;
|
if (m_state.m_activeFBO->colorBuffer[i].texture && m_state.m_activeFBO->colorBuffer[i].texture != m_state.m_lastUsedFBO->colorBuffer[i].texture)
|
||||||
break;
|
{
|
||||||
|
needsNewRenderPass = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needsNewRenderPass)
|
if (!needsNewRenderPass)
|
||||||
{
|
{
|
||||||
if (depthRenderTarget && (depthRenderTarget != m_state.m_depthRenderTarget))
|
if (m_state.m_activeFBO->depthBuffer.texture && m_state.m_activeFBO->depthBuffer.texture != m_state.m_lastUsedFBO->depthBuffer.texture)
|
||||||
{
|
{
|
||||||
needsNewRenderPass = true;
|
needsNewRenderPass = true;
|
||||||
}
|
}
|
||||||
@ -928,13 +929,8 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(MTL::RenderPas
|
|||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
m_state.m_lastUsedFBO = m_state.m_activeFBO;
|
m_state.m_lastUsedFBO = m_state.m_activeFBO;
|
||||||
for (uint8 i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
m_state.m_colorRenderTargets[i] = colorRenderTargets[i];
|
|
||||||
}
|
|
||||||
m_state.m_depthRenderTarget = depthRenderTarget;
|
|
||||||
|
|
||||||
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(renderPassDescriptor);
|
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(m_state.m_activeFBO->GetRenderPassDescriptor());
|
||||||
m_commandEncoder = renderCommandEncoder;
|
m_commandEncoder = renderCommandEncoder;
|
||||||
m_encoderType = MetalEncoderType::Render;
|
m_encoderType = MetalEncoderType::Render;
|
||||||
|
|
||||||
@ -991,10 +987,11 @@ MTL::BlitCommandEncoder* MetalRenderer::GetBlitCommandEncoder()
|
|||||||
|
|
||||||
void MetalRenderer::EndEncoding()
|
void MetalRenderer::EndEncoding()
|
||||||
{
|
{
|
||||||
if (m_encoderType != MetalEncoderType::None)
|
if (m_commandEncoder)
|
||||||
{
|
{
|
||||||
m_commandEncoder->endEncoding();
|
m_commandEncoder->endEncoding();
|
||||||
m_commandEncoder->release();
|
m_commandEncoder->release();
|
||||||
|
m_commandEncoder = nullptr;
|
||||||
m_encoderType = MetalEncoderType::None;
|
m_encoderType = MetalEncoderType::None;
|
||||||
|
|
||||||
// Commit the command buffer if enough draw calls have been recorded
|
// Commit the command buffer if enough draw calls have been recorded
|
||||||
@ -1427,6 +1424,7 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
|
|||||||
|
|
||||||
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
MTL::Texture* colorRenderTargets[8] = {nullptr};
|
||||||
colorRenderTargets[0] = mtlTexture;
|
colorRenderTargets[0] = mtlTexture;
|
||||||
GetRenderCommandEncoder(renderPassDescriptor, colorRenderTargets, nullptr, true);
|
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
renderPassDescriptor->release();
|
renderPassDescriptor->release();
|
||||||
|
EndEncoding();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalMemoryManager.h"
|
||||||
#include "Common/precompiled.h"
|
#include "Common/precompiled.h"
|
||||||
#include "Metal/MTLCommandBuffer.hpp"
|
#include "Metal/MTLCommandBuffer.hpp"
|
||||||
|
#include "Metal/MTLRenderPass.hpp"
|
||||||
|
|
||||||
#define MAX_MTL_BUFFERS 31
|
#define MAX_MTL_BUFFERS 31
|
||||||
#define GET_MTL_VERTEX_BUFFER_INDEX(index) (MAX_MTL_BUFFERS - index - 2)
|
#define GET_MTL_VERTEX_BUFFER_INDEX(index) (MAX_MTL_BUFFERS - index - 2)
|
||||||
@ -42,9 +43,6 @@ struct MetalState
|
|||||||
class LatteTextureViewMtl* m_textures[64] = {nullptr};
|
class LatteTextureViewMtl* m_textures[64] = {nullptr};
|
||||||
size_t m_uniformBufferOffsets[(uint32)LatteConst::ShaderType::TotalCount][MAX_MTL_BUFFERS];
|
size_t m_uniformBufferOffsets[(uint32)LatteConst::ShaderType::TotalCount][MAX_MTL_BUFFERS];
|
||||||
|
|
||||||
MTL::Texture* m_colorRenderTargets[8] = {nullptr};
|
|
||||||
MTL::Texture* m_depthRenderTarget = nullptr;
|
|
||||||
|
|
||||||
MTL::Viewport m_viewport = {0, 0, 0, 0, 0, 0};
|
MTL::Viewport m_viewport = {0, 0, 0, 0, 0, 0};
|
||||||
MTL::ScissorRect m_scissor = {0, 0, 0, 0};
|
MTL::ScissorRect m_scissor = {0, 0, 0, 0};
|
||||||
};
|
};
|
||||||
@ -249,7 +247,8 @@ public:
|
|||||||
MTL::CommandBuffer* GetCommandBuffer();
|
MTL::CommandBuffer* GetCommandBuffer();
|
||||||
bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer);
|
bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer);
|
||||||
void WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBuffer);
|
void WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBuffer);
|
||||||
MTL::RenderCommandEncoder* GetRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor, MTL::Texture* colorRenderTargets[8], MTL::Texture* depthRenderTarget, bool forceRecreate = false, bool rebindStateIfNewEncoder = true);
|
MTL::RenderCommandEncoder* GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor);
|
||||||
|
MTL::RenderCommandEncoder* GetRenderCommandEncoder(bool forceRecreate = false, bool rebindStateIfNewEncoder = true);
|
||||||
MTL::ComputeCommandEncoder* GetComputeCommandEncoder();
|
MTL::ComputeCommandEncoder* GetComputeCommandEncoder();
|
||||||
MTL::BlitCommandEncoder* GetBlitCommandEncoder();
|
MTL::BlitCommandEncoder* GetBlitCommandEncoder();
|
||||||
void EndEncoding();
|
void EndEncoding();
|
||||||
|
Loading…
Reference in New Issue
Block a user