internal void Return(VulkanMemorySlice returnSlice) { DebugHelper.AssertThrow <InvalidOperationException>(returnSlice.vkDeviceMemory.Handle == vkDeviceMemory.Handle); //First try to merge with existing free slices for (int i = 0; i < freeSlices.Count; i++) { var slice = freeSlices[i]; ulong sizeWithAlign = returnSlice.size + returnSlice.alignOffset; if (slice.startIndex == returnSlice.offset + sizeWithAlign) { slice.length += sizeWithAlign; slice.startIndex -= sizeWithAlign; freeSlices[i] = slice; return; } } //If not possible insert to the list FreeSlice newSlice = new FreeSlice() { length = returnSlice.size + returnSlice.alignOffset, startIndex = returnSlice.offset - returnSlice.alignOffset }; //freeSlices.Add(newSlice); //Add and sort in ascending order by length for (int i = 0; i < freeSlices.Count; i++) { if (freeSlices[i].length > newSlice.length) { freeSlices.Insert(i, newSlice); return; } } //If largest, add to the end freeSlices.Add(newSlice); }
public VkResult Allocate(ulong size, ulong alignment, out VulkanMemorySlice outSlice) { if (size > max_size) { CreateNext(size); var allocResult = next.AllocateDeviceMemory(); if (allocResult != VkResult.Success) { next = null; outSlice = null; return(allocResult); } return(next.Allocate(size, alignment, out outSlice)); } VulkanMemorySlice returnSlice = null; for (int i = 0; i < freeSlices.Count; i++) { FreeSlice slice = freeSlices[i]; //align the slice to alignment uint align = slice.startIndex % alignment == 0 ? 0 : ((uint)alignment - ((uint)slice.startIndex % (uint)alignment)); ulong sizeWithAlign = size + align; if (slice.length >= sizeWithAlign) { returnSlice = new VulkanMemorySlice(this, size, slice.startIndex + align, align, vkDeviceMemory, memoryTypeIndex, memoryPropertyFlags); slice.length -= sizeWithAlign; slice.startIndex += sizeWithAlign; if (slice.length == 0) { freeSlices.RemoveAt(i); } else { freeSlices[i] = slice; } break; } } if (returnSlice != null) { outSlice = returnSlice; return(VkResult.Success); } else { CreateNext(max_size); var allocResult = next.AllocateDeviceMemory(); if (allocResult != VkResult.Success) { next = null; outSlice = null; return(allocResult); } return(next.Allocate(size, alignment, out outSlice)); } }