allocate special buffers only when needed

This commit is contained in:
Samuliak 2024-09-14 17:12:02 +02:00
parent 02254d4e57
commit 008c11ce71
3 changed files with 44 additions and 22 deletions

View File

@ -248,11 +248,18 @@ public:
void SetActiveCommandBuffer(MTL::CommandBuffer* commandBuffer)
{
m_activeCommandBuffer = commandBuffer;
if (commandBuffer)
{
auto result = m_executingCommandBuffers.emplace(std::make_pair(m_activeCommandBuffer, std::vector<uint32>{}));
cemu_assert_debug(result.second);
m_activeCommandBufferIt = result.first;
commandBuffer->retain();
}
else
{
m_activeCommandBufferIt = m_executingCommandBuffers.end();
}
}
void CheckForCompletedCommandBuffers(/*MTL::CommandBuffer* commandBuffer, bool erase = true*/)
{

View File

@ -83,19 +83,6 @@ MetalRenderer::MetalRenderer()
m_depthStencilCache = new MetalDepthStencilCache(this);
m_samplerCache = new MetalSamplerCache(this);
// Texture readback
m_readbackBuffer = m_device->newBuffer(TEXTURE_READBACK_SIZE, MTL::ResourceStorageModeShared);
#ifdef CEMU_DEBUG_ASSERT
m_readbackBuffer->setLabel(GetLabel("Texture readback buffer", m_readbackBuffer));
#endif
// Transform feedback
// HACK: using just LatteStreamout_GetRingBufferSize will cause page faults
m_xfbRingBuffer = m_device->newBuffer(LatteStreamout_GetRingBufferSize() * 4, MTL::ResourceStorageModePrivate);
#ifdef CEMU_DEBUG_ASSERT
m_xfbRingBuffer->setLabel(GetLabel("Transform feedback buffer", m_xfbRingBuffer));
#endif
// Occlusion queries
m_occlusionQuery.m_resultBuffer = m_device->newBuffer(OCCLUSION_QUERY_POOL_SIZE * sizeof(uint64), MTL::ResourceStorageModeShared);
#ifdef CEMU_DEBUG_ASSERT
@ -196,8 +183,14 @@ MetalRenderer::~MetalRenderer()
m_nearestSampler->release();
m_linearSampler->release();
if (m_readbackBuffer)
m_readbackBuffer->release();
if (m_xfbRingBuffer)
m_xfbRingBuffer->release();
m_occlusionQuery.m_resultBuffer->release();
m_commandQueue->release();
m_device->release();
}
@ -794,7 +787,7 @@ void MetalRenderer::bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32
void MetalRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size)
{
CopyBufferToBuffer(m_xfbRingBuffer, srcOffset, m_memoryManager->GetBufferCache(), dstOffset, size, MTL::RenderStageVertex, ALL_MTL_RENDER_STAGES);
CopyBufferToBuffer(GetXfbRingBuffer(), srcOffset, m_memoryManager->GetBufferCache(), dstOffset, size, MTL::RenderStageVertex, ALL_MTL_RENDER_STAGES);
}
void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size)

View File

@ -380,11 +380,33 @@ public:
return (m_hasUnifiedMemory ? MTL::ResourceStorageModeShared : MTL::ResourceStorageModeManaged);
}
MTL::Buffer* GetTextureReadbackBuffer() const
MTL::Buffer* GetTextureReadbackBuffer()
{
if (!m_readbackBuffer)
{
m_readbackBuffer = m_device->newBuffer(TEXTURE_READBACK_SIZE, MTL::ResourceStorageModeShared);
#ifdef CEMU_DEBUG_ASSERT
m_readbackBuffer->setLabel(GetLabel("Texture readback buffer", m_readbackBuffer));
#endif
}
return m_readbackBuffer;
}
MTL::Buffer* GetXfbRingBuffer()
{
if (!m_xfbRingBuffer)
{
// HACK: using just LatteStreamout_GetRingBufferSize will cause page faults
m_xfbRingBuffer = m_device->newBuffer(LatteStreamout_GetRingBufferSize() * 4, MTL::ResourceStorageModePrivate);
#ifdef CEMU_DEBUG_ASSERT
m_xfbRingBuffer->setLabel(GetLabel("Transform feedback buffer", m_xfbRingBuffer));
#endif
}
return m_xfbRingBuffer;
}
MTL::Buffer* GetOcclusionQueryResultBuffer() const
{
return m_occlusionQuery.m_resultBuffer;
@ -460,11 +482,11 @@ private:
MTL::Texture* m_nullTexture2D;
// Texture readback
MTL::Buffer* m_readbackBuffer;
MTL::Buffer* m_readbackBuffer = nullptr;
uint32 m_readbackBufferWriteOffset = 0;
// Transform feedback
MTL::Buffer* m_xfbRingBuffer;
MTL::Buffer* m_xfbRingBuffer = nullptr;
// Occlusion queries
struct