public MgOptimizedStorageMap MapAllocations(MgOptimizedStorageCreateInfo createInfo, MgStorageBufferInstance[] bufferInstances) { Validate(createInfo); var attributes = new MgOptimizedStorageAllocation[createInfo.Allocations.Length]; for (var i = 0U; i < bufferInstances.Length; i += 1) { var instance = bufferInstances[i]; foreach (var mapping in instance.Mappings) { attributes[mapping.Index] = new MgOptimizedStorageAllocation { AllocationIndex = mapping.Index, BlockIndex = i, Offset = mapping.Offset, Size = mapping.Size, Usage = mapping.Usage, }; } } return(new MgOptimizedStorageMap { Allocations = attributes }); }
public MgStorageBufferInstance[] PrepareInstances(MgOptimizedStorageCreateInfo createInfo) { // setup Validate(createInfo); var optimalLayout = mSplitter.Setup(createInfo.Allocations); return(mVerifier.Revise(createInfo, optimalLayout)); }
private void Validate(MgOptimizedStorageCreateInfo createInfo) { if (createInfo.Allocations == null) { throw new ArgumentNullException("createInfo.Allocations"); } if (createInfo.Allocations.Length <= 0) { throw new ArgumentOutOfRangeException("createInfo.Allocations must be greater than zero"); } }
public MgOptimizedStorageContainer Build(MgOptimizedStorageCreateInfo createInfo) { var bufferInstances = PrepareInstances(createInfo); var storageMap = MapAllocations(createInfo, bufferInstances); var storage = AllocateBlocks(bufferInstances); return(new MgOptimizedStorageContainer { Storage = storage, Map = storageMap, }); }
public MgStorageBufferInstance[] Revise(MgOptimizedStorageCreateInfo createInfo, MgStorageBlockInfo[] segments) { var output = new List <MgStorageBufferInstance>(); foreach (var sector in segments) { if (DoPack(sector, createInfo, out MgStorageBufferInstance firstOutput)) { output.Add(firstOutput); } else { OntoSecondChance(output, sector, createInfo); } } return(output.ToArray()); }
private void OntoFinalChance(List <MgStorageBufferInstance> output, MgStorageBlockInfo second, MgOptimizedStorageCreateInfo createInfo) { var individuals = SplitToSingleBuffers(second); foreach (var single in individuals) { if (DoPack(single, createInfo, out MgStorageBufferInstance thirdOutput)) { output.Add(thirdOutput); } else { throw new InvalidOperationException("Cannot create buffer for MgOptimizedMesh"); } } }
private void OntoSecondChance(List <MgStorageBufferInstance> output, MgStorageBlockInfo sector, MgOptimizedStorageCreateInfo createInfo) { MgStorageBlockInfo[] slices = SubdivideByMemoryPropertyFlags(sector, createInfo.Allocations); foreach (var second in slices) { if (DoPack(second, createInfo, out MgStorageBufferInstance secondOutput)) { output.Add(secondOutput); } else { OntoFinalChance(output, second, createInfo); } } }
private bool DoPack(MgStorageBlockInfo sector, MgOptimizedStorageCreateInfo createInfo, out MgStorageBufferInstance instance) { MgBufferUsageFlagBits bufferUsage = 0; MgMemoryPropertyFlagBits deviceMemoryProperties = 0; var sortedList = new SortedDictionary <SortedKey, uint>(); foreach (var attr in sector.Attributes) { bufferUsage |= attr.Usage; deviceMemoryProperties |= createInfo.Allocations[attr.Index].MemoryPropertyFlags; var firstGroup = 0U; for (var i = 0U; i < mPackingOrder.Length; i += 1) { firstGroup = i; var first = (mPackingOrder[i] & createInfo.Allocations[attr.Index].Usage) > 0; if (first) { break; } } Debug.Assert(firstGroup <= mPackingOrder.Length); var key = new SortedKey { Group = firstGroup, SubOrder = attr.Index, }; sortedList.Add(key, attr.Index); } ulong overallSize = 0; var pCreateInfo = new MgBufferCreateInfo { SharingMode = createInfo.SharingMode, QueueFamilyIndices = createInfo.QueueFamilyIndices, Size = 0, Usage = bufferUsage, }; // The alignment member is identical for all VkBuffer objects created with the same combination of values // for the usage and flags members in the VkBufferCreateInfo structure passed to vkCreateBuffer. var err = mConfiguration.Device.CreateBuffer(pCreateInfo, null, out IMgBuffer pZeroBuffer); if (err != Result.SUCCESS) { instance = null; return(false); } mConfiguration.Device.GetBufferMemoryRequirements(pZeroBuffer, out MgMemoryRequirements pZeroMemReqs); pZeroBuffer.DestroyBuffer(mConfiguration.Device, null); var requiredAlignment = pZeroMemReqs.Alignment; var mappings = new List <MgStorageBufferOffset>(); foreach (var element in sortedList.Values) { var attr = createInfo.Allocations[element]; var mapping = new MgStorageBufferOffset { Index = element, Offset = UpperBounded(overallSize, requiredAlignment), Size = attr.Size, Usage = attr.Usage, }; mappings.Add(mapping); overallSize = mapping.Offset + mapping.Size; } // Real memory allocation pCreateInfo.Size = overallSize; err = mConfiguration.Device.CreateBuffer(pCreateInfo, null, out IMgBuffer pBuffer); if (err != Result.SUCCESS) { instance = null; return(false); } mConfiguration.Device.GetBufferMemoryRequirements(pBuffer, out MgMemoryRequirements pMemReqs); if (mConfiguration.MemoryProperties.GetMemoryType(pMemReqs.MemoryTypeBits, deviceMemoryProperties, out uint typeIndex)) { instance = new MgStorageBufferInstance { Buffer = pBuffer, Usage = bufferUsage, MemoryPropertyFlags = deviceMemoryProperties, TypeIndex = typeIndex, AllocationSize = pMemReqs.Size, Mappings = mappings.ToArray(), }; return(true); } else { // CLEAN UP pBuffer.DestroyBuffer(mConfiguration.Device, null); instance = null; return(false); } }