Esempio n. 1
0
 public ValueBufferCpu(Device device, VkBufferUsageFlag usage, VkBufferCreateFlag flags,
                       bool coherent, params T[] values) : base(device, usage, flags,
                                                                FindHostMemory(device.PhysicalDevice, coherent, (ulong)Marshal.SizeOf <T>() * (ulong)values.LongLength),
                                                                values)
 {
     Coherent = BackingBuffer.Memory.BackingMemory.MemoryType.HostCoherent;
     CommitEverything();
 }
Esempio n. 2
0
        private List <BufferPool> PoolForUsage(MemoryType type, VkBufferUsageFlag usage, VkBufferCreateFlag create)
        {
            var cval = _poolsByType[type.TypeIndex, (int)usage, (int)create];

            if (cval != null)
            {
                return(cval);
            }
            return(_poolsByType[type.TypeIndex, (int)usage, (int)create] = new List <BufferPool>());
        }
Esempio n. 3
0
 protected ValueBuffer(Device device, VkBufferUsageFlag usage, VkBufferCreateFlag flags, MemoryType mem,
                       params T[] values) : base(device, mem,
                                                 (ulong)Marshal.SizeOf <T>() * (ulong)values.LongLength, usage, flags)
 {
     _data     = values;
     _itemSize = (ulong)Marshal.SizeOf <T>();
     _dirtyMin = 0;
     _dirtyMax = (uint)_data.Length;
     ;
 }
        public PooledMemoryBuffer(Device dev, VkBufferUsageFlag usage, VkBufferCreateFlag flags, MemoryRequirements req,
                                  ulong size, params uint[] sharedQueueFamilies) :
            base(dev, usage, flags, size, sharedQueueFamilies)
        {
            var pool = Size >= DeviceMemoryPools.BlockSizeForPool(DeviceMemoryPools.Pool.LargeBufferPool)
                ? DeviceMemoryPools.Pool.LargeBufferPool
                : DeviceMemoryPools.Pool.SmallBufferPool;
            var reqs = MemoryRequirements.Union(MemoryRequirements, req);
            var type = reqs.FindMemoryType(PhysicalDevice);

            _memory = Device.MemoryPool.Allocate(type, pool, reqs.TypeRequirements.Size);
            BindMemory(_memory.BackingMemory, _memory.Offset);
        }
Esempio n. 5
0
 private ulong BlockSizeForUsage(VkBufferUsageFlag flag)
 {
     if ((flag & VkBufferUsageFlag.UniformBuffer) != 0)
     {
         return(Extensions.LeastCommonMultiple(128, PhysicalDevice.Limits.MinUniformBufferOffsetAlignment));
     }
     if ((flag & VkBufferUsageFlag.VertexBuffer) != 0)
     {
         return(1024 * 128); // 4k VertexTextured
     }
     if ((flag & VkBufferUsageFlag.IndexBuffer) != 0)
     {
         return(1024 * 32); // 8k uint indices
     }
     return(1024 * 16);
 }
