Example #1
0
        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
            });
        }
Example #2
0
        public MgStorageBufferInstance[] PrepareInstances(MgOptimizedStorageCreateInfo createInfo)
        {
            // setup
            Validate(createInfo);
            var optimalLayout = mSplitter.Setup(createInfo.Allocations);

            return(mVerifier.Revise(createInfo, optimalLayout));
        }
Example #3
0
        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");
            }
        }
Example #4
0
        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,
            });
        }
Example #5
0
        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());
        }
Example #6
0
        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");
                }
            }
        }
Example #7
0
        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);
                }
            }
        }
Example #8
0
        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);
            }
        }