Fix #110293: Metal: Resolve tile corruption in Cycles render preview

PixelBuffer required addition of buffer re-allocation during mapping
to avoid host updates over-writing previous in-flight data as required
by the GPU. Changes allow multiple copies of existing pixel data to
be in-flight simultaneously.

Authored by Apple: Michael Parkin-White

Pull Request: https://projects.blender.org/blender/blender/pulls/110305
This commit is contained in:
Jason Fielder
2023-08-03 11:17:04 +02:00
committed by Clément Foucault
parent 110ea98ea2
commit 049f0798a3

View File

@@ -2223,18 +2223,11 @@ id<MTLTexture> MTLTexture::get_non_srgb_handle()
MTLPixelBuffer::MTLPixelBuffer(uint size) : PixelBuffer(size)
{
MTLContext *ctx = MTLContext::get();
BLI_assert(ctx);
/* Ensure buffer satisfies the alignment of 256 bytes for copying
* data between buffers and textures. As specified in:
* https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf */
BLI_assert(size >= 256);
MTLResourceOptions resource_options = ([ctx->device hasUnifiedMemory]) ?
MTLResourceStorageModeShared :
MTLResourceStorageModeManaged;
buffer_ = [ctx->device newBufferWithLength:size options:resource_options];
BLI_assert(buffer_ != nil);
buffer_ = nil;
}
MTLPixelBuffer::~MTLPixelBuffer()
@@ -2247,8 +2240,23 @@ MTLPixelBuffer::~MTLPixelBuffer()
void *MTLPixelBuffer::map()
{
if (buffer_ == nil) {
return nullptr;
/* Duplicate the existing buffer and release original to ensure we do not directly modify data
* in-flight on the GPU. */
MTLContext *ctx = MTLContext::get();
BLI_assert(ctx);
MTLResourceOptions resource_options = ([ctx->device hasUnifiedMemory]) ?
MTLResourceStorageModeShared :
MTLResourceStorageModeManaged;
if (buffer_ != nil) {
id<MTLBuffer> new_buffer = [ctx->device newBufferWithBytes:[buffer_ contents]
length:size_
options:resource_options];
[buffer_ release];
buffer_ = new_buffer;
}
else {
buffer_ = [ctx->device newBufferWithLength:size_ options:resource_options];
}
return [buffer_ contents];