Esempio n. 6
0
        /// <summary>
        /// Allocates a new memory pool.
        /// </summary>
        /// <param name="dev">Device to allocate on</param>
        /// <param name="blockSize">Memory block size</param>
        /// <param name="blockCount">Number of blocks to allocate</param>
        /// <param name="usage">buffer usage</param>
        /// <param name="flags">buffer creation flags</param>
        /// <param name="memoryType">Memory to use</param>
        /// <param name="sharedQueueFamilies">Concurrency mode, or exclusive if empty</param>
        public BufferPool(Device dev, ulong blockSize, ulong blockCount, VkBufferUsageFlag usage,
                          VkBufferCreateFlag flags, MemoryType memoryType, params uint[] sharedQueueFamilies)
        {
            Device = dev;
            var bitAlignment = (uint)System.Math.Ceiling(System.Math.Log(blockSize) / System.Math.Log(2));

            blockSize = (1UL << (int)bitAlignment);
            _pool     = new MemoryPool(blockSize * blockCount, bitAlignment);
            _buffer   = new PooledMemoryBuffer(dev, usage, flags, new MemoryRequirements()
            {
                TypeRequirements = new VkMemoryRequirements()
                {
                    MemoryTypeBits = 1u << (int)memoryType.TypeIndex
                }
            },
                                               blockSize * blockCount, sharedQueueFamilies);
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a new buffer
        /// </summary>
        /// <param name="dev">device</param>
        /// <param name="usage">buffer usage</param>
        /// <param name="flags">buffer creation flags</param>
        /// <param name="size">buffer size</param>
        /// <param name="sharedQueueFamilies">Concurrency mode, or exclusive if empty</param>
        public Buffer(Device dev, VkBufferUsageFlag usage, VkBufferCreateFlag flags, ulong size,
                      params uint[] sharedQueueFamilies)
        {
            Logging.Allocations?.Trace($"Creating {Extensions.FormatFileSize(size)} buffer with usage {usage}");

            Device = dev;
            Size   = size;
            Usage  = usage;
            unsafe
            {
                var pin = sharedQueueFamilies.Length > 0
                    ? GCHandle.Alloc(sharedQueueFamilies, GCHandleType.Pinned)
                    : default(GCHandle);
                try
                {
                    var info = new VkBufferCreateInfo()
                    {
                        SType       = VkStructureType.BufferCreateInfo,
                        PNext       = IntPtr.Zero,
                        Flags       = flags,
                        Size        = size,
                        Usage       = usage,
                        SharingMode =
                            sharedQueueFamilies.Length > 0 ? VkSharingMode.Concurrent : VkSharingMode.Exclusive,
                        QueueFamilyIndexCount = (uint)sharedQueueFamilies.Length,
                        PQueueFamilyIndices   =
                            (uint *)(sharedQueueFamilies.Length > 0
                                ? Marshal.UnsafeAddrOfPinnedArrayElement(sharedQueueFamilies, 0)
                                : IntPtr.Zero).ToPointer()
                    };
                    Handle = dev.Handle.CreateBuffer(&info, Instance.AllocationCallbacks);
                }
                finally
                {
                    if (sharedQueueFamilies.Length > 0)
                    {
                        pin.Free();
                    }
                }
            }
        }
Esempio n. 8
0
        [MethodImpl(MethodImplOptions.Synchronized)] // TODO better sync with rwlock
        public MemoryHandle Allocate(MemoryType type, VkBufferUsageFlag usage, VkBufferCreateFlag create, ulong size)
        {
            var pools = PoolForUsage(type, usage, create);

            foreach (var pool in pools)
            {
                if (pool.TryAllocate(size, out var tmp))
                {
                    return(new MemoryHandle(pool, tmp));
                }
            }
            // Create a new pool
            var blockSize  = BlockSizeForUsage(usage);
            var blockCount = System.Math.Max((ulong)System.Math.Ceiling(size / (double)blockSize) * 4UL, PoolBlockCount);
            var families   = Device.Queues.Select(x => x.FamilyIndex).Distinct().ToArray();
            // TODO consider how concurrency works here.  Needed?
            // families.Length > 1 ? families : new uint[0]);
            var npool = new BufferPool(Device, blockSize, blockCount, usage, create, type, new uint[0]);

            pools.Add(npool);
            return(new MemoryHandle(npool, npool.Allocate(size)));
        }
Esempio n. 9
0
 public ValueBufferGpu(DeferredTransfer flush, VkBufferUsageFlag usage, VkBufferCreateFlag create, T[] values) :
     base(flush.Device, usage, create,
          FindDeviceMemory(flush.PhysicalDevice, (ulong)Marshal.SizeOf <T>() * (ulong)values.LongLength), values)
 {
     _deferredFlusher = flush;
 }
Esempio n. 10
0
 public PooledBuffer(Device dev, MemoryType memType, ulong capacity, VkBufferUsageFlag usage, VkBufferCreateFlag create = 0)
 {
     Handle = dev.BufferPools.Allocate(memType, usage, create, capacity);
 }