diff --git a/cocos/renderer/backend/metal/BufferMTL.h b/cocos/renderer/backend/metal/BufferMTL.h index 4ce742ae99f7..d55716ab170e 100644 --- a/cocos/renderer/backend/metal/BufferMTL.h +++ b/cocos/renderer/backend/metal/BufferMTL.h @@ -86,7 +86,7 @@ class BufferMTL : public Buffer void beginFrame(); private: - void updateIndex(); + void inflightBuffer(std::size_t offset, std::size_t size); id _mtlBuffer = nil; NSMutableArray* _dynamicDataBuffers = nil; diff --git a/cocos/renderer/backend/metal/BufferMTL.mm b/cocos/renderer/backend/metal/BufferMTL.mm index 9abe3d62a4a4..f2f15567a66f 100644 --- a/cocos/renderer/backend/metal/BufferMTL.mm +++ b/cocos/renderer/backend/metal/BufferMTL.mm @@ -71,14 +71,14 @@ of this software and associated documentation files (the "Software"), to deal void BufferMTL::updateData(void* data, std::size_t size) { assert(size <= _size); - updateIndex(); + inflightBuffer(0, size); memcpy((uint8_t*)_mtlBuffer.contents, data, size); } void BufferMTL::updateSubData(void* data, std::size_t offset, std::size_t size) { assert(offset + size <= _size); - updateIndex(); + inflightBuffer(offset, size); memcpy((uint8_t*)_mtlBuffer.contents + offset, data, size); } @@ -92,12 +92,22 @@ of this software and associated documentation files (the "Software"), to deal _indexUpdated = false; } -void BufferMTL::updateIndex() +void BufferMTL::inflightBuffer(std::size_t offset, std::size_t size) { if (BufferUsage::DYNAMIC == _usage && !_indexUpdated) { _currentFrameIndex = (_currentFrameIndex + 1) % MAX_INFLIGHT_BUFFER; + id prevFrameBuffer = _mtlBuffer; _mtlBuffer = _dynamicDataBuffers[_currentFrameIndex]; + if(offset) + { + memcpy((uint8_t*)_mtlBuffer.contents, prevFrameBuffer.contents, offset); + } + offset += size; + if(offset < _size) + { + memcpy((uint8_t*)_mtlBuffer.contents + offset, (uint8_t*)prevFrameBuffer.contents + offset, _size - offset); + } _indexUpdated = true; } }