Updates to Metal resource locking.
MVKBufferView add lock when creating MTLTexture. MVKDeviceMemory add lock when creating MTLBuffer during memory mapping. MVKMTLBufferAllocator does not need to be threadsafe. Cleanup syntax on other lock handling to add consistency.
This commit is contained in:
parent
a1b5ea5494
commit
13687d1a57
@ -130,14 +130,16 @@ public:
|
||||
* maximum size. Because MVKMTLBufferRegions are created with a power-of-two size,
|
||||
* the largest size of a MVKMTLBufferAllocation dispensed by this instance will be the
|
||||
* next power-of-two value that is at least as big as the specified maximum size.
|
||||
* If makeThreadSafe is true, a lock will be applied when an allocation is acquired.
|
||||
*/
|
||||
MVKMTLBufferAllocator(MVKDevice* device, NSUInteger maxRegionLength);
|
||||
MVKMTLBufferAllocator(MVKDevice* device, NSUInteger maxRegionLength, bool makeThreadSafe = false);
|
||||
|
||||
~MVKMTLBufferAllocator() override;
|
||||
|
||||
protected:
|
||||
std::vector<MVKMTLBufferAllocationPool*> _regionPools;
|
||||
NSUInteger _maxAllocationLength;
|
||||
bool _makeThreadSafe;
|
||||
|
||||
};
|
||||
|
||||
|
@ -80,11 +80,13 @@ const MVKMTLBufferAllocation* MVKMTLBufferAllocator::acquireMTLBufferRegion(NSUI
|
||||
|
||||
// Convert max length to the next power-of-two exponent to use as a lookup
|
||||
uint32_t p2Exp = mvkPowerOfTwoExponent(length);
|
||||
return _regionPools[p2Exp]->acquireObjectSafely();
|
||||
MVKMTLBufferAllocationPool* pRP = _regionPools[p2Exp];
|
||||
return _makeThreadSafe ? pRP->acquireObjectSafely() : pRP->acquireObject();
|
||||
}
|
||||
|
||||
MVKMTLBufferAllocator::MVKMTLBufferAllocator(MVKDevice* device, NSUInteger maxAllocationLength) : MVKBaseDeviceObject(device) {
|
||||
_maxAllocationLength = maxAllocationLength;
|
||||
MVKMTLBufferAllocator::MVKMTLBufferAllocator(MVKDevice* device, NSUInteger maxRegionLength, bool makeThreadSafe) : MVKBaseDeviceObject(device) {
|
||||
_maxAllocationLength = maxRegionLength;
|
||||
_makeThreadSafe = makeThreadSafe;
|
||||
|
||||
// Convert max length to the next power-of-two exponent
|
||||
uint32_t maxP2Exp = mvkPowerOfTwoExponent(_maxAllocationLength);
|
||||
|
@ -122,5 +122,6 @@ protected:
|
||||
id<MTLTexture> _mtlTexture;
|
||||
VkDeviceSize _byteCount;
|
||||
VkExtent2D _textureSize;
|
||||
std::mutex _lock;
|
||||
};
|
||||
|
||||
|
@ -157,12 +157,9 @@ id<MTLBuffer> MVKBuffer::getMTLBuffer() {
|
||||
id<MTLBuffer> devMemMTLBuff = _deviceMemory->getMTLBuffer();
|
||||
if (devMemMTLBuff) { return devMemMTLBuff; }
|
||||
|
||||
// Lock and check again in case another thread has created the buffer.
|
||||
lock_guard<mutex> lock(_lock);
|
||||
|
||||
// Check again in case another thread has created the buffer.
|
||||
if (_mtlBuffer) {
|
||||
return _mtlBuffer;
|
||||
}
|
||||
if (_mtlBuffer) { return _mtlBuffer; }
|
||||
|
||||
NSUInteger mtlBuffLen = mvkAlignByteOffset(_byteCount, _byteAlignment);
|
||||
_mtlBuffer = [getMTLDevice() newBufferWithLength: mtlBuffLen
|
||||
@ -203,6 +200,11 @@ MVKBuffer::~MVKBuffer() {
|
||||
|
||||
id<MTLTexture> MVKBufferView::getMTLTexture() {
|
||||
if ( !_mtlTexture && _mtlPixelFormat && _device->_pMetalFeatures->texelBuffers) {
|
||||
|
||||
// Lock and check again in case another thread has created the texture.
|
||||
lock_guard<mutex> lock(_lock);
|
||||
if (_mtlTexture) { return _mtlTexture; }
|
||||
|
||||
VkDeviceSize byteAlign = _device->_pProperties->limits.minTexelBufferOffsetAlignment;
|
||||
NSUInteger mtlByteCnt = mvkAlignByteOffset(_byteCount, byteAlign);
|
||||
MTLTextureDescriptor* mtlTexDesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat: _mtlPixelFormat
|
||||
|
@ -120,6 +120,7 @@ protected:
|
||||
VkDeviceSize _mapOffset;
|
||||
VkDeviceSize _mapSize;
|
||||
id<MTLBuffer> _mtlBuffer;
|
||||
std::mutex _lock;
|
||||
MTLResourceOptions _mtlResourceOptions;
|
||||
MTLStorageMode _mtlStorageMode;
|
||||
MTLCPUCacheMode _mtlCPUCacheMode;
|
||||
|
@ -62,10 +62,15 @@ VkResult MVKDeviceMemory::map(VkDeviceSize offset, VkDeviceSize size, VkMemoryMa
|
||||
if ( !mapToSingleResource(offset, mapSize) ) {
|
||||
if (isMemoryHostCoherent()) {
|
||||
if ( !_mtlBuffer ) {
|
||||
NSUInteger mtlBuffLen = mvkAlignByteOffset(_allocationSize, _device->_pMetalFeatures->mtlBufferAlignment);
|
||||
_mtlBuffer = [getMTLDevice() newBufferWithLength: mtlBuffLen options: _mtlResourceOptions]; // retained
|
||||
// MVKLogDebug("Allocating host mapped memory %p with offset %d and size %d via underlying coherent MTLBuffer %p of size %d.", this, offset, mapSize, _mtlBuffer , _mtlBuffer.length);
|
||||
}
|
||||
|
||||
// Lock and check again in case another thread has created the buffer.
|
||||
lock_guard<mutex> lock(_lock);
|
||||
if ( !_mtlBuffer ) {
|
||||
NSUInteger mtlBuffLen = mvkAlignByteOffset(_allocationSize, _device->_pMetalFeatures->mtlBufferAlignment);
|
||||
_mtlBuffer = [getMTLDevice() newBufferWithLength: mtlBuffLen options: _mtlResourceOptions]; // retained
|
||||
// MVKLogDebug("Allocating host mapped memory %p with offset %d and size %d via underlying coherent MTLBuffer %p of size %d.", this, offset, mapSize, _mtlBuffer , _mtlBuffer.length);
|
||||
}
|
||||
}
|
||||
_pLogicalMappedMemory = _mtlBuffer.contents;
|
||||
_pMappedMemory = (void*)((uintptr_t)_pLogicalMappedMemory + offset);
|
||||
} else {
|
||||
|
@ -216,11 +216,12 @@ void* MVKImage::map(VkDeviceSize offset, VkDeviceSize size) {
|
||||
|
||||
id<MTLTexture> MVKImage::getMTLTexture() {
|
||||
if ( !_mtlTexture && _mtlPixelFormat ) {
|
||||
|
||||
// Lock and check again in case another thread has created the texture.
|
||||
lock_guard<mutex> lock(_lock);
|
||||
// Check again in case another thread has created the texture.
|
||||
if ( !_mtlTexture ) {
|
||||
_mtlTexture = newMTLTexture(); // retained
|
||||
}
|
||||
if (_mtlTexture) { return _mtlTexture; }
|
||||
|
||||
_mtlTexture = newMTLTexture(); // retained
|
||||
}
|
||||
return _mtlTexture;
|
||||
}
|
||||
@ -544,11 +545,12 @@ 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 ) {
|
||||
|
||||
// Lock and check again in case another thread created the texture view
|
||||
lock_guard<mutex> lock(_lock);
|
||||
// Check again in case another thread created the texture view
|
||||
if ( !_mtlTexture ) {
|
||||
_mtlTexture = newMTLTexture(); // retained
|
||||
}
|
||||
if (_mtlTexture) { return _mtlTexture; }
|
||||
|
||||
_mtlTexture = newMTLTexture(); // retained
|
||||
}
|
||||
return _mtlTexture;
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user