diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h index 8edde975..8becc7a3 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.h @@ -79,6 +79,7 @@ protected: VkBufferMemoryBarrier* pBufferMemoryBarrier); id _mtlBuffer; + std::mutex _lock; }; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm index 5503cabe..f594e7a6 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKBuffer.mm @@ -154,6 +154,13 @@ id MVKBuffer::getMTLBuffer() { if (_mtlBuffer) { return _mtlBuffer; } + lock_guard lock(_lock); + + // Check again in case another thread has created the buffer. + if (_mtlBuffer) { + return _mtlBuffer; + } + id devMemMTLBuff = _deviceMemory->getMTLBuffer(); if (devMemMTLBuff) { return devMemMTLBuff; } diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h index 9db7b7d7..c0a2ae11 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h @@ -222,6 +222,7 @@ protected: MTLPixelFormat _mtlPixelFormat; MTLTextureType _mtlTextureType; id _mtlTexture; + std::mutex _lock; IOSurfaceRef _ioSurface; bool _isDepthStencilAttachment; bool _canSupportMTLTextureView; @@ -279,6 +280,7 @@ protected: MVKImage* _image; VkImageSubresourceRange _subresourceRange; id _mtlTexture; + std::mutex _lock; MTLPixelFormat _mtlPixelFormat; MTLTextureType _mtlTextureType; bool _useMTLTextureView; diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm index 7efe093a..9fde386c 100644 --- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm +++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.mm @@ -215,7 +215,13 @@ void* MVKImage::map(VkDeviceSize offset, VkDeviceSize size) { #pragma mark Metal id MVKImage::getMTLTexture() { - if ( !_mtlTexture && _mtlPixelFormat ) { _mtlTexture = newMTLTexture(); } // retained + if ( !_mtlTexture && _mtlPixelFormat ) { + lock_guard lock(_lock); + // Check again in case another thread has created the texture. + if ( !_mtlTexture ) { + _mtlTexture = newMTLTexture(); + } + } // retained return _mtlTexture; } @@ -537,7 +543,13 @@ void MVKImageView::populateMTLRenderPassAttachmentDescriptorResolve(MTLRenderPas id MVKImageView::getMTLTexture() { // If we can use a Metal texture view, lazily create it, otherwise use the image texture directly. if (_useMTLTextureView) { - if ( !_mtlTexture && _mtlPixelFormat ) { _mtlTexture = newMTLTexture(); } // retained + if ( !_mtlTexture && _mtlPixelFormat ) { + lock_guard lock(_lock); + // Check again in case another thread created the texture view + if ( !_mtlTexture ) { + _mtlTexture = newMTLTexture(); // retained + } + } return _mtlTexture; } else { return _image->getMTLTexture();