Esempio n. 1
0
        public Node TryAllocate(ulong size, ulong alignment)
        {
            var free = TreeSearch(size + alignment - 1);

            if (free == null)
            {
                return(null);
            }
            TreeRemove(free);
            var offset = GraphicsUtility.AlignUp(free.Offset, alignment);

            if (offset > free.Offset)
            {
                var frag = new Node {
                    Offset = free.Offset,
                    Size   = offset - free.Offset
                };
                TreeInsert(frag);
                ListInsertBefore(free, frag);
            }
            if (offset + size < free.Offset + free.Size)
            {
                var frag = new Node {
                    Offset = offset + size,
                    Size   = free.Offset + free.Size - offset - size
                };
                TreeInsert(frag);
                ListInsertAfter(free, frag);
            }
            free.Offset = offset;
            free.Size   = size;
            return(free);
        }
Esempio n. 2
0
        private void FlushOrInvalidateMappedMemoryRange(MemoryAlloc alloc, ulong offset, ulong size, bool flush)
        {
            if (alloc.Allocator != this)
            {
                throw new ArgumentException(nameof(alloc));
            }
            if (alloc.Size < offset + size)
            {
                throw new ArgumentException();
            }
            if (size == 0)
            {
                return;
            }
            var memoryType   = alloc.Memory.Type;
            var hostCoherent = (memoryType.PropertyFlags & SharpVulkan.MemoryPropertyFlags.HostCoherent) != 0;

            if (hostCoherent)
            {
                return;
            }
            var nonCoherentAtomSize = Context.PhysicalDeviceLimits.NonCoherentAtomSize;
            var rangeStart          = GraphicsUtility.AlignDown(alloc.Offset + offset, nonCoherentAtomSize);
            var rangeEnd            = GraphicsUtility.AlignUp(alloc.Offset + offset + size, nonCoherentAtomSize);

            if (rangeEnd > alloc.Memory.Size)
            {
                rangeEnd = alloc.Memory.Size;
            }
            var range = new SharpVulkan.MappedMemoryRange {
                StructureType = SharpVulkan.StructureType.MappedMemoryRange,
                Memory        = alloc.Memory.Memory,
                Offset        = rangeStart,
                Size          = rangeEnd - rangeStart
            };

            if (flush)
            {
                Context.Device.FlushMappedMemoryRanges(1, &range);
            }
            else
            {
                Context.Device.InvalidateMappedMemoryRanges(1, &range);
            }
        }
Esempio n. 3
0
        public UploadBufferAlloc Allocate(ulong size, ulong alignment)
        {
            var alignedOffset = GraphicsUtility.AlignUp(bufferOffset, alignment);

            if (alignedOffset + size > bufferSize)
            {
                var newBufferSize = bufferSize;
                while (newBufferSize < size)
                {
                    newBufferSize *= 2;
                }
                ReleaseBuffer();
                CreateBuffer(newBufferSize);
                alignedOffset = 0;
            }
            bufferOffset = alignedOffset + size;
            return(new UploadBufferAlloc(buffer, new IntPtr((byte *)mappedMemory + alignedOffset), alignedOffset, size));
        }
Esempio n. 4
0
        private void CreateBuffer()
        {
            var alignedSliceSize = GraphicsUtility.AlignUp(sliceSize, sliceAlignment);
            var bufferSize       = sliceCount * alignedSliceSize;
            var createInfo       = new SharpVulkan.BufferCreateInfo {
                StructureType = SharpVulkan.StructureType.BufferCreateInfo,
                Size          = bufferSize,
                SharingMode   = SharpVulkan.SharingMode.Exclusive,
                Usage         = usage
            };

            buffer = context.Device.CreateBuffer(ref createInfo);
            memory = context.MemoryAllocator.Allocate(buffer, memoryPropertyFlags);
            sliceQueue.Clear();
            for (ulong i = 0; i < sliceCount; i++)
            {
                sliceQueue.Enqueue(new SliceEntry {
                    Offset = i * alignedSliceSize
                });
            }
            Generation++;
        }