Fix intermittent corruption uploading textures in Dota 2.
The problem was that MVKBuffer::getMTLBuffer() was not thread-safe. If multiple threads called it at the same time, more than one underlying _mtlBuffer would be created. This could make the vkCmdCopyBufferToImage copy from an unfilled buffer leaving the texture corrupted. I also added similar thread safety to MVKImage::getMTLTexture() and MVKImageView::getMTLTexture() since they both looked like they would have the same potential problem.
This commit is contained in:
parent
d1cd122201
commit
6d50a88178
@ -79,6 +79,7 @@ protected:
|
||||
VkBufferMemoryBarrier* pBufferMemoryBarrier);
|
||||
|
||||
id<MTLBuffer> _mtlBuffer;
|
||||
std::mutex _lock;
|
||||
};
|
||||
|
||||
|
||||
|
@ -154,6 +154,13 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
|
||||
if (_mtlBuffer) { return _mtlBuffer; }
|
||||
|
||||
lock_guard<mutex> lock(_lock);
|
||||
|
||||
// Check again in case another thread has created the buffer.
|
||||
if (_mtlBuffer) {
|
||||
return _mtlBuffer;
|
||||
}
|
||||
|
||||
id<MTLBuffer> devMemMTLBuff = _deviceMemory->getMTLBuffer();
|
||||
if (devMemMTLBuff) { return devMemMTLBuff; }
|
||||
|
||||
|
@ -222,6 +222,7 @@ protected:
|
||||
MTLPixelFormat _mtlPixelFormat;
|
||||
MTLTextureType _mtlTextureType;
|
||||
id<MTLTexture> _mtlTexture;
|
||||
std::mutex _lock;
|
||||
IOSurfaceRef _ioSurface;
|
||||
bool _isDepthStencilAttachment;
|
||||
bool _canSupportMTLTextureView;
|
||||
@ -279,6 +280,7 @@ protected:
|
||||
MVKImage* _image;
|
||||
VkImageSubresourceRange _subresourceRange;
|
||||
id<MTLTexture> _mtlTexture;
|
||||
std::mutex _lock;
|
||||
MTLPixelFormat _mtlPixelFormat;
|
||||
MTLTextureType _mtlTextureType;
|
||||
bool _useMTLTextureView;
|
||||
|
@ -215,7 +215,13 @@ void* MVKImage::map(VkDeviceSize offset, VkDeviceSize size) {
|
||||
#pragma mark Metal
|
||||
|
||||
id<MTLTexture> MVKImage::getMTLTexture() {
|
||||
if ( !_mtlTexture && _mtlPixelFormat ) { _mtlTexture = newMTLTexture(); } // retained
|
||||
if ( !_mtlTexture && _mtlPixelFormat ) {
|
||||
lock_guard<mutex> 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<MTLTexture> 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<mutex> lock(_lock);
|
||||
// Check again in case another thread created the texture view
|
||||
if ( !_mtlTexture ) {
|
||||
_mtlTexture = newMTLTexture(); // retained
|
||||
}
|
||||
}
|
||||
return _mtlTexture;
|
||||
} else {
|
||||
return _image->getMTLTexture();
|
||||
|
Loading…
x
Reference in New Issue
Block a user