4 using System.Collections.Generic;
7 using SiliconStudio.Core.Collections;
8 using SiliconStudio.Paradox.Effects;
10 namespace SiliconStudio.
Paradox.Graphics.Internals
28 var builder =
new StringBuilder();
31 .Append(Destination.Name)
34 foreach (var source
in Sources)
41 return builder.ToString();
58 SortedKeys = keys.OrderBy(x => x.HashCode).ToArray();
59 SortedKeyHashes = SortedKeys.Select(x => x.HashCode).ToArray();
62 dependencies = BuildDependencies(dependencies).ToArray();
65 var dependenciesIndex =
new List<ParameterDependencyIndex>();
66 foreach (var dependency
in dependencies)
68 var destinationIndex = Array.IndexOf(SortedKeys, dependency.Destination);
69 if (destinationIndex == -1)
70 throw new InvalidOperationException();
71 var sourceIndices = dependency.Sources.Select(x => Array.IndexOf(SortedKeys, x)).ToArray();
72 if (sourceIndices.Any(x => x == -1))
73 throw new InvalidOperationException();
76 Destination = destinationIndex,
77 Sources = sourceIndices,
83 this.Dependencies = dependenciesIndex.ToArray();
86 for (
int i = 0; i < ThreadLocalDynamicValues.Length; ++i)
88 ThreadLocalDynamicValues[i] = Dependencies.Select(x => ParameterCollection.CreateInternalValue(SortedKeys[x.Destination])).ToArray();
95 private static void VisitDependencies(Dictionary<
ParameterDependency, List<ParameterDependency>> graph, HashSet<ParameterDependency> processedVertices, List<ParameterDependency> result,
ParameterDependency vertex)
97 if (!processedVertices.Contains(vertex))
99 processedVertices.Add(vertex);
100 List<ParameterDependency> outEdges;
101 if (graph.TryGetValue(vertex, out outEdges))
103 foreach (var outVertex
in outEdges)
105 VisitDependencies(graph, processedVertices, result, outVertex);
110 if (!result.Contains(vertex))
123 var processedVertices =
new HashSet<ParameterDependency>();
124 var result =
new List<ParameterDependency>();
125 var keyToDependencies =
new Dictionary<ParameterKey, ParameterDependency>();
126 foreach (var dependency
in dependencies)
128 keyToDependencies[dependency.Destination] = dependency;
131 var graph =
new Dictionary<ParameterDependency, List<ParameterDependency>>();
132 foreach (var dependency
in dependencies)
134 foreach (var sourceKey
in dependency.Sources)
136 ParameterDependency source;
137 if (!keyToDependencies.TryGetValue(sourceKey, out source))
140 List<ParameterDependency> outEdges;
141 if (!graph.TryGetValue(dependency, out outEdges))
143 graph[dependency] = outEdges =
new List<ParameterDependency>();
145 outEdges.Add(source);
149 foreach (var dependency
in dependencies)
151 VisitDependencies(graph, processedVertices, result, dependency);
158 struct FastListStruct<T>
165 Count = fastList.Count;
166 Items = fastList.Items;
171 Count = array.Length;
189 internal class ShaderParameterUpdater : ParameterUpdater
191 internal int InternalValueBinarySearch(
int[] values,
int keyHash)
194 int end = values.Length - 1;
197 int middle = start + ((end - start) >> 1);
198 var hash1 = values[middle];
217 public void Update(GraphicsDevice graphicsDevice, ShaderParameterUpdaterDefinition definition,
ParameterCollection[] parameterCollections,
int levelCount)
219 Update(definition, parameterCollections, levelCount);
225 var dependencies = definition.Dependencies;
226 for (
int dependencyIndex = 0; dependencyIndex < dependencies.Length; ++dependencyIndex)
228 var dependency = dependencies[dependencyIndex];
229 int highestLevel = 0;
230 int destinationLevel = InternalValues[dependency.Destination].Key;
232 var destination = InternalValues[dependency.Destination];
233 bool needUpdate =
false;
234 for (
int i = 0; i < dependency.Sources.Length; ++i)
236 var source = InternalValues[dependency.Sources[i]];
237 var sourceLevel = source.Key;
239 if (highestLevel < sourceLevel)
240 highestLevel = sourceLevel;
243 if (destinationLevel < highestLevel)
249 int maxLevelNoOverride = levelCount - 1;
250 if (highestLevel <= maxLevelNoOverride)
255 var bestCollectionForDynamicValue = parameterCollections[maxLevelNoOverride];
256 var key = definition.SortedKeys[dependency.Destination];
257 bestCollectionForDynamicValue.SetDefault(key,
true);
258 InternalValues[dependency.Destination] = destination =
new KeyValuePair<int,
ParameterCollection.InternalValue>(highestLevel, bestCollectionForDynamicValue.GetInternalValue(key));
263 InternalValues[dependency.Destination] = destination =
new KeyValuePair<int,
ParameterCollection.InternalValue>(parameterCollections.Length, definition.ThreadLocalDynamicValues[graphicsDevice.ThreadIndex][dependencyIndex]);
270 if (!dependency.Dynamic.AutoCheckDependencies)
273 if (destination.Value.Dependencies == null || destination.Value.Dependencies.Length < dependency.Sources.Length)
274 destination.Value.Dependencies =
new ParameterCollection.InternalValueReference[dependency.Sources.Length];
276 var dependencyParameters = destination.Value.Dependencies;
277 for (
int i = 0; i < dependency.Sources.Length; ++i)
279 var source = InternalValues[dependency.Sources[i]];
280 var internalValue = source.Value;
282 if (dependencyParameters[i].Entry != internalValue)
285 dependencyParameters[i].Entry = internalValue;
286 dependencyParameters[i].Counter = internalValue.Counter;
288 else if (dependencyParameters[i].Counter != internalValue.Counter)
291 dependencyParameters[i].Counter = internalValue.Counter;
298 dependency.Dynamic.GetValue(destination.Value);
299 destination.Value.Counter++;
306 return InternalValues[index].Value;
309 public T GetValue<T>(
int index)
A resource that is accessible by both the GPU (read only) and the CPU (write only). A dynamic resource is a good choice for a resource that will be updated by the CPU at least once per frame. To update a dynamic resource, use a Map method.
Key of an effect parameter.
Similar to List{T}, with direct access to underlying array.
FastListStruct(T[] array)
ParameterDynamicValue Dynamic
override string ToString()
Base class for ParameterDynamicValue{T}.
ParameterDynamicValue Dynamic
ShaderParameterUpdaterDefinition(IEnumerable< ParameterKey > keys, IEnumerable< ParameterDependency > dependencies)
Holds a value inside ParameterCollection.
A container to handle a hierarchical collection of effect variables.
FastListStruct(FastList< T > fastList)