public bool Equals(TextureSamplerMethodKey other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (this.Variables.Count != other.Variables.Count) { return(false); } if (!ReferenceEquals(other.Method, this.Method)) { return(false); } for (int i = 0; i < this.Variables.Count; i++) { if (!ReferenceEquals(this.Variables[i], other.Variables[i])) { return(false); } } return(true); }
public bool Equals(TextureSamplerMethodKey other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; if (this.Variables.Count != other.Variables.Count) return false; if (!ReferenceEquals(other.Method, this.Method)) return false; for (int i = 0; i < this.Variables.Count; i++) { if (!ReferenceEquals(this.Variables[i], other.Variables[i])) return false; } return true; }
protected override void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) { var textureParameters = new List <Parameter>(); var parameterValues = new List <Expression>(); var parameterGlobalValues = new List <Variable>(); var samplerTypes = new List <int>(); for (int i = 0; i < method.Parameters.Count; i++) { var parameter = method.Parameters[i]; if (parameter.Type is TextureType || parameter.Type.IsStateType()) { textureParameters.Add(parameter); // Find global variable var parameterValue = this.FindGlobalVariable(invoke.Arguments[i]); // Set the tag ScopeValue for the current parameter parameter.SetTag(ScopeValueKey, parameterValue); // Add only new variable if (!parameterGlobalValues.Contains(parameterValue)) { parameterGlobalValues.Add(parameterValue); } } else if (i < invoke.Arguments.Count) { parameterValues.Add(invoke.Arguments[i]); if (parameter.Type.IsSamplerType()) { samplerTypes.Add(i); } } } // We have texture/sampler parameters. We need to generate a new specialized method if (textureParameters.Count > 0) { // Order parameter values by name parameterGlobalValues.Sort((left, right) => left.Name.Text.CompareTo(right.Name.Text)); var methodKey = new TextureSamplerMethodKey(method); int indexOf = textureSamplerMethods.IndexOf(methodKey); if (indexOf < 0) { methodKey.Initialize(cloneContext); textureSamplerMethods.Add(methodKey); } else { // If a key is found again, add it as it was reused in order to keep usage in order methodKey = textureSamplerMethods[indexOf]; textureSamplerMethods.RemoveAt(indexOf); textureSamplerMethods.Add(methodKey); } methodKey.Invokers.Add(invoke); var newTarget = new VariableReferenceExpression(methodKey.NewMethod.Name) { TypeInference = { Declaration = methodKey.NewMethod, TargetType = invoke.TypeInference.TargetType } }; invoke.Target = newTarget; invoke.Arguments = parameterValues; invoke.TypeInference.Declaration = methodKey.NewMethod; invoke.TypeInference.TargetType = invoke.TypeInference.TargetType; this.VisitDynamic(methodKey.NewMethod); } else { // Visit the method callstack this.VisitDynamic(method); // There is an anonymous sampler type // We need to resolve its types after the method definition was processed if (samplerTypes.Count > 0) { foreach (var samplerTypeIndex in samplerTypes) { var samplerRef = invoke.Arguments[samplerTypeIndex] as VariableReferenceExpression; if (samplerRef != null) { var samplerDecl = samplerRef.TypeInference.Declaration as Variable; ChangeVariableType(samplerDecl, method.Parameters[samplerTypeIndex].Type); } } } } // Remove temporary parameters if (textureParameters.Count > 0) { foreach (var textureParameter in textureParameters) { textureParameter.RemoveTag(ScopeValueKey); } } }
protected override void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) { var textureParameters = new List<Parameter>(); var parameterValues = new List<Expression>(); var parameterGlobalValues = new List<Variable>(); var samplerTypes = new List<int>(); for (int i = 0; i < method.Parameters.Count; i++) { var parameter = method.Parameters[i]; if (parameter.Type is TextureType || parameter.Type is StateType) { textureParameters.Add(parameter); // Find global variable var parameterValue = this.FindGlobalVariable(invoke.Arguments[i]); // Set the tag ScopeValue for the current parameter parameter.SetTag(ScopeValueKey, parameterValue); // Add only new variable if (!parameterGlobalValues.Contains(parameterValue)) parameterGlobalValues.Add(parameterValue); } else if ( i < invoke.Arguments.Count) { parameterValues.Add(invoke.Arguments[i]); if (parameter.Type is SamplerType) { samplerTypes.Add(i); } } } // We have texture/sampler parameters. We need to generate a new specialized method if (textureParameters.Count > 0) { // Order parameter values by name parameterGlobalValues.Sort((left, right) => left.Name.Text.CompareTo(right.Name.Text)); var methodKey = new TextureSamplerMethodKey(method); int indexOf = textureSamplerMethods.IndexOf(methodKey); if (indexOf < 0) { methodKey.Initialize(cloneContext); textureSamplerMethods.Add(methodKey); } else { // If a key is found again, add it as it was reused in order to keep usage in order methodKey = textureSamplerMethods[indexOf]; textureSamplerMethods.RemoveAt(indexOf); textureSamplerMethods.Add(methodKey); } methodKey.Invokers.Add(invoke); var newTarget = new VariableReferenceExpression(methodKey.NewMethod.Name) { TypeInference = { Declaration = methodKey.NewMethod, TargetType = invoke.TypeInference.TargetType } }; invoke.Target = newTarget; invoke.Arguments = parameterValues; invoke.TypeInference.Declaration = methodKey.NewMethod; invoke.TypeInference.TargetType = invoke.TypeInference.TargetType; this.VisitDynamic(methodKey.NewMethod); } else { // Visit the method callstack this.VisitDynamic(method); // There is an anonymous sampler type // We need to resolve its types after the method definition was processed if (samplerTypes.Count > 0) { foreach (var samplerTypeIndex in samplerTypes) { var samplerRef = invoke.Arguments[samplerTypeIndex] as VariableReferenceExpression; if (samplerRef != null) { var samplerDecl = samplerRef.TypeInference.Declaration as Variable; ChangeVariableType(samplerDecl, method.Parameters[samplerTypeIndex].Type); } } } } // Remove temporary parameters if (textureParameters.Count > 0) { foreach (var textureParameter in textureParameters) { textureParameter.RemoveTag(ScopeValueKey); } } }