From fd16488e4c238e83a5faf52fc2f3ed1ebca365d7 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Fri, 13 Sep 2024 11:19:56 +0200 Subject: [PATCH] improve command buffer sync --- .../Metal/LatteTextureReadbackMtl.cpp | 4 ++-- .../Renderer/Metal/MetalBufferAllocator.h | 2 +- .../HW/Latte/Renderer/Metal/MetalCommon.h | 6 +++++ .../HW/Latte/Renderer/Metal/MetalQuery.cpp | 13 +++++++++-- src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.h | 5 ++-- .../HW/Latte/Renderer/Metal/MetalRenderer.cpp | 23 ++++--------------- .../HW/Latte/Renderer/Metal/MetalRenderer.h | 9 ++++---- 7 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp index f2c03709..d7adc25c 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteTextureReadbackMtl.cpp @@ -38,12 +38,12 @@ bool LatteTextureReadbackInfoMtl::IsFinished() if (m_mtlr->GetCurrentCommandBuffer() == m_commandBuffer) m_mtlr->CommitCommandBuffer(); - return m_mtlr->CommandBufferCompleted(m_commandBuffer); + return CommandBufferCompleted(m_commandBuffer); } void LatteTextureReadbackInfoMtl::ForceFinish() { - m_mtlr->WaitForCommandBufferCompletion(m_commandBuffer); + m_commandBuffer->waitUntilCompleted(); } uint8* LatteTextureReadbackInfoMtl::GetData() diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h index b8a3c760..198d9978 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalBufferAllocator.h @@ -255,7 +255,7 @@ public: auto& buffer = m_buffers[i]; for (uint32_t j = 0; j < buffer.m_data.m_commandBuffers.size(); j++) { - if (m_mtlr->CommandBufferCompleted(buffer.m_data.m_commandBuffers[j])) + if (CommandBufferCompleted(buffer.m_data.m_commandBuffers[j])) { if (buffer.m_data.m_commandBuffers.size() == 1) { diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h index 8a6daa92..a1fe7f82 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalCommon.h @@ -69,3 +69,9 @@ inline bool IsValidDepthTextureType(Latte::E_DIM dim) { return (dim == Latte::E_DIM::DIM_2D || dim == Latte::E_DIM::DIM_2D_MSAA || dim == Latte::E_DIM::DIM_2D_ARRAY || dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA || dim == Latte::E_DIM::DIM_CUBEMAP); } + +inline bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer) +{ + auto status = commandBuffer->status(); + return (status == MTL::CommandBufferStatusCompleted || status == MTL::CommandBufferStatusError); +} diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.cpp index c27a5620..0119209b 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.cpp @@ -4,14 +4,21 @@ bool LatteQueryObjectMtl::getResult(uint64& numSamplesPassed) { - if (!m_mtlr->CommandBufferCompleted(m_commandBuffer)) + if (!CommandBufferCompleted(m_commandBuffer)) return false; numSamplesPassed = m_mtlr->GetOcclusionQueryResultsPtr()[m_queryIndex]; + printf("Num samples: %llu\n", numSamplesPassed); return true; } +LatteQueryObjectMtl::~LatteQueryObjectMtl() +{ + if (m_queryIndex != INVALID_UINT32) + m_mtlr->ReleaseOcclusionQueryIndex(m_queryIndex); +} + void LatteQueryObjectMtl::begin() { m_queryIndex = m_mtlr->GetAvailableOcclusionQueryIndex(); @@ -21,5 +28,7 @@ void LatteQueryObjectMtl::begin() void LatteQueryObjectMtl::end() { m_mtlr->SetActiveOcclusionQueryIndex(INVALID_UINT32); - // TODO: request soon submit of the command buffer + m_commandBuffer = m_mtlr->GetCurrentCommandBuffer(); + // TODO: request soon submit instead? + m_mtlr->CommitCommandBuffer(); } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.h index 8fa53497..58b4e266 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalQuery.h @@ -8,6 +8,7 @@ class LatteQueryObjectMtl : public LatteQueryObject { public: LatteQueryObjectMtl(class MetalRenderer* mtlRenderer) : m_mtlr{mtlRenderer} {} + ~LatteQueryObjectMtl(); bool getResult(uint64& numSamplesPassed) override; void begin() override; @@ -16,7 +17,7 @@ public: private: class MetalRenderer* m_mtlr; - uint32 m_queryIndex; + uint32 m_queryIndex = INVALID_UINT32; + // TODO: make this a list of command buffers MTL::CommandBuffer* m_commandBuffer; - uint64 m_acccumulatedSum; }; diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp index 045ca77e..e4b25d55 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp @@ -334,7 +334,7 @@ void MetalRenderer::Flush(bool waitIdle) { cemu_assert_debug(commandBuffer.m_commited); - WaitForCommandBufferCompletion(commandBuffer.m_commandBuffer); + commandBuffer.m_commandBuffer->waitUntilCompleted(); } } } @@ -1059,7 +1059,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32 if (m_occlusionQuery.m_activeIndex != encoderState.m_visibilityResultOffset) { auto mode = (m_occlusionQuery.m_activeIndex == INVALID_UINT32 ? MTL::VisibilityResultModeDisabled : MTL::VisibilityResultModeCounting); - renderCommandEncoder->setVisibilityResultMode(mode, m_occlusionQuery.m_activeIndex); + renderCommandEncoder->setVisibilityResultMode(mode, m_occlusionQuery.m_activeIndex * sizeof(uint64)); encoderState.m_visibilityResultOffset = m_occlusionQuery.m_activeIndex; } @@ -1309,16 +1309,16 @@ LatteQueryObject* MetalRenderer::occlusionQuery_create() { } void MetalRenderer::occlusionQuery_destroy(LatteQueryObject* queryObj) { - // TODO: do something? + auto queryObjMtl = static_cast(queryObj); + delete queryObjMtl; } void MetalRenderer::occlusionQuery_flush() { // TODO: implement - debug_printf("Occlusion query flush is not implemented\n"); } void MetalRenderer::occlusionQuery_updateState() { - // TODO + // TODO: implement } void MetalRenderer::SetBuffer(MTL::RenderCommandEncoder* renderCommandEncoder, MetalShaderType shaderType, MTL::Buffer* buffer, size_t offset, uint32 index) @@ -1420,17 +1420,6 @@ MTL::CommandBuffer* MetalRenderer::GetCommandBuffer() } } -bool MetalRenderer::CommandBufferCompleted(MTL::CommandBuffer* commandBuffer) -{ - auto status = commandBuffer->status(); - return (status == MTL::CommandBufferStatusCompleted || status == MTL::CommandBufferStatusError); -} - -void MetalRenderer::WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBuffer) -{ - commandBuffer->waitUntilCompleted(); -} - MTL::RenderCommandEncoder* MetalRenderer::GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor) { EndEncoding(); @@ -1594,8 +1583,6 @@ void MetalRenderer::CommitCommandBuffer() m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(nullptr); - m_occlusionQuery.m_availableIndices.insert(m_occlusionQuery.m_availableIndices.end(), m_occlusionQuery.m_crntCmdBuffIndices.begin(), m_occlusionQuery.m_crntCmdBuffIndices.end()); - // Debug //m_commandQueue->insertDebugCaptureBoundary(); } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h index 4f7376b6..f46a4be3 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h @@ -323,8 +323,6 @@ public: void SetSamplerState(MTL::RenderCommandEncoder* renderCommandEncoder, MetalShaderType shaderType, MTL::SamplerState* samplerState, uint32 index); MTL::CommandBuffer* GetCommandBuffer(); - bool CommandBufferCompleted(MTL::CommandBuffer* commandBuffer); - void WaitForCommandBufferCompletion(MTL::CommandBuffer* commandBuffer); MTL::RenderCommandEncoder* GetTemporaryRenderCommandEncoder(MTL::RenderPassDescriptor* renderPassDescriptor); MTL::RenderCommandEncoder* GetRenderCommandEncoder(bool forceRecreate = false); MTL::ComputeCommandEncoder* GetComputeCommandEncoder(); @@ -397,11 +395,15 @@ public: uint32 queryIndex = m_occlusionQuery.m_availableIndices.back(); m_occlusionQuery.m_availableIndices.pop_back(); - m_occlusionQuery.m_crntCmdBuffIndices.push_back(queryIndex); return queryIndex; } + void ReleaseOcclusionQueryIndex(uint32 queryIndex) + { + m_occlusionQuery.m_availableIndices.push_back(queryIndex); + } + void SetActiveOcclusionQueryIndex(uint32 queryIndex) { m_occlusionQuery.m_activeIndex = queryIndex; @@ -460,7 +462,6 @@ private: MTL::Buffer* m_resultBuffer; uint64* m_resultsPtr; std::vector m_availableIndices; - std::vector m_crntCmdBuffIndices; uint32 m_activeIndex = INVALID_UINT32; } m_occlusionQuery;