private ChunkAllocatorSet GetAllocator(uint memoryTypeIndex)
        {
            if (!_allocatorsByMemoryType.TryGetValue(memoryTypeIndex, out ChunkAllocatorSet ret))
            {
                ret = new ChunkAllocatorSet(_device, memoryTypeIndex);
                _allocatorsByMemoryType.Add(memoryTypeIndex, ret);
            }

            return(ret);
        }
        public VkMemoryBlock Allocate(uint memoryTypeIndex, ulong size, ulong alignment)
        {
            ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex);
            bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);

            if (!result)
            {
                throw new VeldridException("Unable to allocate memory.");
            }

            return(ret);
        }
Exemplo n.º 3
0
        public VkMemoryBlock Allocate(
            VkPhysicalDeviceMemoryProperties memProperties,
            uint memoryTypeBits,
            VkMemoryPropertyFlags flags,
            bool persistentMapped,
            ulong size,
            ulong alignment)
        {
            lock (_lock)
            {
                uint memoryTypeIndex = FindMemoryType(memProperties, memoryTypeBits, flags);

                ulong minDedicatedAllocationSize = persistentMapped
                    ? MinDedicatedAllocationSizeDynamic
                    : MinDedicatedAllocationSizeNonDynamic;

                if (size >= minDedicatedAllocationSize)
                {
                    VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();
                    allocateInfo.allocationSize  = size;
                    allocateInfo.memoryTypeIndex = memoryTypeIndex;
                    VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory);
                    if (allocationResult != VkResult.Success)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    void *mappedPtr = null;
                    if (persistentMapped)
                    {
                        VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr);
                        if (mapResult != VkResult.Success)
                        {
                            throw new VeldridException("Unable to map newly-allocated Vulkan memory.");
                        }
                    }

                    return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, null, true));
                }
                else
                {
                    ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped);
                    bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);
                    if (!result)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    return(ret);
                }
            }
        }
Exemplo n.º 4
0
        public VkMemoryBlock Allocate(
            VkPhysicalDeviceMemoryProperties memProperties,
            uint memoryTypeBits,
            VkMemoryPropertyFlags flags,
            bool persistentMapped,
            ulong size,
            ulong alignment)
        {
            lock (_lock)
            {
                uint memoryTypeIndex        = FindMemoryType(memProperties, memoryTypeBits, flags);
                ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped);
                bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);
                if (!result)
                {
                    throw new VeldridException("Unable to allocate memory.");
                }

                return(ret);
            }
        }
Exemplo n.º 5
0
        private ChunkAllocatorSet GetAllocator(uint memoryTypeIndex, bool persistentMapped)
        {
            ChunkAllocatorSet ret = null;

            if (persistentMapped)
            {
                if (!_allocatorsByMemoryType.TryGetValue(memoryTypeIndex, out ret))
                {
                    ret = new ChunkAllocatorSet(_device, memoryTypeIndex, true);
                    _allocatorsByMemoryType.Add(memoryTypeIndex, ret);
                }
            }
            else
            {
                if (!_allocatorsByMemoryTypeUnmapped.TryGetValue(memoryTypeIndex, out ret))
                {
                    ret = new ChunkAllocatorSet(_device, memoryTypeIndex, false);
                    _allocatorsByMemoryTypeUnmapped.Add(memoryTypeIndex, ret);
                }
            }

            return(ret);
        }
Exemplo n.º 6
0
        public VkMemoryBlock Allocate(
            VkPhysicalDeviceMemoryProperties memProperties,
            uint memoryTypeBits,
            VkMemoryPropertyFlags flags,
            bool persistentMapped,
            ulong size,
            ulong alignment,
            bool dedicated,
            VkImage dedicatedImage,
            Vulkan.VkBuffer dedicatedBuffer)
        {
            // Round up to the nearest multiple of bufferImageGranularity.
            size = ((size / _bufferImageGranularity) + 1) * _bufferImageGranularity;
            _totalAllocatedBytes += size;

            lock (_lock)
            {
                if (!TryFindMemoryType(memProperties, memoryTypeBits, flags, out var memoryTypeIndex))
                {
                    throw new VeldridException("No suitable memory type.");
                }

                ulong minDedicatedAllocationSize = persistentMapped
                    ? MinDedicatedAllocationSizeDynamic
                    : MinDedicatedAllocationSizeNonDynamic;

                if (dedicated || size >= minDedicatedAllocationSize)
                {
                    VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();
                    allocateInfo.allocationSize  = size;
                    allocateInfo.memoryTypeIndex = memoryTypeIndex;

                    VkMemoryDedicatedAllocateInfoKHR dedicatedAI;
                    if (dedicated)
                    {
                        dedicatedAI        = VkMemoryDedicatedAllocateInfoKHR.New();
                        dedicatedAI.buffer = dedicatedBuffer;
                        dedicatedAI.image  = dedicatedImage;
                        allocateInfo.pNext = &dedicatedAI;
                    }

                    VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory);
                    if (allocationResult != VkResult.Success)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    void *mappedPtr = null;
                    if (persistentMapped)
                    {
                        VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr);
                        if (mapResult != VkResult.Success)
                        {
                            throw new VeldridException("Unable to map newly-allocated Vulkan memory.");
                        }
                    }

                    return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, mappedPtr, true));
                }
                else
                {
                    ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped);
                    bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);
                    if (!result)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    return(ret);
                }
            }
        }