public ShaderClassType ParseSource(string shaderSource, LoggerResult log) { var parsingResult = ParadoxShaderParser.TryParse(shaderSource, null); parsingResult.CopyTo(log); if (parsingResult.HasErrors) { return(null); } var shader = parsingResult.Shader; var shaderClass = shader.Declarations.OfType <ShaderClassType>().Single(); shaderClass.SourcePath = null; // shaderSource.Path; shaderClass.SourceHash = ObjectId.Empty; // shaderSource.Hash; shaderClass.PreprocessedSourceHash = ObjectId.Empty; // hashPreprocessSource; shaderClass.IsInstanciated = false; return(shaderClass); }
private ShaderClassType LoadShaderClass(string type, string generics, LoggerResult log, SiliconStudio.Shaders.Parser.ShaderMacro[] macros = null, HashSet <string> modifiedShaders = null) { if (type == null) { throw new ArgumentNullException("type"); } var shaderSourceKey = new ShaderSourceKey(type, generics, macros); lock (loadedShaders) { // Already instantiated ShaderClassType shaderClass; if (loadedShaders.TryGetValue(shaderSourceKey, out shaderClass)) { return(shaderClass); } // Load file var shaderSource = SourceManager.LoadShaderSource(type, modifiedShaders); // TODO USE ORIGINAL SOURCE PATH and not to object database path var preprocessedSource = PreProcessor.Run(shaderSource.Source, shaderSource.Path, macros); byte[] byteArray = Encoding.ASCII.GetBytes(preprocessedSource); var hashPreprocessSource = ObjectId.FromBytes(byteArray); // Compile var parsingResult = ParadoxShaderParser.TryParse(preprocessedSource, shaderSource.Path); parsingResult.CopyTo(log); if (parsingResult.HasErrors) { return(null); } var shader = parsingResult.Shader; // As shaders can be embedded in namespaces, get only the shader class and make sure there is only one in a pdxsl. var shaderClassTypes = GetShaderClassTypes(shader.Declarations).ToList(); if (shaderClassTypes.Count != 1) { throw new InvalidOperationException(string.Format("Shader [{0}] must contain only a single Shader class type intead of [{1}]", type, shaderClassTypes.Count)); } shaderClass = shaderClassTypes.First(); shaderClass.SourcePath = shaderSource.Path; shaderClass.SourceHash = shaderSource.Hash; shaderClass.PreprocessedSourceHash = hashPreprocessSource; shaderClass.IsInstanciated = false; // TODO: We should not use Console. Change the way we log things here Console.WriteLine("Loading Shader {0}{1}", type, macros != null && macros.Length > 0 ? String.Format("<{0}>", string.Join(", ", macros)) : string.Empty); if (shaderClass.Name.Text != type) { throw new InvalidOperationException(string.Format("Unable to load shader [{0}] not maching class name [{1}]", type, shaderClass.Name.Text)); } // Only full version are stored loadedShaders.Add(shaderSourceKey, shaderClass); return(shaderClass); } }
private ShaderClassType LoadShaderClass(ShaderClassSource classSource, string generics, LoggerResult log, SiliconStudio.Shaders.Parser.ShaderMacro[] macros = null) { var type = classSource.ClassName; if (type == null) { throw new ArgumentNullException("type"); } var shaderSourceKey = new ShaderSourceKey(type, generics, macros); lock (loadedShaders) { // Already instantiated ShaderClassType shaderClass; if (loadedShaders.TryGetValue(shaderSourceKey, out shaderClass)) { return(shaderClass); } // Load file var shaderSource = SourceManager.LoadShaderSource(type); string preprocessedSource; try { preprocessedSource = PreProcessor.Run(shaderSource.Source, shaderSource.Path, macros); } catch (Exception ex) { log.Error(MessageCode.ErrorUnexpectedException, new SourceSpan(new SourceLocation(shaderSource.Path, 0, 1, 1), 1), ex); return(null); } byte[] byteArray = Encoding.ASCII.GetBytes(preprocessedSource); var hashPreprocessSource = ObjectId.FromBytes(byteArray); // Compile var parsingResult = ParadoxShaderParser.TryParse(preprocessedSource, shaderSource.Path); parsingResult.CopyTo(log); if (parsingResult.HasErrors) { return(null); } var shader = parsingResult.Shader; // As shaders can be embedded in namespaces, get only the shader class and make sure there is only one in a pdxsl. var shaderClassTypes = ParadoxShaderParser.GetShaderClassTypes(shader.Declarations).ToList(); if (shaderClassTypes.Count != 1) { var sourceSpan = new SourceSpan(new SourceLocation(shaderSource.Path, 0, 0, 0), 1); if (shaderClassTypes.Count > 1) { sourceSpan = shaderClassTypes[1].Span; } log.Error(ParadoxMessageCode.ShaderMustContainSingleClassDeclaration, sourceSpan, type); return(null); } shaderClass = shaderClassTypes.First(); shaderClass.SourcePath = shaderSource.Path; shaderClass.SourceHash = shaderSource.Hash; shaderClass.PreprocessedSourceHash = hashPreprocessSource; shaderClass.IsInstanciated = false; // TODO: We should not use Console. Change the way we log things here // Console.WriteLine("Loading Shader {0}{1}", type, macros != null && macros.Length > 0 ? String.Format("<{0}>", string.Join(", ", macros)) : string.Empty); // If the file name is not matching the class name, provide an error if (shaderClass.Name.Text != type) { log.Error(ParadoxMessageCode.FileNameNotMatchingClassName, shaderClass.Name.Span, type, shaderClass.Name.Text); return(null); } loadedShaders.Add(shaderSourceKey, shaderClass); return(shaderClass); } }