private void CompileExpressionContext(IEnumerable <VFXContext> contexts, VFXExpressionContextOption options, VFXDeviceTarget target, VFXExpression.Flags forbiddenFlags = VFXExpression.Flags.None) { var expressionContext = new VFXExpression.Context(options, m_GlobalEventAttributes); var contextsToExpressions = target == VFXDeviceTarget.GPU ? m_ContextsToGPUExpressions : m_ContextsToCPUExpressions; var expressionsToReduced = target == VFXDeviceTarget.GPU ? m_GPUExpressionsToReduced : m_CPUExpressionsToReduced; foreach (var context in contexts) { var mapper = context.GetExpressionMapper(target); if (mapper != null) { foreach (var exp in mapper.expressions) { expressionContext.RegisterExpression(exp); } contextsToExpressions.Add(context, mapper); } } expressionContext.Compile(); foreach (var exp in expressionContext.RegisteredExpressions) { var reduced = expressionContext.GetReduced(exp); if (expressionsToReduced.ContainsKey(exp)) { if (reduced != expressionsToReduced[exp]) { throw new InvalidOperationException("Unexpected diverging expression reduction"); } continue; } expressionsToReduced.Add(exp, reduced); } var allReduced = expressionContext.BuildAllReduced(); if (forbiddenFlags != VFXExpression.Flags.None) { var check = allReduced.Any(e => e.IsAny(forbiddenFlags)); if (check) { //TODO: Provide an error in GUI when feedback is possible throw new InvalidOperationException("Invalid expression usage while compiling"); } } m_Expressions.UnionWith(allReduced); foreach (var exp in expressionsToReduced.Values) { AddExpressionDataRecursively(m_ExpressionsData, exp); } }
public Context(VFXExpressionContextOption reductionOption = VFXExpressionContextOption.Reduction) { m_ReductionOptions = reductionOption; if (Has(VFXExpressionContextOption.CPUEvaluation) && Has(VFXExpressionContextOption.GPUDataTransformation)) { throw new ArgumentException("Invalid reduction options"); } }
public Context(VFXExpressionContextOption reductionOption, List <VFXLayoutElementDesc> globalEventAttibutes = null) { m_ReductionOptions = reductionOption; m_GlobalEventAttribute = globalEventAttibutes; if (Has(VFXExpressionContextOption.CPUEvaluation) && Has(VFXExpressionContextOption.GPUDataTransformation)) { throw new ArgumentException("Invalid reduction options"); } }
public void CompileExpressions(VFXGraph graph, VFXExpressionContextOption options, bool filterOutInvalidContexts = false) { var models = new HashSet <ScriptableObject>(); graph.CollectDependencies(models, false); var contexts = models.OfType <VFXContext>(); if (filterOutInvalidContexts) { contexts = contexts.Where(c => c.CanBeCompiled()); } CompileExpressions(contexts, options); }
public void CompileExpressions(IEnumerable <VFXContext> contexts, VFXExpressionContextOption options) { Profiler.BeginSample("VFXEditor.CompileExpressionGraph"); try { m_Expressions.Clear(); m_FlattenedExpressions.Clear(); m_ExpressionsData.Clear(); CompileExpressionContext(contexts, options, VFXDeviceTarget.CPU); CompileExpressionContext(contexts, options | VFXExpressionContextOption.GPUDataTransformation, VFXDeviceTarget.GPU); var sortedList = m_ExpressionsData.Where(kvp => { var exp = kvp.Key; return(!exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)); }).ToList(); // remove per element expression from flattened data // TODO Remove uniform constants too sortedList.Sort((kvpA, kvpB) => kvpB.Value.depth.CompareTo(kvpA.Value.depth)); m_FlattenedExpressions = sortedList.Select(kvp => kvp.Key).ToList(); // update index in expression data for (int i = 0; i < m_FlattenedExpressions.Count; ++i) { var data = m_ExpressionsData[m_FlattenedExpressions[i]]; data.index = i; m_ExpressionsData[m_FlattenedExpressions[i]] = data; } if (VFXViewPreference.advancedLogs) { Debug.Log(string.Format("RECOMPILE EXPRESSION GRAPH - NB EXPRESSIONS: {0} - NB CPU END EXPRESSIONS: {1} - NB GPU END EXPRESSIONS: {2}", m_Expressions.Count, m_CPUExpressionsToReduced.Count, m_GPUExpressionsToReduced.Count)); } } finally { Profiler.EndSample(); } }
private void CompileExpressionContext(IEnumerable <VFXContext> contexts, VFXExpressionContextOption options, VFXDeviceTarget target) { HashSet <VFXExpression> expressions = new HashSet <VFXExpression>(); var expressionContext = new VFXExpression.Context(options); var contextsToExpressions = target == VFXDeviceTarget.GPU ? m_ContextsToGPUExpressions : m_ContextsToCPUExpressions; var expressionsToReduced = target == VFXDeviceTarget.GPU ? m_GPUExpressionsToReduced : m_CPUExpressionsToReduced; contextsToExpressions.Clear(); expressionsToReduced.Clear(); foreach (var context in contexts) { var mapper = context.GetExpressionMapper(target); if (mapper != null) { foreach (var exp in mapper.expressions) { expressionContext.RegisterExpression(exp); } expressions.UnionWith(mapper.expressions); contextsToExpressions.Add(context, mapper); } } expressionContext.Compile(); foreach (var exp in expressionContext.RegisteredExpressions) { expressionsToReduced.Add(exp, expressionContext.GetReduced(exp)); } m_Expressions.UnionWith(expressionContext.BuildAllReduced()); foreach (var exp in expressionsToReduced.Values) { AddExpressionDataRecursively(m_ExpressionsData, exp); } }
private bool HasAny(VFXExpressionContextOption options) { return((m_ReductionOptions & options) != 0); }
private bool Has(VFXExpressionContextOption options) { return((m_ReductionOptions & options) == options); }
public static void DebugExpressionGraph(VFXGraph graph, VFXExpressionContextOption option, string fileName = "expGraph.dot") { var expressionGraph = new VFXExpressionGraph(); expressionGraph.CompileExpressions(graph, option, true); var mainExpressions = new Dictionary <VFXExpression, List <string> >(); FillMainExpressions(mainExpressions, expressionGraph.GPUExpressionsToReduced, expressionGraph); FillMainExpressions(mainExpressions, expressionGraph.CPUExpressionsToReduced, expressionGraph); var expressions = expressionGraph.Expressions; DotGraph dotGraph = new DotGraph(); var expressionsToDot = new Dictionary <VFXExpression, DotNode>(); foreach (var exp in expressions) { var dotNode = new DotNode(); string name = exp.GetType().Name; name += " " + exp.valueType.ToString(); string valueStr = GetExpressionValue(exp); if (!string.IsNullOrEmpty(valueStr)) { name += string.Format(" ({0})", valueStr); } dotNode.attributes[DotAttribute.Shape] = DotShape.Box; if (mainExpressions.ContainsKey(exp)) { string allOwnersStr = string.Empty; foreach (var str in mainExpressions[exp]) { allOwnersStr += "\n" + str; } name += string.Format("{0}", allOwnersStr); if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)) { dotNode.attributes[DotAttribute.Color] = DotColor.Orange; } else if (exp.Is(VFXExpression.Flags.Constant)) { dotNode.attributes[DotAttribute.Color] = DotColor.SteelBlue; } else { dotNode.attributes[DotAttribute.Color] = DotColor.Cyan; } } else if (exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)) { dotNode.attributes[DotAttribute.Color] = DotColor.Yellow; } else if (exp.Is(VFXExpression.Flags.Constant)) { dotNode.attributes[DotAttribute.Color] = DotColor.SlateGray; } else if (exp.Is(VFXExpression.Flags.Foldable)) { dotNode.attributes[DotAttribute.Color] = DotColor.LightGray; } if (dotNode.attributes.ContainsKey(DotAttribute.Color)) { dotNode.attributes[DotAttribute.Style] = DotStyle.Filled; } dotNode.Label = name; expressionsToDot[exp] = dotNode; dotGraph.AddElement(dotNode); } foreach (var exp in expressionsToDot) { var parents = exp.Key.parents; for (int i = 0; i < parents.Length; ++i) { var dotEdge = new DotEdge(expressionsToDot[parents[i]], exp.Value); if (parents.Length > 1) { dotEdge.attributes[DotAttribute.HeadLabel] = i.ToString(); } dotGraph.AddElement(dotEdge); } } var basePath = Application.dataPath; basePath = basePath.Replace("/Assets", ""); basePath = basePath.Replace("/", "\\"); var outputfile = basePath + "\\GraphViz\\output\\" + fileName; dotGraph.OutputToDotFile(outputfile); var proc = new Process(); proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.UseShellExecute = false; proc.StartInfo.FileName = "C:\\Windows\\system32\\cmd.exe"; var path = basePath + "\\GraphViz\\Postbuild.bat"; proc.StartInfo.Arguments = "/c" + path + " \"" + outputfile + "\""; proc.EnableRaisingEvents = true; proc.Start(); }
private void CompileExpressionContext(IEnumerable <VFXContext> contexts, VFXExpressionContextOption options, VFXDeviceTarget target, VFXExpression.Flags forbiddenFlags = VFXExpression.Flags.None) { var expressionContext = new VFXExpression.Context(options, m_GlobalEventAttributes); var contextsToExpressions = target == VFXDeviceTarget.GPU ? m_ContextsToGPUExpressions : m_ContextsToCPUExpressions; var expressionsToReduced = target == VFXDeviceTarget.GPU ? m_GPUExpressionsToReduced : m_CPUExpressionsToReduced; foreach (var context in contexts) { var mapper = context.GetExpressionMapper(target); if (mapper != null) { foreach (var exp in mapper.expressions) { expressionContext.RegisterExpression(exp); } contextsToExpressions.Add(context, mapper); } } expressionContext.Compile(); foreach (var exp in expressionContext.RegisteredExpressions) { var reduced = expressionContext.GetReduced(exp); if (expressionsToReduced.ContainsKey(exp)) { if (reduced != expressionsToReduced[exp]) { throw new InvalidOperationException("Unexpected diverging expression reduction"); } continue; } expressionsToReduced.Add(exp, reduced); } var allReduced = expressionContext.BuildAllReduced(); m_Expressions.UnionWith(allReduced); foreach (var exp in expressionsToReduced.Values) { AddExpressionDataRecursively(m_ExpressionsData, exp); } var graphicsBufferUsageType = m_GraphicsBufferUsageType .Concat(expressionContext.GraphicsBufferUsageType) .GroupBy(o => o.Key).ToArray(); m_GraphicsBufferUsageType.Clear(); foreach (var expression in graphicsBufferUsageType) { var types = expression.Select(o => o.Value); if (types.Count() != 1) { throw new InvalidOperationException("Diverging type usage for GraphicsBuffer : " + types.Select(o => o.ToString()).Aggregate((a, b) => a + b)); } m_GraphicsBufferUsageType.Add(expression.Key, types.First()); } }
public void CompileExpressions(IEnumerable <VFXContext> contexts, VFXExpressionContextOption options) { Profiler.BeginSample("VFXEditor.CompileExpressionGraph"); try { ComputeEventAttributeDescs(m_GlobalEventAttributes, contexts); m_Expressions.Clear(); m_FlattenedExpressions.Clear(); m_CommonExpressionCount = 0u; m_ExpressionsData.Clear(); m_ContextsToGPUExpressions.Clear(); m_ContextsToCPUExpressions.Clear(); m_GPUExpressionsToReduced.Clear(); m_CPUExpressionsToReduced.Clear(); var spawnerContexts = contexts.Where(o => o.contextType == VFXContextType.Spawner); var otherContexts = contexts.Where(o => o.contextType != VFXContextType.Spawner); CompileExpressionContext(spawnerContexts, options | VFXExpressionContextOption.PatchReadToEventAttribute, VFXDeviceTarget.CPU, VFXExpression.Flags.NotCompilableOnCPU); CompileExpressionContext(otherContexts, options, VFXDeviceTarget.CPU, VFXExpression.Flags.NotCompilableOnCPU | VFXExpression.Flags.PerSpawn); CompileExpressionContext(contexts, options | VFXExpressionContextOption.GPUDataTransformation, VFXDeviceTarget.GPU, VFXExpression.Flags.PerSpawn); var sortedList = m_ExpressionsData.Where(kvp => { var exp = kvp.Key; return(!exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU)); // remove per element expression from flattened data // TODO Remove uniform constants too }); var expressionPerSpawn = sortedList.Where(o => o.Key.Is(VFXExpression.Flags.PerSpawn)); var expressionNotPerSpawn = sortedList.Where(o => !o.Key.Is(VFXExpression.Flags.PerSpawn)); //m_FlattenedExpressions is a concatenation of [sorted all expression !PerSpawn] & [sorted all expression Per Spawn] //It's more convenient for two reasons : // - Reduces process chunk for ComputePreProcessExpressionForSpawn // - Allows to determine the maximum index of expression while processing main expression evaluation sortedList = expressionNotPerSpawn.OrderByDescending(o => o.Value.depth); sortedList = sortedList.Concat(expressionPerSpawn.OrderByDescending(o => o.Value.depth)); m_FlattenedExpressions = sortedList.Select(o => o.Key).ToList(); m_CommonExpressionCount = (uint)expressionNotPerSpawn.Count(); // update index in expression data for (int i = 0; i < m_FlattenedExpressions.Count; ++i) { var data = m_ExpressionsData[m_FlattenedExpressions[i]]; data.index = i; m_ExpressionsData[m_FlattenedExpressions[i]] = data; } if (VFXViewPreference.advancedLogs) { Debug.Log(string.Format("RECOMPILE EXPRESSION GRAPH - NB EXPRESSIONS: {0} - NB CPU END EXPRESSIONS: {1} - NB GPU END EXPRESSIONS: {2}", m_Expressions.Count, m_CPUExpressionsToReduced.Count, m_GPUExpressionsToReduced.Count)); } } finally { Profiler.EndSample(); } }
private void TestExpressionGraph(Action <VFXGraph> init, Action <Graphs> test, VFXExpressionContextOption option) { var vfxGraph = ScriptableObject.CreateInstance <VFXGraph>(); var context = ScriptableObject.CreateInstance <ContextTest>(); var block = ScriptableObject.CreateInstance <BlockTest>(); context.AddChild(block); vfxGraph.AddChild(context); if (init != null) { init(vfxGraph); } var expressionGraph = new VFXExpressionGraph(); expressionGraph.CompileExpressions(vfxGraph, option, false); var graphs = new Graphs(); graphs.vfx = vfxGraph; graphs.exp = expressionGraph; test(graphs); }