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; }
static TransformationKeys() { View = ParameterKeys.NewValue(Matrix.Identity); Projection = ParameterKeys.NewValue(Matrix.Identity); World = ParameterKeys.NewValue(Matrix.Identity); WorldView = ParameterKeys.NewValue(Matrix.Identity); WorldViewProjection = ParameterKeys.NewValue(Matrix.Identity); WorldInverse = ParameterKeys.NewValue(Matrix.Identity); WorldInverseTranspose = ParameterKeys.NewValue(Matrix.Identity); ViewInverse = ParameterKeys.NewValue(Matrix.Identity); ProjectionInverse = ParameterKeys.NewValue(Matrix.Identity); WorldViewInverse = ParameterKeys.NewValue(Matrix.Identity); WorldScale = ParameterKeys.NewValue(Vector3.One); }
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); } } }
/// <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); }
static SpriteBaseKeys() { MatrixTransform = ParameterKeys.NewValue(Matrix.Identity); }