refactor command buffers

This commit is contained in:
Samuliak 2024-11-05 17:57:20 +01:00
parent 552c4901b9
commit c46c8214f5
No known key found for this signature in database
4 changed files with 35 additions and 39 deletions

View File

@ -6,6 +6,7 @@ public:
size_t m_bufferAllocatorMemory = 0; size_t m_bufferAllocatorMemory = 0;
// Per frame data // Per frame data
uint32 m_commandBuffers = 0;
uint32 m_renderPasses = 0; uint32 m_renderPasses = 0;
uint32 m_clears = 0; uint32 m_clears = 0;
uint32 m_manualVertexFetchDraws = 0; uint32 m_manualVertexFetchDraws = 0;
@ -17,6 +18,7 @@ public:
void ResetPerFrameData() void ResetPerFrameData()
{ {
m_commandBuffers = 0;
m_renderPasses = 0; m_renderPasses = 0;
m_clears = 0; m_clears = 0;
m_manualVertexFetchDraws = 0; m_manualVertexFetchDraws = 0;

View File

@ -37,9 +37,8 @@ void LatteQueryObjectMtl::end()
{ {
m_range.end = m_mtlr->GetOcclusionQueryIndex(); m_range.end = m_mtlr->GetOcclusionQueryIndex();
m_mtlr->EndOcclusionQuery(); m_mtlr->EndOcclusionQuery();
m_commandBuffer = m_mtlr->GetCurrentCommandBuffer()->retain();
if (m_mtlr->IsCommandBufferActive()) if (m_mtlr->IsCommandBufferActive())
{
m_commandBuffer = m_mtlr->GetCurrentCommandBuffer()->retain();
m_mtlr->RequestSoonCommit(); m_mtlr->RequestSoonCommit();
}
} }

View File

@ -234,7 +234,6 @@ void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
// Reset the command buffers (they are released by TemporaryBufferAllocator) // Reset the command buffers (they are released by TemporaryBufferAllocator)
CommitCommandBuffer(); CommitCommandBuffer();
m_commandBuffers.clear();
// Release frame persistent buffers // Release frame persistent buffers
m_memoryManager->GetFramePersistentBufferAllocator().ResetAllocations(); m_memoryManager->GetFramePersistentBufferAllocator().ResetAllocations();
@ -318,12 +317,9 @@ void MetalRenderer::Flush(bool waitIdle)
CommitCommandBuffer(); CommitCommandBuffer();
if (waitIdle) if (waitIdle)
{ {
for (auto commandBuffer : m_commandBuffers) cemu_assert_debug(m_currentCommandBuffer.m_commited);
{
cemu_assert_debug(commandBuffer.m_commited);
commandBuffer.m_commandBuffer->waitUntilCompleted(); m_currentCommandBuffer.m_commandBuffer->waitUntilCompleted();
}
} }
} }
@ -448,7 +444,7 @@ void MetalRenderer::AppendOverlayDebugInfo()
ImGui::Text("Buffer allocator memory %zuMB", m_performanceMonitor.m_bufferAllocatorMemory / 1024 / 1024); ImGui::Text("Buffer allocator memory %zuMB", m_performanceMonitor.m_bufferAllocatorMemory / 1024 / 1024);
ImGui::Text("--- Metal info (per frame) ---"); ImGui::Text("--- Metal info (per frame) ---");
ImGui::Text("Command buffers %zu", m_commandBuffers.size()); ImGui::Text("Command buffers %u", m_performanceMonitor.m_commandBuffers);
ImGui::Text("Render passes %u", m_performanceMonitor.m_renderPasses); ImGui::Text("Render passes %u", m_performanceMonitor.m_renderPasses);
ImGui::Text("Clears %u", m_performanceMonitor.m_clears); ImGui::Text("Clears %u", m_performanceMonitor.m_clears);
ImGui::Text("Manual vertex fetch draws %u (mesh draws: %u)", m_performanceMonitor.m_manualVertexFetchDraws, m_performanceMonitor.m_meshDraws); ImGui::Text("Manual vertex fetch draws %u (mesh draws: %u)", m_performanceMonitor.m_manualVertexFetchDraws, m_performanceMonitor.m_meshDraws);
@ -1427,14 +1423,14 @@ void MetalRenderer::SetSamplerState(MTL::RenderCommandEncoder* renderCommandEnco
MTL::CommandBuffer* MetalRenderer::GetCommandBuffer() MTL::CommandBuffer* MetalRenderer::GetCommandBuffer()
{ {
bool needsNewCommandBuffer = (m_commandBuffers.empty() || m_commandBuffers.back().m_commited); bool needsNewCommandBuffer = (!m_currentCommandBuffer.m_commandBuffer || m_currentCommandBuffer.m_commited);
if (needsNewCommandBuffer) if (needsNewCommandBuffer)
{ {
// Debug // Debug
//m_commandQueue->insertDebugCaptureBoundary(); //m_commandQueue->insertDebugCaptureBoundary();
MTL::CommandBuffer* mtlCommandBuffer = m_commandQueue->commandBuffer(); MTL::CommandBuffer* mtlCommandBuffer = m_commandQueue->commandBuffer();
m_commandBuffers.push_back({mtlCommandBuffer}); m_currentCommandBuffer = {mtlCommandBuffer};
m_recordedDrawcalls = 0; m_recordedDrawcalls = 0;
m_commitTreshold = m_defaultCommitTreshlod; m_commitTreshold = m_defaultCommitTreshlod;
@ -1442,11 +1438,14 @@ MTL::CommandBuffer* MetalRenderer::GetCommandBuffer()
// Notify memory manager about the new command buffer // Notify memory manager about the new command buffer
m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(mtlCommandBuffer); m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(mtlCommandBuffer);
// Debug
m_performanceMonitor.m_commandBuffers++;
return mtlCommandBuffer; return mtlCommandBuffer;
} }
else else
{ {
return m_commandBuffers.back().m_commandBuffer; return m_currentCommandBuffer.m_commandBuffer;
} }
} }
@ -1594,27 +1593,26 @@ void MetalRenderer::EndEncoding()
void MetalRenderer::CommitCommandBuffer() void MetalRenderer::CommitCommandBuffer()
{ {
if (m_commandBuffers.size() != 0) if (!m_currentCommandBuffer.m_commandBuffer)
return;
EndEncoding();
if (!m_currentCommandBuffer.m_commited)
{ {
EndEncoding(); // Handled differently, since it seems like Metal doesn't always call the completion handler
//commandBuffer.m_commandBuffer->addCompletedHandler(^(MTL::CommandBuffer*) {
// m_memoryManager->GetTemporaryBufferAllocator().CommandBufferFinished(commandBuffer.m_commandBuffer);
//});
auto& commandBuffer = m_commandBuffers.back(); m_currentCommandBuffer.m_commandBuffer->commit();
if (!commandBuffer.m_commited) m_currentCommandBuffer.m_commandBuffer->release();
{ m_currentCommandBuffer.m_commited = true;
// Handled differently, since it seems like Metal doesn't always call the completion handler
//commandBuffer.m_commandBuffer->addCompletedHandler(^(MTL::CommandBuffer*) {
// m_memoryManager->GetTemporaryBufferAllocator().CommandBufferFinished(commandBuffer.m_commandBuffer);
//});
commandBuffer.m_commandBuffer->commit(); m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(nullptr);
commandBuffer.m_commandBuffer->release();
commandBuffer.m_commited = true;
m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(nullptr); // Debug
//m_commandQueue->insertDebugCaptureBoundary();
// Debug
//m_commandQueue->insertDebugCaptureBoundary();
}
} }
} }

View File

@ -137,7 +137,7 @@ struct MetalState
struct MetalCommandBuffer struct MetalCommandBuffer
{ {
MTL::CommandBuffer* m_commandBuffer; MTL::CommandBuffer* m_commandBuffer = nullptr;
bool m_commited = false; bool m_commited = false;
}; };
@ -280,14 +280,14 @@ public:
bool IsCommandBufferActive() const bool IsCommandBufferActive() const
{ {
return (m_commandBuffers.size() != 0); return (m_currentCommandBuffer.m_commandBuffer && !m_currentCommandBuffer.m_commited);
} }
MTL::CommandBuffer* GetCurrentCommandBuffer() MTL::CommandBuffer* GetCurrentCommandBuffer()
{ {
cemu_assert_debug(m_commandBuffers.size() != 0); cemu_assert_debug(m_currentCommandBuffer.m_commandBuffer);
return m_commandBuffers[m_commandBuffers.size() - 1].m_commandBuffer; return m_currentCommandBuffer.m_commandBuffer;
} }
void RequestSoonCommit() void RequestSoonCommit()
@ -431,10 +431,7 @@ public:
m_occlusionQuery.m_active = false; m_occlusionQuery.m_active = false;
if (m_occlusionQuery.m_lastCommandBuffer) if (m_occlusionQuery.m_lastCommandBuffer)
m_occlusionQuery.m_lastCommandBuffer->release(); m_occlusionQuery.m_lastCommandBuffer->release();
if (IsCommandBufferActive()) m_occlusionQuery.m_lastCommandBuffer = GetCurrentCommandBuffer()->retain();
m_occlusionQuery.m_lastCommandBuffer = GetCurrentCommandBuffer()->retain();
else
m_occlusionQuery.m_lastCommandBuffer = nullptr;
} }
private: private:
@ -490,7 +487,7 @@ private:
} m_occlusionQuery; } m_occlusionQuery;
// Active objects // Active objects
std::vector<MetalCommandBuffer> m_commandBuffers; MetalCommandBuffer m_currentCommandBuffer{};
MetalEncoderType m_encoderType = MetalEncoderType::None; MetalEncoderType m_encoderType = MetalEncoderType::None;
MTL::CommandEncoder* m_commandEncoder = nullptr; MTL::CommandEncoder* m_commandEncoder = nullptr;