private MgStorageBlockInfo[] SubdivideByMemoryPropertyFlags(MgStorageBlockInfo sector, MgStorageBlockAllocationInfo[] allocations) { // EXACT MATCH ONLY var groups = new Dictionary <MgMemoryPropertyFlagBits, MgStorageBlockInfo>(); foreach (var attr in sector.Attributes) { var allocation = allocations[attr.Index]; MgStorageBlockInfo found; if (!groups.TryGetValue(allocation.MemoryPropertyFlags, out found)) { found = new MgStorageBlockInfo { Usage = attr.Usage, Attributes = new List <MgStorageBlockAttribute>(), }; groups.Add(allocation.MemoryPropertyFlags, found); } found.Attributes.Add(attr); } var noOfGroups = groups.Keys.Count; var segments = new MgStorageBlockInfo[noOfGroups]; groups.Values.CopyTo(segments, 0); return(segments); }
private MgStorageBlockInfo[] SplitToSingleBuffers(MgStorageBlockInfo second) { var slices = new List <MgStorageBlockInfo>(); foreach (var attr in second.Attributes) { var slice = new MgStorageBlockInfo { Usage = attr.Usage, Attributes = new List <MgStorageBlockAttribute>(), }; slice.Attributes.Add(attr); slices.Add(slice); } return(slices.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); } } }
public MgStorageBlockInfo[] Setup(MgStorageBlockAllocationInfo[] attributes) { var layouts = new List <MgStorageBlockInfo>(); MgBufferUsageFlagBits?[] unallocatedAttributes = TransformAttributes(attributes); foreach (var combination in mLayout.Combinations) { MgStorageBlockInfo currentLayout = null; for (var i = 0U; i < unallocatedAttributes.Length; i += 1) { var attr = unallocatedAttributes[i]; if (attr.HasValue) { var mask = (attr.Value & combination.Usage); if (mask == attr.Value) { MgStorageBlockInfo destination = null; if (currentLayout == null) { currentLayout = new MgStorageBlockInfo { Usage = mask, Attributes = new List <MgStorageBlockAttribute>(), }; layouts.Add(currentLayout); destination = currentLayout; } else { // CREATE ADDITIONAL BUFFER IF NEEDED if ((attr.Value & combination.SeparateBlockRequired) == attr.Value // IF CURRENT LAYOUT ALREADY HAS OCCUPIED, THEN CREATE NEW SEGMENT && (currentLayout.Usage & attr.Value) == attr.Value) { var temp = new MgStorageBlockInfo { Usage = mask, Attributes = new List <MgStorageBlockAttribute>(), }; layouts.Add(temp); destination = temp; } else { // APPEND ATTRIBUTE currentLayout.Usage |= attr.Value; // currentBuffer.RequestedSize += attr.Size; destination = currentLayout; } } var location = new MgStorageBlockAttribute { Index = i, Usage = attr.Value, }; destination.Attributes.Add(location); // REMOVE attributes unallocatedAttributes[i] = null; } } } } return(layouts.ToArray()); }
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); } }