Beispiel #1
0
            private void Compile()
            {
                // If we are first, let's apply our layout!
                if (source.Layout == null && subKey == null)
                {
                    source.UpdateLayout(destination.Layout);
                    return;
                }
                else
                {
                    // TODO GRAPHICS REFACTOR optim: check if layout are the same
                    //if (source.Layout.LayoutParameterKeyInfos == destination.Layout.LayoutParameterKeyInfos)
                }

                var rangesList = new List <CopyRange>();

                // Try to match elements (both source and destination should have a layout by now)
                foreach (var parameterKeyInfo in destination.Layout.LayoutParameterKeyInfos)
                {
                    var sourceKey = parameterKeyInfo.Key;
                    if (subKey != null && sourceKey.Name.EndsWith(subKey))
                    {
                        // That's a match
                        var subkeyName = parameterKeyInfo.Key.Name.Substring(0, parameterKeyInfo.Key.Name.Length - subKey.Length);
                        sourceKey = ParameterKeys.FindByName(subkeyName);
                    }

                    if (parameterKeyInfo.Key.Type == ParameterKeyType.Value)
                    {
                        var sourceAccessor = source.GetValueAccessorHelper(sourceKey, parameterKeyInfo.Count);
                        var destAccessor   = destination.GetValueAccessorHelper(parameterKeyInfo.Key, parameterKeyInfo.Count);
                        var elementCount   = Math.Min(sourceAccessor.Count, destAccessor.Count);
                        var elementSize    = parameterKeyInfo.Key.Size;
                        var size           = (elementSize + 15) / 16 * 16 * (elementCount - 1) + elementSize;
                        rangesList.Add(new CopyRange {
                            IsData = true, SourceStart = sourceAccessor.Offset, DestStart = destAccessor.Offset, Size = size
                        });
                    }
                    else
                    {
                        var sourceAccessor = source.GetObjectParameterHelper(sourceKey);
                        var destAccessor   = destination.GetObjectParameterHelper(parameterKeyInfo.Key);
                        var elementCount   = Math.Min(sourceAccessor.Count, destAccessor.Count);
                        rangesList.Add(new CopyRange {
                            IsResource = true, SourceStart = sourceAccessor.Offset, DestStart = destAccessor.Offset, Size = elementCount
                        });
                    }
                }

                ranges = rangesList.ToArray();
                sourceLayoutCounter = source.LayoutCounter;
            }
Beispiel #2
0
        public override void Serialize(ref PermutationParameterKey <T> obj, ArchiveMode mode, SerializationStream stream)
        {
            if (mode == ArchiveMode.Serialize)
            {
                stream.Write(obj.Name);
                stream.Write(obj.Length);
            }
            else
            {
                var parameterName   = stream.ReadString();
                var parameterLength = stream.ReadInt32();
                obj = (PermutationParameterKey <T>)ParameterKeys.FindByName(parameterName);

                // If parameter could not be found, create one matching this type.
                if (obj == null)
                {
                    var metadata = new ParameterKeyValueMetadata <T>();
                    obj = new PermutationParameterKey <T>(parameterName, parameterLength, metadata);
                    ParameterKeys.Merge(obj, null, parameterName);
                }
            }
        }
Beispiel #3
0
            /// <summary>
            /// Compute copy operations. Assumes destination layout is sequential.
            /// </summary>
            /// <param name="dest"></param>
            /// <param name="source"></param>
            /// <param name="keyRoot"></param>
            public void Compile(ParameterCollection dest, ParameterCollection source, string keyRoot)
            {
                ranges      = new List <CopyRange>();
                destination = dest;
                var sourceLayout = new ParameterCollectionLayout();

                // Helper structures to try to keep range contiguous and have as few copy operations as possible (note: there can be some padding)
                var currentDataRange = new CopyRange {
                    IsData = true, DestStart = -1
                };
                var currentResourceRange = new CopyRange {
                    IsResource = true, DestStart = -1
                };

                // Iterate over each variable in dest, and if they match keyRoot, create the equivalent layout in source
                foreach (var parameterKeyInfo in dest.Layout.LayoutParameterKeyInfos)
                {
                    bool isResource = parameterKeyInfo.BindingSlot != -1;
                    bool isData     = parameterKeyInfo.Offset != -1;

                    if (parameterKeyInfo.Key.Name.EndsWith(keyRoot))
                    {
                        // That's a match
                        var subkeyName = parameterKeyInfo.Key.Name.Substring(0, parameterKeyInfo.Key.Name.Length - keyRoot.Length);
                        var subkey     = ParameterKeys.FindByName(subkeyName);

                        if (isData)
                        {
                            // First time since range reset, let's setup destination offset
                            if (currentDataRange.DestStart == -1)
                            {
                                currentDataRange.DestStart = parameterKeyInfo.Offset;
                            }

                            // Might be some empty space (padding)
                            currentDataRange.Size = parameterKeyInfo.Offset - currentDataRange.DestStart;

                            sourceLayout.LayoutParameterKeyInfos.Add(new ParameterKeyInfo(subkey, currentDataRange.SourceStart + currentDataRange.Size, parameterKeyInfo.Count));

                            var elementCount = parameterKeyInfo.Count;
                            var elementSize  = parameterKeyInfo.Key.Size;
                            var size         = (elementSize + 15) / 16 * 16 * (elementCount - 1) + elementSize;

                            currentDataRange.Size += size;
                        }
                        else if (isResource)
                        {
                            // First time since range reset, let's setup destination offset
                            if (currentResourceRange.DestStart == -1)
                            {
                                currentResourceRange.DestStart = parameterKeyInfo.BindingSlot;
                            }

                            // Might be some empty space (padding) (probably unlikely for resources...)
                            currentResourceRange.Size = parameterKeyInfo.BindingSlot - currentResourceRange.DestStart;

                            sourceLayout.LayoutParameterKeyInfos.Add(new ParameterKeyInfo(subkey, currentResourceRange.SourceStart + currentResourceRange.Size));

                            currentResourceRange.Size += parameterKeyInfo.Count;
                        }
                    }
                    else
                    {
                        // Found one item not part of the range, let's finish it
                        if (isData)
                        {
                            FlushRangeIfNecessary(ref currentDataRange);
                        }
                        else if (isResource)
                        {
                            FlushRangeIfNecessary(ref currentResourceRange);
                        }
                    }
                }

                // Finish ranges
                FlushRangeIfNecessary(ref currentDataRange);
                FlushRangeIfNecessary(ref currentResourceRange);

                // Update sizes
                sourceLayout.BufferSize    = currentDataRange.SourceStart;
                sourceLayout.ResourceCount = currentResourceRange.SourceStart;

                source.UpdateLayout(sourceLayout);
            }