private static void GetFunctionName(VFXBlock block, out string functionName, out string comment) { var settings = block.GetSettings(true).ToArray(); if (settings.Length > 0) { comment = ""; int hash = 0; foreach (var setting in settings) { var value = setting.value; hash = (hash * 397) ^ value.GetHashCode(); comment += string.Format("{0}:{1} ", setting.field.Name, value.ToString()); } functionName = string.Format("{0}_{1}", block.GetType().Name, hash.ToString("X")); } else { comment = null; functionName = block.GetType().Name; } }
public void CollectAttributes() { if (m_Contexts == null) // Context hasnt been initialized (may happen in unity tests but not during actual compilation) { InitImplicitContexts(); } m_DependenciesIn = new HashSet <VFXData>( m_Contexts.Where(c => c.contextType == VFXContextType.Init) .SelectMany(c => c.inputContexts.Where(i => i.contextType == VFXContextType.SpawnerGPU)) .SelectMany(c => c.allLinkedInputSlot) .Where(s => { if (s.owner is VFXBlock) { VFXBlock block = (VFXBlock)(s.owner); if (block.enabled) { return(true); } } else if (s.owner is VFXContext) { return(true); } return(false); }) .Select(s => ((VFXModel)s.owner).GetFirstOfType <VFXContext>()) .Where(c => c.CanBeCompiled()) .Select(c => c.GetData()) ); m_DependenciesOut = new HashSet <VFXData>( owners.SelectMany(o => o.allLinkedOutputSlot) .Select(s => (VFXContext)s.owner) .Where(c => c.CanBeCompiled()) .SelectMany(c => c.outputContexts) .Where(c => c.CanBeCompiled()) .Select(c => c.GetData()) ); m_ContextsToAttributes.Clear(); m_AttributesToContexts.Clear(); var processedExp = new HashSet <VFXExpression>(); bool changed = true; int count = 0; while (changed) { ++count; var attributeContexts = new List <VFXAttributeInfoContext>(); foreach (var context in m_Contexts) { processedExp.Clear(); var attributes = Enumerable.Empty <VFXAttributeInfo>(); attributes = attributes.Concat(context.attributes); foreach (var block in context.activeFlattenedChildrenWithImplicit) { attributes = attributes.Concat(block.attributes); } var mapper = context.GetExpressionMapper(GetCompilationTarget(context)); if (mapper != null) { foreach (var exp in mapper.expressions) { attributes = attributes.Concat(CollectInputAttributes(exp, processedExp)); } } attributeContexts.Add(new VFXAttributeInfoContext { attributes = attributes.ToArray(), context = context }); } changed = false; foreach (var context in attributeContexts) { foreach (var attribute in context.attributes) { if (AddAttribute(context.context, attribute)) { changed = true; } } } } ProcessAttributes(); //TMP Debug only DebugLogAttributes(); }
private static void BuildBlock(VFXContextCompiledData contextData, List <VFXSlot> linkedEventOut, VFXShaderWriter blockFunction, VFXShaderWriter blockCallFunction, HashSet <string> blockDeclared, Dictionary <VFXExpression, string> expressionToName, VFXBlock block, ref int blockIndex) { var parameters = block.mergedAttributes.Select(o => { return(new VFXShaderWriter.FunctionParameter { name = o.attrib.name, expression = new VFXAttributeExpression(o.attrib) as VFXExpression, mode = o.mode }); }).ToList(); foreach (var parameter in block.parameters) { var expReduced = contextData.gpuMapper.FromNameAndId(parameter.name, blockIndex); if (VFXExpression.IsTypeValidOnGPU(expReduced.valueType)) { parameters.Add(new VFXShaderWriter.FunctionParameter { name = parameter.name, expression = expReduced, mode = VFXAttributeMode.None }); } } string methodName, commentMethod; GetFunctionName(block, out methodName, out commentMethod); if (!blockDeclared.Contains(methodName)) { blockDeclared.Add(methodName); blockFunction.WriteBlockFunction(contextData.gpuMapper, methodName, block.source, parameters, commentMethod); } //< Parameters (computed and/or extracted from uniform) var expressionToNameLocal = expressionToName; bool needScope = parameters.Any(o => !expressionToNameLocal.ContainsKey(o.expression)); if (needScope) { expressionToNameLocal = new Dictionary <VFXExpression, string>(expressionToNameLocal); blockCallFunction.EnterScope(); foreach (var exp in parameters.Select(o => o.expression)) { if (expressionToNameLocal.ContainsKey(exp)) { continue; } blockCallFunction.WriteVariable(exp, expressionToNameLocal); } } var indexEventCount = parameters.FindIndex(o => o.name == VFXAttribute.EventCount.name); if (indexEventCount != -1) { if ((parameters[indexEventCount].mode & VFXAttributeMode.Read) != 0) { throw new InvalidOperationException(string.Format("{0} isn't expected as read (special case)", VFXAttribute.EventCount.name)); } blockCallFunction.WriteLine(string.Format("{0} = 0u;", VFXAttribute.EventCount.GetNameInCode(VFXAttributeLocation.Current))); } blockCallFunction.WriteCallFunction(methodName, parameters, contextData.gpuMapper, expressionToNameLocal); if (indexEventCount != -1) { foreach (var outputSlot in block.outputSlots.SelectMany(o => o.LinkedSlots)) { var eventIndex = linkedEventOut.IndexOf(outputSlot); if (eventIndex != -1) { blockCallFunction.WriteLineFormat("{0}_{1} += {2};", VFXAttribute.EventCount.name, VFXCodeGeneratorHelper.GeneratePrefix((uint)eventIndex), VFXAttribute.EventCount.GetNameInCode(VFXAttributeLocation.Current)); } } } if (needScope) { blockCallFunction.ExitScope(); } blockIndex++; }
public override bool Accept(VFXBlock block, int index = -1) { return((block.compatibleContexts & compatibleContextType) == compatibleContextType); }
public static void MigrateBlockTShapeFromShape(VFXBlock to, VFXBlock from) { var fromSettings = from.GetSettings(true); var toSettings = to.GetSettings(true); foreach (var fromSetting in fromSettings) { var toSetting = toSettings.FirstOrDefault(o => o.name.Equals(fromSetting.name, StringComparison.InvariantCultureIgnoreCase)); if (toSetting.field != null) { to.SetSettingValue(toSetting.name, fromSetting.value); } } if (from.inputSlots.Count != to.inputSlots.Count) { throw new InvalidOperationException(); } for (int i = 0; i < from.inputSlots.Count; ++i) { var fromInputSlot = from.inputSlots[i]; var toInputSlot = to.inputSlots[i]; if (toInputSlot.property.type == fromInputSlot.property.type) { VFXSlot.CopyLinksAndValue(toInputSlot, fromInputSlot, true); } else if (toInputSlot.property.type == typeof(TArcSphere)) { MigrateTArcSphereFromArcSphere(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TArcCircle)) { MigrateTArcCircleFromArcCircle(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TArcTorus)) { MigrateTArcTorusFromArcTorus(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TArcCone)) { //There wasn't a TArcCylinder type MigrateTArcConeFromArcCone(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TSphere)) { MigrateTSphereFromSphere(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TCircle)) { MigrateTCircleFromCircle(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TTorus)) { MigrateTTorusFromTorus(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TCone) && fromInputSlot.property.type == typeof(Cone)) { //Actually, no reference of this case MigrateTConeFromCone(toInputSlot, fromInputSlot); } else if (toInputSlot.property.type == typeof(TCone) && fromInputSlot.property.type == typeof(Cylinder)) { MigrateTConeFromCylinder(toInputSlot, fromInputSlot); } else { throw new NotImplementedException(); } } }