//private void Flush(UInt64 start, UInt64 length) { // VkMappedMemoryRange memoryRange = VkMappedMemoryRange.New(); // memoryRange.memory = vkMemory; // memoryRange.size = length; // memoryRange.offset = start; // Util.CheckResult(vkFlushMappedMemoryRanges(device.device, 1, ref memoryRange)); //} private void Allocate() { if (usageHint == BufferMemoryUsageHint.Static) { bufferUsageFlags |= VkBufferUsageFlags.TransferDst; } // Create the buffer handle VkBufferCreateInfo bufferCreateInfo = Initializers.bufferCreateInfo(bufferUsageFlags, size); bufferCreateInfo.sharingMode = VkSharingMode.Exclusive; Util.CheckResult(vkCreateBuffer(device.device, &bufferCreateInfo, null, out vkBuffer)); // Create the memory backing up the buffer handle VkMemoryRequirements memReqs; vkGetBufferMemoryRequirements(device.device, vkBuffer, &memReqs); var hostVisible = usageHint == BufferMemoryUsageHint.Dynamic; memory = device.memoryAllocator.Allocate(memReqs, hostVisible); // Attach the memory to the buffer object Util.CheckResult(vkBindBufferMemory(device.device, vkBuffer, memory.vkDeviceMemory, memory.offset)); }
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)); } }
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); }