diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp index ef157664..491017c0 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp @@ -25,15 +25,22 @@ void LatteTextureReadbackInfoMtl::StartTransfer() blitCommandEncoder->copyFromTexture(baseTexture->GetTexture(), 0, 0, MTL::Origin{0, 0, 0}, MTL::Size{(uint32)baseTexture->width, (uint32)baseTexture->height, 1}, m_mtlr->GetTextureReadbackBuffer(), m_bufferOffset, bytesPerRow, bytesPerImage); m_commandBuffer = m_mtlr->GetCurrentCommandBuffer(); - // TODO: uncomment - //m_mtlr->RequestSoonCommit(); + m_mtlr->RequestSoonCommit(); + m_mtlr->RequestCommitOnIdle(); } bool LatteTextureReadbackInfoMtl::IsFinished() { - // HACK: just return true for now, otherwise the game would freeze - //return m_mtlr->CommandBufferCompleted(m_commandBuffer); - return true; + // TODO: is this needed? + if (!m_commandBuffer) + return false; + + // TODO: remove this? + // Command buffer wasn't even comitted, let's commit immediately + if (m_mtlr->GetCurrentCommandBuffer() == m_commandBuffer) + m_mtlr->CommitCommandBuffer(); + + return m_mtlr->CommandBufferCompleted(m_commandBuffer); } void LatteTextureReadbackInfoMtl::ForceFinish() diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 7604406f..a348409d 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -21,7 +21,7 @@ #include "HW/Latte/Renderer/Metal/MetalCommon.h" #include "gui/guiWrapper.h" -#define COMMIT_TRESHOLD 256 +#define DEFAULT_COMMIT_TRESHOLD 256 extern bool hasValidFramebufferAttached; @@ -297,8 +297,7 @@ bool MetalRenderer::BeginFrame(bool mainWindow) void MetalRenderer::Flush(bool waitIdle) { - // TODO: commit if commit on idle is requested - if (m_recordedDrawcalls > 0) + if (m_commitOnIdle || m_recordedDrawcalls > 0) CommitCommandBuffer(); if (waitIdle) { @@ -309,8 +308,8 @@ void MetalRenderer::Flush(bool waitIdle) void MetalRenderer::NotifyLatteCommandProcessorIdle() { - // TODO: commit if commit on idle is requested - //CommitCommandBuffer(); + if (m_commitOnIdle) + CommitCommandBuffer(); } void MetalRenderer::AppendOverlayDebugInfo() @@ -1056,7 +1055,7 @@ void MetalRenderer::draw_endSequence() bool hasReadback = LatteTextureReadback_Update(); m_recordedDrawcalls++; // The number of draw calls needs to twice as big, since we are interrupting the render pass - if (m_recordedDrawcalls >= COMMIT_TRESHOLD * 2 || hasReadback) + if (m_recordedDrawcalls >= m_commitTreshold * 2 || hasReadback) { CommitCommandBuffer(); @@ -1321,14 +1320,16 @@ void MetalRenderer::EndEncoding() m_encoderType = MetalEncoderType::None; // Commit the command buffer if enough draw calls have been recorded - if (m_recordedDrawcalls >= COMMIT_TRESHOLD) + if (m_recordedDrawcalls >= m_commitTreshold) CommitCommandBuffer(); } } void MetalRenderer::CommitCommandBuffer() { + m_commitTreshold = DEFAULT_COMMIT_TRESHOLD; m_recordedDrawcalls = 0; + m_commitOnIdle = false; if (m_commandBuffers.size() != 0) { diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index f8e12bd6..108901f3 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -375,6 +375,16 @@ public: return m_state.m_encoderState; } + void RequestSoonCommit() + { + m_commitTreshold = m_recordedDrawcalls + 8; + } + + void RequestCommitOnIdle() + { + m_commitOnIdle = true; + } + void SetBuffer(MTL::RenderCommandEncoder* renderCommandEncoder, MetalShaderType shaderType, MTL::Buffer* buffer, size_t offset, uint32 index); void SetTexture(MTL::RenderCommandEncoder* renderCommandEncoder, MetalShaderType shaderType, MTL::Texture* texture, uint32 index); void SetSamplerState(MTL::RenderCommandEncoder* renderCommandEncoder, MetalShaderType shaderType, MTL::SamplerState* samplerState, uint32 index); @@ -471,11 +481,14 @@ private: // Active objects std::vector m_commandBuffers; - uint32 m_recordedDrawcalls = 0; MetalEncoderType m_encoderType = MetalEncoderType::None; MTL::CommandEncoder* m_commandEncoder = nullptr; CA::MetalDrawable* m_drawable = nullptr; + uint32 m_commitTreshold = 0; + uint32 m_recordedDrawcalls = 0; + bool m_commitOnIdle = false; + // State MetalState m_state; };