mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 13:34:18 +01:00
refactor command buffers
This commit is contained in:
parent
552c4901b9
commit
c46c8214f5
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user