Metal: Fix buffer alignment issues on Mac

Bug: skia:8243
Change-Id: I9d588c732e9aba2348a294cd88f17d261ba05f03
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255088
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2019-11-18 13:10:27 -05:00 committed by Skia Commit-Bot
parent 63edc57c97
commit 7c4ea9083f
2 changed files with 19 additions and 2 deletions

View File

@ -41,6 +41,11 @@ GrMtlBuffer::GrMtlBuffer(GrMtlGpu* gpu, size_t size, GrGpuBufferType intendedTyp
if (@available(macOS 10.11, iOS 9.0, *)) { if (@available(macOS 10.11, iOS 9.0, *)) {
options |= MTLResourceStorageModePrivate; options |= MTLResourceStorageModePrivate;
} }
#ifdef SK_BUILD_FOR_MAC
// Mac requires 4-byte alignment for copies so we need
// to ensure we have space for the extra data
size = GrSizeAlignUp(size, 4);
#endif
fMtlBuffer = size == 0 ? nil : fMtlBuffer = size == 0 ? nil :
[gpu->device() newBufferWithLength: size [gpu->device() newBufferWithLength: size
options: options]; options: options];
@ -77,7 +82,7 @@ bool GrMtlBuffer::onUpdateData(const void* src, size_t srcInBytes) {
} }
SkASSERT(fMappedBuffer); SkASSERT(fMappedBuffer);
if (!fIsDynamic) { if (!fIsDynamic) {
SkASSERT(srcInBytes == fMappedBuffer.length); SkASSERT(GrSizeAlignUp(srcInBytes, 4) == fMappedBuffer.length);
} }
memcpy(fMapPtr, src, srcInBytes); memcpy(fMapPtr, src, srcInBytes);
this->internalUnmap(srcInBytes); this->internalUnmap(srcInBytes);
@ -129,6 +134,10 @@ void GrMtlBuffer::internalMap(size_t sizeInBytes) {
if (@available(macOS 10.11, iOS 9.0, *)) { if (@available(macOS 10.11, iOS 9.0, *)) {
options |= MTLResourceStorageModeShared; options |= MTLResourceStorageModeShared;
} }
#ifdef SK_BUILD_FOR_MAC
// Mac requires 4-byte alignment for copies so we pad this out
sizeInBytes = GrSizeAlignUp(sizeInBytes, 4);
#endif
fMappedBuffer = fMappedBuffer =
[this->mtlGpu()->device() newBufferWithLength: sizeInBytes [this->mtlGpu()->device() newBufferWithLength: sizeInBytes
options: options]; options: options];
@ -149,9 +158,13 @@ void GrMtlBuffer::internalUnmap(size_t sizeInBytes) {
fMapPtr = nullptr; fMapPtr = nullptr;
return; return;
} }
#ifdef SK_BUILD_FOR_MAC
// In both cases the size needs to be 4-byte aligned on Mac
sizeInBytes = GrSizeAlignUp(sizeInBytes, 4);
#endif
if (fIsDynamic) { if (fIsDynamic) {
#ifdef SK_BUILD_FOR_MAC #ifdef SK_BUILD_FOR_MAC
// TODO: need to make sure offset and size have valid alignments. SkASSERT(0 == (fOffset & 0x3)); // should be 4-byte aligned
[fMtlBuffer didModifyRange: NSMakeRange(fOffset, sizeInBytes)]; [fMtlBuffer didModifyRange: NSMakeRange(fOffset, sizeInBytes)];
#endif #endif
} else { } else {

View File

@ -262,6 +262,10 @@ void GrMtlResourceProvider::BufferSuballocator::addCompletionHandler(
} }
id<MTLBuffer> GrMtlResourceProvider::getDynamicBuffer(size_t size, size_t* offset) { id<MTLBuffer> GrMtlResourceProvider::getDynamicBuffer(size_t size, size_t* offset) {
#ifdef SK_BUILD_FOR_MAC
// Mac requires 4-byte alignment for didModifyRange:
size = GrSizeAlignUp(size, 4);
#endif
id<MTLBuffer> buffer = fBufferSuballocator->getAllocation(size, offset); id<MTLBuffer> buffer = fBufferSuballocator->getAllocation(size, offset);
if (buffer) { if (buffer) {
return buffer; return buffer;