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;
// Per frame data
uint32 m_commandBuffers = 0;
uint32 m_renderPasses = 0;
uint32 m_clears = 0;
uint32 m_manualVertexFetchDraws = 0;
@ -17,6 +18,7 @@ public:
void ResetPerFrameData()
{
m_commandBuffers = 0;
m_renderPasses = 0;
m_clears = 0;
m_manualVertexFetchDraws = 0;

View File

@ -37,9 +37,8 @@ void LatteQueryObjectMtl::end()
{
m_range.end = m_mtlr->GetOcclusionQueryIndex();
m_mtlr->EndOcclusionQuery();
m_commandBuffer = m_mtlr->GetCurrentCommandBuffer()->retain();
if (m_mtlr->IsCommandBufferActive())
{
m_commandBuffer = m_mtlr->GetCurrentCommandBuffer()->retain();
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)
CommitCommandBuffer();
m_commandBuffers.clear();
// Release frame persistent buffers
m_memoryManager->GetFramePersistentBufferAllocator().ResetAllocations();
@ -318,12 +317,9 @@ void MetalRenderer::Flush(bool waitIdle)
CommitCommandBuffer();
if (waitIdle)
{
for (auto commandBuffer : m_commandBuffers)
{
cemu_assert_debug(commandBuffer.m_commited);
cemu_assert_debug(m_currentCommandBuffer.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("--- 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("Clears %u", m_performanceMonitor.m_clears);
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()
{
bool needsNewCommandBuffer = (m_commandBuffers.empty() || m_commandBuffers.back().m_commited);
bool needsNewCommandBuffer = (!m_currentCommandBuffer.m_commandBuffer || m_currentCommandBuffer.m_commited);
if (needsNewCommandBuffer)
{
// Debug
//m_commandQueue->insertDebugCaptureBoundary();
MTL::CommandBuffer* mtlCommandBuffer = m_commandQueue->commandBuffer();
m_commandBuffers.push_back({mtlCommandBuffer});
m_currentCommandBuffer = {mtlCommandBuffer};
m_recordedDrawcalls = 0;
m_commitTreshold = m_defaultCommitTreshlod;
@ -1442,11 +1438,14 @@ MTL::CommandBuffer* MetalRenderer::GetCommandBuffer()
// Notify memory manager about the new command buffer
m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(mtlCommandBuffer);
// Debug
m_performanceMonitor.m_commandBuffers++;
return mtlCommandBuffer;
}
else
{
return m_commandBuffers.back().m_commandBuffer;
return m_currentCommandBuffer.m_commandBuffer;
}
}
@ -1594,27 +1593,26 @@ void MetalRenderer::EndEncoding()
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();
if (!commandBuffer.m_commited)
{
// 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);
//});
m_currentCommandBuffer.m_commandBuffer->commit();
m_currentCommandBuffer.m_commandBuffer->release();
m_currentCommandBuffer.m_commited = true;
commandBuffer.m_commandBuffer->commit();
commandBuffer.m_commandBuffer->release();
commandBuffer.m_commited = true;
m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(nullptr);
m_memoryManager->GetTemporaryBufferAllocator().SetActiveCommandBuffer(nullptr);
// Debug
//m_commandQueue->insertDebugCaptureBoundary();
}
// Debug
//m_commandQueue->insertDebugCaptureBoundary();
}
}

View File

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