/// <summary>
        /// Allocates a pooled memory handle of the given size, on the given pool.
        /// </summary>
        /// <param name="type">Required memory type</param>
        /// <param name="poolType">Pool type</param>
        /// <param name="size">Size of allocated region</param>
        /// <returns>Memory handle</returns>
        public MemoryHandle Allocate(MemoryType type, Pool poolType, ulong size)
        {
            var pools = PoolForType(type, poolType);

            foreach (var pool in pools)
            {
                if (pool.TryAllocate(size, out var tmp))
                {
                    return(new MemoryHandle(pool, tmp));
                }
            }
            // Create a new pool
            var blockCount = PoolBlockCount;
            var blockSize  = BlockSizeForPool(poolType);

            blockCount = System.Math.Max((ulong)System.Math.Ceiling(size / (double)blockSize) * 4UL, blockCount);
            var npool = new DeviceMemoryPool(Device, blockSize, type.TypeIndex, blockCount, type.HostVisible);

            pools.Add(npool);
            return(new MemoryHandle(npool, npool.Allocate(size)));
        }
 internal MemoryHandle(DeviceMemoryPool pool, DeviceMemoryPool.MemoryHandle handle)
 {
     _handle = handle;
     _pool   = pool;
 }
 internal void FreeFor(DeviceMemoryPool pool)
 {
     pool._pool.Free(_handle);
     MappedMemory.Dispose();
 }
 internal MemoryHandle(DeviceMemoryPool pool, MemoryPool.Memory handle)
 {
     _handle       = handle;
     BackingMemory = pool._memory;
     MappedMemory  = pool._mapped != null ? new ProxyMemory(pool._mapped, handle.Offset, handle.Size) : null;
 }