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)); } }
private bool AllocateFromPools(ulong size, ulong alignment, uint memoryTypeBits, VkMemoryPropertyFlags required, VkMemoryPropertyFlags preferred, bool hostVisible, out VulkanMemorySlice allocation) { var physicalMemoryProperties = device.DeviceMemoryProperties; //Match for preferred for (int i = 0; i < memoryPools.Count; i++) { VulkanMemoryPool pool = memoryPools[i]; uint memoryTypeIndex = pool.memoryTypeIndex; if (pool.hostVisible != hostVisible) { continue; } //Match memoryTypeIndex of the pool if ((((int)memoryTypeBits >> (int)memoryTypeIndex) & 1) == 0) { continue; } // Match required memory properties VkMemoryPropertyFlags properties = physicalMemoryProperties.GetMemoryType(memoryTypeIndex).propertyFlags; if ((properties & required) != required) { continue; } // Match preferred if ((properties & preferred) != preferred) { continue; } var result = pool.Allocate(size, alignment, out allocation); if (result != VkResult.Success) { continue; } return(true); } //Match only required for (int i = 0; i < memoryPools.Count; i++) { VulkanMemoryPool pool = memoryPools[i]; uint memoryTypeIndex = pool.memoryTypeIndex; if (pool.hostVisible != hostVisible) { continue; } //Match memoryTypeIndex of the pool if ((((int)memoryTypeBits >> (int)memoryTypeIndex) & 1) == 0) { continue; } // Match required memory properties VkMemoryPropertyFlags properties = physicalMemoryProperties.GetMemoryType(memoryTypeIndex).propertyFlags; if ((properties & required) != required) { continue; } var result = pool.Allocate(size, alignment, out allocation); if (result != VkResult.Success) { continue; } return(true); } allocation = null; return(false); }