synchronize buffer copying correctly

This commit is contained in:
Samuliak 2024-08-30 15:27:55 +02:00
parent 1412d1e70a
commit 9c29acc635
4 changed files with 10 additions and 9 deletions

View File

@ -60,3 +60,5 @@ inline NS::String* GetLabel(const std::string& label, const void* identifier)
{ {
return ToNSString(label + " (" + std::to_string(reinterpret_cast<uintptr_t>(identifier)) + ")"); return ToNSString(label + " (" + std::to_string(reinterpret_cast<uintptr_t>(identifier)) + ")");
} }
constexpr MTL::RenderStages ALL_MTL_RENDER_STAGES = MTL::RenderStageVertex | MTL::RenderStageObject | MTL::RenderStageMesh | MTL::RenderStageFragment;

View File

@ -139,7 +139,7 @@ void MetalMemoryManager::UploadToBufferCache(const void* data, size_t offset, si
// Lock the buffer to make sure it's not deallocated before the copy is done // Lock the buffer to make sure it's not deallocated before the copy is done
m_tempBufferAllocator.LockBuffer(allocation.bufferIndex); m_tempBufferAllocator.LockBuffer(allocation.bufferIndex);
m_mtlr->CopyBufferToBuffer(buffer, allocation.offset, m_bufferCache, offset, size); m_mtlr->CopyBufferToBuffer(buffer, allocation.offset, m_bufferCache, offset, size, ALL_MTL_RENDER_STAGES, ALL_MTL_RENDER_STAGES);
// Make sure the buffer has the right command buffer // Make sure the buffer has the right command buffer
m_tempBufferAllocator.GetBuffer(allocation.bufferIndex); // TODO: make a helper function for this m_tempBufferAllocator.GetBuffer(allocation.bufferIndex); // TODO: make a helper function for this
@ -155,5 +155,5 @@ void MetalMemoryManager::CopyBufferCache(size_t srcOffset, size_t dstOffset, siz
{ {
cemu_assert_debug(m_bufferCache); cemu_assert_debug(m_bufferCache);
m_mtlr->CopyBufferToBuffer(m_bufferCache, srcOffset, m_bufferCache, dstOffset, size); m_mtlr->CopyBufferToBuffer(m_bufferCache, srcOffset, m_bufferCache, dstOffset, size, ALL_MTL_RENDER_STAGES, ALL_MTL_RENDER_STAGES);
} }

View File

@ -20,6 +20,7 @@
#include "HW/Latte/Renderer/Metal/MetalCommon.h" #include "HW/Latte/Renderer/Metal/MetalCommon.h"
#include "HW/Latte/Renderer/Metal/MetalLayerHandle.h" #include "HW/Latte/Renderer/Metal/MetalLayerHandle.h"
#include "HW/Latte/Renderer/Renderer.h" #include "HW/Latte/Renderer/Renderer.h"
#include "Metal/MTLRenderCommandEncoder.hpp"
#include "imgui.h" #include "imgui.h"
#define IMGUI_IMPL_METAL_CPP #define IMGUI_IMPL_METAL_CPP
@ -780,7 +781,7 @@ void MetalRenderer::bufferCache_copy(uint32 srcOffset, uint32 dstOffset, uint32
void MetalRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size) void MetalRenderer::bufferCache_copyStreamoutToMainBuffer(uint32 srcOffset, uint32 dstOffset, uint32 size)
{ {
CopyBufferToBuffer(m_xfbRingBuffer, srcOffset, m_memoryManager->GetBufferCache(), dstOffset, size); CopyBufferToBuffer(m_xfbRingBuffer, srcOffset, m_memoryManager->GetBufferCache(), dstOffset, size, MTL::RenderStageVertex, ALL_MTL_RENDER_STAGES);
} }
void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size) void MetalRenderer::buffer_bindVertexBuffer(uint32 bufferIndex, uint32 offset, uint32 size)
@ -1834,7 +1835,7 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
EndEncoding(); EndEncoding();
} }
void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size) void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size, MTL::RenderStages after, MTL::RenderStages before)
{ {
// Do the copy in a vertex shader on Apple GPUs // Do the copy in a vertex shader on Apple GPUs
if (m_isAppleGPU && m_encoderType == MetalEncoderType::Render) if (m_isAppleGPU && m_encoderType == MetalEncoderType::Render)
@ -1842,8 +1843,7 @@ void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::
auto renderCommandEncoder = static_cast<MTL::RenderCommandEncoder*>(m_commandEncoder); auto renderCommandEncoder = static_cast<MTL::RenderCommandEncoder*>(m_commandEncoder);
MTL::Resource* barrierBuffers[] = {src}; MTL::Resource* barrierBuffers[] = {src};
// TODO: let the caller choose the stages renderCommandEncoder->memoryBarrier(barrierBuffers, 1, after, MTL::RenderStageVertex);
renderCommandEncoder->memoryBarrier(barrierBuffers, 1, MTL::RenderStageVertex | MTL::RenderStageFragment | MTL::RenderStageObject | MTL::RenderStageMesh, MTL::RenderStageVertex);
renderCommandEncoder->setRenderPipelineState(m_copyBufferToBufferPipeline->GetRenderPipelineState()); renderCommandEncoder->setRenderPipelineState(m_copyBufferToBufferPipeline->GetRenderPipelineState());
m_state.m_encoderState.m_renderPipelineState = m_copyBufferToBufferPipeline->GetRenderPipelineState(); m_state.m_encoderState.m_renderPipelineState = m_copyBufferToBufferPipeline->GetRenderPipelineState();
@ -1854,8 +1854,7 @@ void MetalRenderer::CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypePoint, NS::UInteger(0), NS::UInteger(size)); renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypePoint, NS::UInteger(0), NS::UInteger(size));
barrierBuffers[0] = dst; barrierBuffers[0] = dst;
// TODO: let the caller choose the stages renderCommandEncoder->memoryBarrier(barrierBuffers, 1, MTL::RenderStageVertex, before);
renderCommandEncoder->memoryBarrier(barrierBuffers, 1, MTL::RenderStageVertex, MTL::RenderStageVertex | MTL::RenderStageFragment | MTL::RenderStageObject | MTL::RenderStageMesh);
} }
else else
{ {

View File

@ -377,7 +377,7 @@ public:
void ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a); void ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a);
void CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size); void CopyBufferToBuffer(MTL::Buffer* src, uint32 srcOffset, MTL::Buffer* dst, uint32 dstOffset, uint32 size, MTL::RenderStages after, MTL::RenderStages before);
// Getters // Getters
bool IsAppleGPU() const bool IsAppleGPU() const