public static ShaderClassType ParseSource(string shaderSource, LoggerResult log) { var parsingResult = XenkoShaderParser.TryParse(shaderSource, null); parsingResult.CopyTo(log); if (parsingResult.HasErrors) { return(null); } var shader = parsingResult.Shader; var shaderClass = shader.Declarations.OfType <ShaderClassType>().SingleOrDefault(); if (shaderClass == null) { var queue = new Queue <NamespaceBlock>(shader.Declarations.OfType <NamespaceBlock>()); while (queue.Count > 0 && shaderClass == null) { var namespaceNode = queue.Dequeue(); shaderClass = namespaceNode.Body.OfType <ShaderClassType>().SingleOrDefault(); foreach (var subNamespace in namespaceNode.Body.OfType <NamespaceBlock>()) { queue.Enqueue(subNamespace); } } } return(shaderClass); }
public static byte[] GenerateCode(string inputFileName, string inputFileContent) { // Always output a result into the file string result; try { var parsingResult = XenkoShaderParser.TryPreProcessAndParse(inputFileContent, inputFileName); if (parsingResult.HasErrors) { result = "// Failed to parse the shader:\n" + parsingResult; } else { // Try to generate a mixin code. var shaderKeyGenerator = new ShaderMixinCodeGen(parsingResult.Shader, parsingResult); shaderKeyGenerator.Run(); result = shaderKeyGenerator.Text ?? string.Empty; } } catch (Exception ex) { result = "// Unexpected exceptions occurred while generating the file\n" + ex; } // We force the UTF8 to include the BOM to match VS default var data = Encoding.UTF8.GetBytes(result); return(Encoding.UTF8.GetPreamble().Concat(data).ToArray()); }
public override void SaveGeneratedAsset(AssetItem assetItem) { //generate the .cs files // Always output a result into the file string result; try { var parsingResult = XenkoShaderParser.TryPreProcessAndParse(Text, assetItem.FullPath); if (parsingResult.HasErrors) { result = "// Failed to parse the shader:\n" + parsingResult; } else { // Try to generate a mixin code. var shaderKeyGenerator = new ShaderMixinCodeGen(parsingResult.Shader, parsingResult); shaderKeyGenerator.Run(); result = shaderKeyGenerator.Text ?? string.Empty; } } catch (Exception ex) { result = "// Unexpected exceptions occurred while generating the file\n" + ex; } // We force the UTF8 to include the BOM to match VS default var data = Encoding.UTF8.GetBytes(result); File.WriteAllBytes(assetItem.GetGeneratedAbsolutePath(), data); }
public static byte[] GenerateCode(string inputFileName, string inputFileContent) { // Always output a result into the file string result; try { SiliconStudio.Shaders.Parser.ShaderMacro[] macros; // Changed some keywords to avoid ambiguities with HLSL and improve consistency if (inputFileName != null && Path.GetExtension(inputFileName).ToLowerInvariant() == ".xkfx") { // XKFX macros = new[] { new SiliconStudio.Shaders.Parser.ShaderMacro("shader", "effect") }; } else { // XKSL macros = new[] { new SiliconStudio.Shaders.Parser.ShaderMacro("class", "shader") }; } var parsingResult = XenkoShaderParser.TryPreProcessAndParse(inputFileContent, inputFileName, macros); if (parsingResult.HasErrors) { result = "// Failed to parse the shader:\n" + parsingResult; } else { // Try to generate a mixin code. var shaderKeyGenerator = new ShaderMixinCodeGen(parsingResult.Shader, parsingResult); shaderKeyGenerator.Run(); result = shaderKeyGenerator.Text ?? string.Empty; } } catch (Exception ex) { result = "// Unexpected exceptions occurred while generating the file\n" + ex; } // We force the UTF8 to include the BOM to match VS default var data = Encoding.UTF8.GetBytes(result); return(Encoding.UTF8.GetPreamble().Concat(data).ToArray()); }
/// <summary> /// Generates the csharp code from a xkfx file. /// </summary> /// <param name="xkfxShaderCode">The PDXFX shader code.</param> /// <param name="filePath">The file path.</param> /// <returns>System.String.</returns> /// <exception cref="System.InvalidOperationException"></exception> public static string GenerateCsharp(string xkfxShaderCode, string filePath) { // Compile var shader = XenkoShaderParser.PreProcessAndParse(xkfxShaderCode, filePath); // Try to generate a mixin code. var loggerResult = new LoggerResult(); var shaderKeyGenerator = new ShaderMixinCodeGen(shader, loggerResult); if (shaderKeyGenerator.Run()) { return(shaderKeyGenerator.Text); } throw new InvalidOperationException(loggerResult.ToString()); }
public static ShaderClassType ParseSource(string shaderSource, LoggerResult log) { var parsingResult = XenkoShaderParser.TryParse(shaderSource, null); parsingResult.CopyTo(log); if (parsingResult.HasErrors) { return(null); } var shader = parsingResult.Shader; var shaderClass = shader.Declarations.OfType <ShaderClassType>().Single(); return(shaderClass); }
public override void Save(Stream stream) { //regex the class name if it has changed var className = new UFile(AbsoluteSourceLocation).GetFileName(); Text = Regex.Replace(Text, $"class {className}"); var buffer = Encoding.UTF8.GetBytes(Text); stream.Write(buffer, 0, buffer.Length); //generate the .cs files // Always output a result into the file string result; try { var parsingResult = XenkoShaderParser.TryPreProcessAndParse(Text, AbsoluteSourceLocation); if (parsingResult.HasErrors) { result = "// Failed to parse the shader:\n" + parsingResult; } else { // Try to generate a mixin code. var shaderKeyGenerator = new ShaderMixinCodeGen(parsingResult.Shader, parsingResult); shaderKeyGenerator.Run(); result = shaderKeyGenerator.Text ?? string.Empty; } } catch (Exception ex) { result = "// Unexpected exceptions occurred while generating the file\n" + ex; } // We force the UTF8 to include the BOM to match VS default var data = Encoding.UTF8.GetBytes(result); File.WriteAllBytes(GeneratedAbsolutePath, data); }
/// <summary> /// Generates the csharp code from a xkfx file. /// </summary> /// <param name="xkfxShaderCode">The PDXFX shader code.</param> /// <param name="filePath">The file path.</param> /// <returns>System.String.</returns> /// <exception cref="System.InvalidOperationException"></exception> public static string GenerateCsharp(string xkfxShaderCode, string filePath) { // In .xkfx, shader has been renamed to effect, in order to avoid ambiguities with HLSL and .xksl var macros = new [] { new Xenko.Core.Shaders.Parser.ShaderMacro("shader", "effect") }; // Compile var shader = XenkoShaderParser.PreProcessAndParse(xkfxShaderCode, filePath, macros); // Try to generate a mixin code. var loggerResult = new LoggerResult(); var shaderKeyGenerator = new ShaderMixinCodeGen(shader, loggerResult); if (shaderKeyGenerator.Run()) { return(shaderKeyGenerator.Text); } throw new InvalidOperationException(loggerResult.ToString()); }
public static ShaderClassType ParseSource(string shaderSource, LoggerResult log) { var parsingResult = XenkoShaderParser.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 LoadedShaderClassType 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 LoadedShaderClassType 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.UTF8.GetBytes(preprocessedSource); var hashPreprocessSource = ObjectId.FromBytes(byteArray); // Compile var parsingResult = XenkoShaderParser.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 xksl. var shaderClassTypes = XenkoShaderParser.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(XenkoMessageCode.ShaderMustContainSingleClassDeclaration, sourceSpan, type); return(null); } shaderClass = new LoadedShaderClassType(); shaderClass.Type = 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.Type.Name.Text != type) { log.Error(XenkoMessageCode.FileNameNotMatchingClassName, shaderClass.Type.Name.Span, type, shaderClass.Type.Name.Text); return(null); } loadedShaders.Add(shaderSourceKey, shaderClass); return(shaderClass); } }