mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 20:44:18 +01:00
use buffer allocator for restrided vertex buffers
This commit is contained in:
parent
27925a4fd9
commit
bba2bbcefb
@ -70,17 +70,6 @@ MetalBufferAllocation MetalBufferAllocator::GetBufferAllocation(size_t size, siz
|
|||||||
|
|
||||||
MetalVertexBufferCache::~MetalVertexBufferCache()
|
MetalVertexBufferCache::~MetalVertexBufferCache()
|
||||||
{
|
{
|
||||||
for (uint32 i = 0; i < LATTE_MAX_VERTEX_BUFFERS; i++)
|
|
||||||
{
|
|
||||||
auto vertexBufferRange = m_bufferRanges[i];
|
|
||||||
if (vertexBufferRange.offset != INVALID_OFFSET)
|
|
||||||
{
|
|
||||||
if (vertexBufferRange.restrideInfo->buffer)
|
|
||||||
{
|
|
||||||
vertexBufferRange.restrideInfo->buffer->release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Buffer* bufferCache, uint32 bufferIndex, size_t stride)
|
MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Buffer* bufferCache, uint32 bufferIndex, size_t stride)
|
||||||
@ -94,17 +83,12 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu
|
|||||||
return {bufferCache, vertexBufferRange.offset};
|
return {bufferCache, vertexBufferRange.offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto buffer = m_bufferAllocator->GetBuffer(restrideInfo.allocation.bufferIndex);
|
||||||
if (restrideInfo.memoryInvalidated || stride != restrideInfo.lastStride)
|
if (restrideInfo.memoryInvalidated || stride != restrideInfo.lastStride)
|
||||||
{
|
{
|
||||||
size_t newStride = Align(stride, 4);
|
size_t newStride = Align(stride, 4);
|
||||||
size_t newSize = vertexBufferRange.size / stride * newStride;
|
size_t newSize = vertexBufferRange.size / stride * newStride;
|
||||||
if (!restrideInfo.buffer || newSize != restrideInfo.buffer->length())
|
restrideInfo.allocation = m_bufferAllocator->GetBufferAllocation(newSize, 4);
|
||||||
{
|
|
||||||
if (restrideInfo.buffer)
|
|
||||||
restrideInfo.buffer->release();
|
|
||||||
// TODO: use one big buffer for all restrided buffers
|
|
||||||
restrideInfo.buffer = m_mtlr->GetDevice()->newBuffer(newSize, MTL::StorageModeShared);
|
|
||||||
}
|
|
||||||
|
|
||||||
//uint8* oldPtr = (uint8*)bufferCache->contents() + vertexBufferRange.offset;
|
//uint8* oldPtr = (uint8*)bufferCache->contents() + vertexBufferRange.offset;
|
||||||
//uint8* newPtr = (uint8*)restrideInfo.buffer->contents();
|
//uint8* newPtr = (uint8*)restrideInfo.buffer->contents();
|
||||||
@ -120,8 +104,8 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu
|
|||||||
auto renderCommandEncoder = static_cast<MTL::RenderCommandEncoder*>(m_mtlr->GetCommandEncoder());
|
auto renderCommandEncoder = static_cast<MTL::RenderCommandEncoder*>(m_mtlr->GetCommandEncoder());
|
||||||
|
|
||||||
renderCommandEncoder->setRenderPipelineState(m_restrideBufferPipeline->GetRenderPipelineState());
|
renderCommandEncoder->setRenderPipelineState(m_restrideBufferPipeline->GetRenderPipelineState());
|
||||||
MTL::Buffer* buffers[] = {bufferCache, restrideInfo.buffer};
|
MTL::Buffer* buffers[] = {bufferCache, buffer};
|
||||||
size_t offsets[] = {vertexBufferRange.offset, 0};
|
size_t offsets[] = {vertexBufferRange.offset, restrideInfo.allocation.bufferOffset};
|
||||||
renderCommandEncoder->setVertexBuffers(buffers, offsets, NS::Range(0, 2));
|
renderCommandEncoder->setVertexBuffers(buffers, offsets, NS::Range(0, 2));
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -133,7 +117,8 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu
|
|||||||
|
|
||||||
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypePoint, NS::UInteger(0), vertexBufferRange.size / stride);
|
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypePoint, NS::UInteger(0), vertexBufferRange.size / stride);
|
||||||
|
|
||||||
MTL::Resource* barrierBuffers[] = {restrideInfo.buffer};
|
// TODO: restride in one call?
|
||||||
|
MTL::Resource* barrierBuffers[] = {buffer};
|
||||||
renderCommandEncoder->memoryBarrier(barrierBuffers, 1, MTL::RenderStageVertex, MTL::RenderStageVertex);
|
renderCommandEncoder->memoryBarrier(barrierBuffers, 1, MTL::RenderStageVertex, MTL::RenderStageVertex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -146,7 +131,7 @@ MetalRestridedBufferRange MetalVertexBufferCache::RestrideBufferIfNeeded(MTL::Bu
|
|||||||
restrideInfo.lastStride = newStride;
|
restrideInfo.lastStride = newStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {restrideInfo.buffer, 0};
|
return {buffer, restrideInfo.allocation.bufferOffset};
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetalVertexBufferCache::MemoryRangeChanged(size_t offset, size_t size)
|
void MetalVertexBufferCache::MemoryRangeChanged(size_t offset, size_t size)
|
||||||
|
@ -10,7 +10,12 @@ struct MetalBufferAllocation
|
|||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
uint32 bufferIndex;
|
uint32 bufferIndex;
|
||||||
size_t bufferOffset;
|
size_t bufferOffset = INVALID_OFFSET;
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
return bufferOffset != INVALID_OFFSET;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MetalBufferRange
|
struct MetalBufferRange
|
||||||
@ -62,7 +67,7 @@ struct MetalRestrideInfo
|
|||||||
{
|
{
|
||||||
bool memoryInvalidated = true;
|
bool memoryInvalidated = true;
|
||||||
size_t lastStride = 0;
|
size_t lastStride = 0;
|
||||||
MTL::Buffer* buffer = nullptr;
|
MetalBufferAllocation allocation{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MetalVertexBufferRange
|
struct MetalVertexBufferRange
|
||||||
@ -77,7 +82,7 @@ class MetalVertexBufferCache
|
|||||||
public:
|
public:
|
||||||
friend class MetalMemoryManager;
|
friend class MetalMemoryManager;
|
||||||
|
|
||||||
MetalVertexBufferCache(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {}
|
MetalVertexBufferCache(class MetalRenderer* metalRenderer, MetalBufferAllocator* bufferAllocator) : m_mtlr{metalRenderer}, m_bufferAllocator{bufferAllocator} {}
|
||||||
~MetalVertexBufferCache();
|
~MetalVertexBufferCache();
|
||||||
|
|
||||||
void SetRestrideBufferPipeline(class MetalHybridComputePipeline* restrideBufferPipeline)
|
void SetRestrideBufferPipeline(class MetalHybridComputePipeline* restrideBufferPipeline)
|
||||||
@ -93,10 +98,6 @@ public:
|
|||||||
void UntrackVertexBuffer(uint32 bufferIndex)
|
void UntrackVertexBuffer(uint32 bufferIndex)
|
||||||
{
|
{
|
||||||
auto& range = m_bufferRanges[bufferIndex];
|
auto& range = m_bufferRanges[bufferIndex];
|
||||||
if (range.restrideInfo->buffer)
|
|
||||||
{
|
|
||||||
range.restrideInfo->buffer->release();
|
|
||||||
}
|
|
||||||
range.offset = INVALID_OFFSET;
|
range.offset = INVALID_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +105,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
class MetalRenderer* m_mtlr;
|
class MetalRenderer* m_mtlr;
|
||||||
|
MetalBufferAllocator* m_bufferAllocator;
|
||||||
|
|
||||||
class MetalHybridComputePipeline* m_restrideBufferPipeline = nullptr;
|
class MetalHybridComputePipeline* m_restrideBufferPipeline = nullptr;
|
||||||
|
|
||||||
@ -115,7 +117,7 @@ private:
|
|||||||
class MetalMemoryManager
|
class MetalMemoryManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MetalMemoryManager(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer}, m_bufferAllocator(metalRenderer), m_vertexBufferCache(metalRenderer) {}
|
MetalMemoryManager(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer}, m_bufferAllocator(metalRenderer), m_vertexBufferCache(metalRenderer, &m_bufferAllocator) {}
|
||||||
~MetalMemoryManager();
|
~MetalMemoryManager();
|
||||||
|
|
||||||
// Pipelines
|
// Pipelines
|
||||||
|
@ -795,7 +795,7 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_activeFBO, LatteGPUState.contextNew);
|
MTL::RenderPipelineState* renderPipelineState = m_pipelineCache->GetPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO, LatteGPUState.contextNew);
|
||||||
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
|
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
|
||||||
|
|
||||||
// Uniform buffers, textures and samplers
|
// Uniform buffers, textures and samplers
|
||||||
|
Loading…
Reference in New Issue
Block a user