| /* |
| * MVKMTLBufferAllocation.h |
| * |
| * Copyright (c) 2015-2022 The Brenwill Workshop Ltd. (http://www.brenwill.com) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| |
| #include "MVKFoundation.h" |
| #include "MVKObjectPool.h" |
| #include "MVKDevice.h" |
| #include "MVKSmallVector.h" |
| |
| class MVKMTLBufferAllocationPool; |
| |
| |
| #pragma mark - |
| #pragma mark MVKMTLBufferAllocation |
| |
| /** Defines a contiguous region of bytes within a MTLBuffer. */ |
| class MVKMTLBufferAllocation : public MVKBaseObject, public MVKLinkableMixin<MVKMTLBufferAllocation> { |
| |
| public: |
| id<MTLBuffer> _mtlBuffer; |
| NSUInteger _offset; |
| NSUInteger _length; |
| |
| /** Returns the Vulkan API opaque object controlling this object. */ |
| MVKVulkanAPIObject* getVulkanAPIObject() override; |
| |
| /** |
| * Returns a pointer to the begining of this allocation memory, taking into |
| * consideration this allocation's offset into the underlying MTLBuffer. |
| */ |
| inline void* getContents() const { return (void*)((uintptr_t)_mtlBuffer.contents + _offset); } |
| |
| /** Returns the pool whence this object was created. */ |
| MVKMTLBufferAllocationPool* getPool() const { return _pool; } |
| |
| /** Returns this object back to the pool that created it. */ |
| void returnToPool(); |
| |
| /** Constructs this instance with the specified pool as its origin. */ |
| MVKMTLBufferAllocation(MVKMTLBufferAllocationPool* pool, |
| id<MTLBuffer> mtlBuffer, |
| NSUInteger offset, |
| NSUInteger length, |
| uint64_t poolIndex) : _mtlBuffer(mtlBuffer), _offset(offset), _length(length), _pool(pool), _poolIndex(poolIndex) {} |
| |
| protected: |
| friend class MVKMTLBufferAllocationPool; |
| |
| MVKMTLBufferAllocationPool* _pool; |
| uint64_t _poolIndex; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKMTLBufferAllocationPool |
| |
| /** |
| * A pool of MVKMTLBufferAllocation instances of a single size. All MVKMTLBufferAllocation |
| * instances will have the same size, as defined when this pool is created. |
| * |
| * To return a MVKMTLBufferAllocation retrieved from this pool, back to this pool, |
| * call the returnToPool() function on the MVKMTLBufferAllocation instance. |
| */ |
| class MVKMTLBufferAllocationPool : public MVKObjectPool<MVKMTLBufferAllocation>, public MVKDeviceTrackingMixin { |
| |
| public: |
| /** Returns a new allocation. */ |
| MVKMTLBufferAllocation* acquireAllocation(); |
| |
| /** Returns a new allocation (without mutual exclusion). */ |
| MVKMTLBufferAllocation* acquireAllocationUnlocked(); |
| |
| /** Returns the Vulkan API opaque object controlling this object. */ |
| MVKVulkanAPIObject* getVulkanAPIObject() override { return _device->getVulkanAPIObject(); }; |
| |
| /** Configures this instance to dispense MVKMTLBufferAllocation instances of the specified size. */ |
| MVKMTLBufferAllocationPool(MVKDevice* device, NSUInteger allocationLength, bool makeThreadSafe, |
| bool isDedicated, MTLStorageMode mtlStorageMode); |
| |
| ~MVKMTLBufferAllocationPool() override; |
| |
| protected: |
| friend class MVKMTLBufferAllocation; |
| |
| MVKBaseObject* getBaseObject() override { return this; }; |
| MVKMTLBufferAllocation* newObject() override; |
| void returnAllocationUnlocked(MVKMTLBufferAllocation* ba); |
| void returnAllocation(MVKMTLBufferAllocation* ba); |
| uint32_t calcMTLBufferAllocationCount(); |
| void addMTLBuffer(); |
| |
| NSUInteger _nextOffset; |
| NSUInteger _allocationLength; |
| NSUInteger _mtlBufferLength; |
| MTLStorageMode _mtlStorageMode; |
| struct MTLBufferTracker { id<MTLBuffer> mtlBuffer; uint64_t allocationCount; }; |
| MVKSmallVector<MTLBufferTracker, 64> _mtlBuffers; |
| bool _isThreadSafe; |
| }; |
| |
| |
| #pragma mark - |
| #pragma mark MVKMTLBufferAllocator |
| |
| /** |
| * A pool of MVKMTLBufferAllocation instances of any size. When requesting a MVKMTLBufferAllocation |
| * from this pool, the caller can request a specific size. The MVKMTLBufferAllocation instance |
| * returned from such a call will have a size that is the next power-of-two value that is |
| * at least as big as the requested size. |
| * |
| * To return a MVKMTLBufferAllocation retrieved from this pool, back to this pool, |
| * call the returnToPool() function on the MVKMTLBufferAllocation instance. |
| */ |
| class MVKMTLBufferAllocator : public MVKBaseDeviceObject { |
| |
| public: |
| |
| /** Returns the Vulkan API opaque object controlling this object. */ |
| MVKVulkanAPIObject* getVulkanAPIObject() override { return _device->getVulkanAPIObject(); }; |
| |
| /** |
| * Returns a MVKMTLBufferAllocation instance with a size that is the next |
| * power-of-two value that is at least as big as the requested size. |
| * |
| * To return the MVKMTLBufferAllocation back to the pool, call |
| * the returnToPool() function on the returned instance. |
| */ |
| MVKMTLBufferAllocation* acquireMTLBufferRegion(NSUInteger length); |
| |
| /** |
| * Configures this instance to dispense MVKMTLBufferAllocation up to the specified |
| * 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, bool makeThreadSafe = false, |
| bool isDedicated = false, MTLStorageMode mtlStorageMode = MTLStorageModeShared); |
| |
| ~MVKMTLBufferAllocator() override; |
| |
| protected: |
| MVKSmallVector<MVKMTLBufferAllocationPool*, 32> _regionPools; |
| NSUInteger _maxAllocationLength; |
| bool _isThreadSafe; |
| |
| }; |
| |