protected override void CompileInternal(ShaderStage shaderStage, string filePath, VertexType vertexType) { var macros = Macros.Select(macro => new ShaderMacro(macro.Key, macro.Value)).ToArray(); using var includeHandler = new IncludeHandler(null); _shaderBytecode = LoadBytecode(shaderStage, filePath, includeHandler, macros); if (shaderStage == ShaderStage.Vertex && vertexType != VertexType.Unknown) { InputLayout = _graphicsFactory.CreateInputLayout(vertexType, _shaderBytecode); } switch (shaderStage) { case ShaderStage.Vertex: _shaderObject = new VertexShader(_graphicsDevice, _shaderBytecode); break; case ShaderStage.Pixel: _shaderObject = new PixelShader(_graphicsDevice, _shaderBytecode); break; case ShaderStage.Compute: _shaderObject = new ComputeShader(_graphicsDevice, _shaderBytecode); break; default: throw new ArgumentOutOfRangeException(nameof(shaderStage), shaderStage, null); } }
public object ExecuteSource(string filename, string src, IncludeHandler includeHandler = null) { var tokens = Tokenizer.Tokenize(filename, src); var ast = Parser.Parse(tokens); var compilation = Compiler.Compile(ast, includeHandler); return(this.Execute(compilation)); }
protected override void CompileStringInternal(ShaderStage shaderStage, string shaderText, VertexType vertexType) { var macros = Macros.Select(macro => new ShaderMacro(macro.Key, macro.Value)).ToArray(); using var includeHandler = new IncludeHandler(null); _shaderBytecode = CreateBytecode(shaderStage, shaderText, includeHandler, macros); _shaderObject = CreateShader(shaderStage, vertexType); }
/// <summary> /// Create new compile options /// </summary> public CompileOptions(IncludeHandler includeCallback = null) { IncludeCallback = includeCallback; _handle = ShadercNative.shaderc_compile_options_initialize(); includeFunction = new ShadercNative.IncludeFunction(DelegateWrapper); releaseInclude = new ShadercNative.ReleaseInclude(ReleaseInclude); ShadercNative.shaderc_compile_options_set_include_callbacks(_handle, includeFunction, releaseInclude, IntPtr.Zero); }
public CompileParams(string filename, string fx, ShaderFlags shaderFlags, EffectFlags effectFlags, ShaderMacro[] shaderMacros, IncludeHandler includeHandler) { this.filename = filename; this.fx = fx; this.shaderFlags = shaderFlags; this.effectFlags = effectFlags; this.shaderMacros = shaderMacros; this.includeHandler = includeHandler; this.cacheFilename = ""; cacheFilename = getBytecodeFilename(); }
public static Runtime.Function Compile(Node node, IncludeHandler includeHandler = null) { var compiler = new Compiler { f = new Runtime.Function(), globalScope = true, includeHandler = includeHandler }; compiler.CompileExpr(node); return(compiler.f); }
public ShaderBytecode CompileFromFile(string filename, string fx, ShaderMacro[] shaderMacros) { //WARNING: using ShaderFlags.SkipOptimization simply causes compiler to go berserk when using functions, they get skipped or smth //var bytecodeOri = ShaderBytecode.CompileFromFile(filename, "fx_5_0", // ShaderFlags.WarningsAreErrors | ShaderFlags.SkipOptimization | // ShaderFlags.Debug, EffectFlags.None, null, includeHandler); var includeHandler = new IncludeHandler(); var compileParams = new CompileParams(filename, "fx_5_0", ShaderFlags.OptimizationLevel3 | ShaderFlags.SkipValidation, EffectFlags.None, shaderMacros, includeHandler); //var compileParams = new CompileParams(filename, "fx_5_0", ShaderFlags.WarningsAreErrors | ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, shaderMacros, includeHandler); var ret = CompileFromFile(compileParams); LastCompiledFiles = includeHandler.IncludedFiles.ToArray(); return(ret); }
public IShader CompileShader(string name, ShaderCompileInfo vertexInfo, ShaderCompileInfo pixelInfo) { if (name == null) { throw new ArgumentNullException("name"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name is empty or whitespace.", "name"); } CheckCompileInfo(vertexInfo, "vertexInfo"); CheckCompileInfo(pixelInfo, "pixelInfo"); ShaderBytecode vertexCode, pixelCode; using (IncludeHandler include = IncludeHandler.CreateForShader(vertexInfo.File)) vertexCode = ShaderBytecode.CompileFromFile(vertexInfo.File, vertexInfo.Function, vertexInfo.Version, ShaderFlags.None, EffectFlags.None, null, include); using (IncludeHandler include = IncludeHandler.CreateForShader(pixelInfo.File)) pixelCode = ShaderBytecode.CompileFromFile(pixelInfo.File, pixelInfo.Function, pixelInfo.Version, ShaderFlags.None, EffectFlags.None, null, include); return(new Shader(graphicsDevice, name, vertexCode, pixelCode)); }
/// <summary> /// Preprocesses the provided shader or effect source. /// </summary> /// <param name="shaderSource">An array of bytes containing the raw source of the shader or effect to preprocess.</param> /// <param name="sourceFileName">Name of the source file.</param> /// <param name="defines">A set of macros to define during preprocessing.</param> /// <param name="include">An interface for handling include files.</param> /// <returns> /// The preprocessed shader source. /// </returns> public static string Run(string shaderSource, string sourceFileName = null, ShaderMacro[] defines = null, IncludeHandler include = null) { // Stringify/Concat not supported by D3DCompiler preprocessor. shaderSource = ConcatenateTokens(shaderSource, defines); try { #if FRAMEWORK_SHADER_USE_SHARPDX string compilationErrors; shaderSource = SharpDX.D3DCompiler.ShaderBytecode.Preprocess( shaderSource, defines != null ? defines.Select(x => new SharpDX.Direct3D.ShaderMacro(x.Name, x.Definition)).ToArray() : null, new IncludeShadow(include), out compilationErrors, sourceFileName); #else IBlob blobForText = null; IBlob blobForErrors = null; var shadow = include == null ? null : new IncludeShadow(include); var data = Encoding.ASCII.GetBytes(shaderSource); int result; unsafe { fixed(void *pData = data) result = D3DPreprocess((IntPtr)pData, new IntPtr(data.Length), sourceFileName, PrepareMacros(defines), shadow != null ? shadow.NativePointer : IntPtr.Zero, out blobForText, out blobForErrors); } if (shadow != null) { shadow.Dispose(); } if (result < 0) { throw new InvalidOperationException(string.Format("Include errors: {0}", blobForErrors == null ? "" : Marshal.PtrToStringAnsi(blobForErrors.GetBufferPointer()))); } shaderSource = Marshal.PtrToStringAnsi(blobForText.GetBufferPointer()); #endif } catch (Exception ex) { Console.WriteLine("Warning, error while preprocessing file [{0}] : {1}", sourceFileName, ex.Message); } return(shaderSource); }
public IncludeShadow(IncludeHandler callback) { this.callback = callback; }
/// <summary> /// /// </summary> /// <param name="buildContext"></param> public override void Process ( AssetSource assetFile, BuildContext buildContext ) { // // Get combinations : // string shaderSource = File.ReadAllText( assetFile.FullSourcePath ); var ubershaderDecl = shaderSource.Split( new[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries ) .Select( line0 => line0.Trim() ) .Where( line1 => line1.StartsWith("$ubershader") ) .ToList(); var defineList = new List<string>(); foreach ( var comb in ubershaderDecl ) { var ue = new UbershaderEnumerator( comb, "$ubershader" ); defineList.AddRange( ue.DefineList ); } // // Start listing builder : // ListingPath = buildContext.GetTempFileName( assetFile.KeyPath, ".html" ); var htmlBuilder = new StringBuilder(); htmlBuilder.AppendFormat("<pre>"); htmlBuilder.AppendLine("<b>Ubershader assembly listing</b>"); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine("<b>Source:</b> <i>" + assetFile.KeyPath + "</i>" ); htmlBuilder.AppendLine(""); // insert includes here bit later: var includeInsert = htmlBuilder.Length; htmlBuilder.AppendLine("<b>Declarations:</b>"); foreach ( var comb in ubershaderDecl ) { htmlBuilder.AppendLine(" <i>" + comb + "</i>"); } htmlBuilder.AppendLine(""); var usdb = new List<UsdbEntry>(); var include = new IncludeHandler(buildContext); // // Build all : // foreach ( var defines in defineList ) { var id = defineList.IndexOf( defines ); var psbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".PS.dxbc" ); var vsbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".VS.dxbc" ); var gsbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".GS.dxbc" ); var hsbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".HS.dxbc" ); var dsbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".DS.dxbc" ); var csbc = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".CS.dxbc" ); var pshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".PS.html" ); var vshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".VS.html" ); var gshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".GS.html" ); var hshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".HS.html" ); var dshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".DS.html" ); var cshtm = buildContext.GetTempFileName( assetFile.KeyPath, "." + id.ToString("D8") + ".CS.html" ); var ps = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "ps_5_0", PSEntryPoint, defines, psbc, pshtm ); var vs = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "vs_5_0", VSEntryPoint, defines, vsbc, vshtm ); var gs = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "gs_5_0", GSEntryPoint, defines, gsbc, gshtm ); var hs = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "hs_5_0", HSEntryPoint, defines, hsbc, hshtm ); var ds = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "ds_5_0", DSEntryPoint, defines, dsbc, dshtm ); var cs = Compile( buildContext, include, shaderSource, assetFile.FullSourcePath, "cs_5_0", CSEntryPoint, defines, csbc, cshtm ); htmlBuilder.AppendFormat( (vs.Length==0) ? ".. " : "<a href=\"{0}\">vs</a> ", Path.GetFileName(vshtm) ); htmlBuilder.AppendFormat( (ps.Length==0) ? ".. " : "<a href=\"{0}\">ps</a> ", Path.GetFileName(pshtm) ); htmlBuilder.AppendFormat( (hs.Length==0) ? ".. " : "<a href=\"{0}\">hs</a> ", Path.GetFileName(hshtm) ); htmlBuilder.AppendFormat( (ds.Length==0) ? ".. " : "<a href=\"{0}\">ds</a> ", Path.GetFileName(dshtm) ); htmlBuilder.AppendFormat( (gs.Length==0) ? ".. " : "<a href=\"{0}\">gs</a> ", Path.GetFileName(gshtm) ); htmlBuilder.AppendFormat( (cs.Length==0) ? ".. " : "<a href=\"{0}\">cs</a> ", Path.GetFileName(cshtm) ); htmlBuilder.Append( "[" + defines + "]<br>" ); usdb.Add( new UsdbEntry( defines, ps, vs, gs, hs, ds, cs ) ); } htmlBuilder.Insert( includeInsert, "<b>Includes:</b>\r\n" + string.Join("", include.Includes.Select(s=>" <i>" + s + "</i>\r\n") ) + "\r\n"); File.WriteAllText( buildContext.GetTempFileName(assetFile.KeyPath, ".html"), htmlBuilder.ToString() ); // // Write ubershader : // using ( var fs = assetFile.OpenTargetStream(include.Includes) ) { using ( var bw = new BinaryWriter( fs ) ) { bw.WriteFourCC( Ubershader.UbershaderSignature ); // params : // bytecodes : bw.Write( usdb.Count ); foreach ( var entry in usdb ) { bw.Write( entry.Defines ); bw.WriteFourCC( Ubershader.PSBytecodeSignature ); bw.Write( entry.PSBytecode.Length ); bw.Write( entry.PSBytecode ); bw.WriteFourCC( Ubershader.VSBytecodeSignature ); bw.Write( entry.VSBytecode.Length ); bw.Write( entry.VSBytecode ); bw.WriteFourCC( Ubershader.GSBytecodeSignature ); bw.Write( entry.GSBytecode.Length ); bw.Write( entry.GSBytecode ); bw.WriteFourCC( Ubershader.HSBytecodeSignature ); bw.Write( entry.HSBytecode.Length ); bw.Write( entry.HSBytecode ); bw.WriteFourCC( Ubershader.DSBytecodeSignature ); bw.Write( entry.DSBytecode.Length ); bw.Write( entry.DSBytecode ); bw.WriteFourCC( Ubershader.CSBytecodeSignature ); bw.Write( entry.CSBytecode.Length ); bw.Write( entry.CSBytecode ); } } } }
/// <summary> /// /// </summary> /// <param name="buildContext"></param> public override void Process(AssetSource assetFile, BuildContext buildContext) { // // Get combinations : // string shaderSource = File.ReadAllText(assetFile.FullSourcePath); var ubershaderDecl = shaderSource.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(line0 => line0.Trim()) .Where(line1 => line1.StartsWith("$ubershader")) .ToList(); var defineList = new List <string>(); foreach (var comb in ubershaderDecl) { var ue = new UbershaderEnumerator(comb, "$ubershader"); defineList.AddRange(ue.DefineList); } // // Start listing builder : // ListingPath = buildContext.GetTempFileFullPath(assetFile.KeyPath, ".html"); var htmlBuilder = new StringBuilder(); htmlBuilder.AppendFormat("<pre>"); htmlBuilder.AppendLine("<b>Ubershader assembly listing</b>"); htmlBuilder.AppendLine(""); htmlBuilder.AppendLine("<b>Source:</b> <i>" + assetFile.KeyPath + "</i>"); htmlBuilder.AppendLine(""); // insert includes here bit later: var includeInsert = htmlBuilder.Length; htmlBuilder.AppendLine("<b>Declarations:</b>"); foreach (var comb in ubershaderDecl) { htmlBuilder.AppendLine(" <i>" + comb + "</i>"); } htmlBuilder.AppendLine(""); var usdb = new List <UsdbEntry>(); var include = new IncludeHandler(buildContext); // // Build all : // foreach (var defines in defineList) { var id = defineList.IndexOf(defines); var psbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".PS.dxbc"); var vsbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".VS.dxbc"); var gsbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".GS.dxbc"); var hsbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".HS.dxbc"); var dsbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".DS.dxbc"); var csbc = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".CS.dxbc"); var pshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".PS.html"); var vshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".VS.html"); var gshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".GS.html"); var hshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".HS.html"); var dshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".DS.html"); var cshtm = buildContext.GetTempFileFullPath(assetFile.KeyPath, "." + id.ToString("D8") + ".CS.html"); var ps = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "ps_5_0", PSEntryPoint, defines, psbc, pshtm); var vs = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "vs_5_0", VSEntryPoint, defines, vsbc, vshtm); var gs = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "gs_5_0", GSEntryPoint, defines, gsbc, gshtm); var hs = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "hs_5_0", HSEntryPoint, defines, hsbc, hshtm); var ds = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "ds_5_0", DSEntryPoint, defines, dsbc, dshtm); var cs = Compile(buildContext, include, shaderSource, assetFile.FullSourcePath, "cs_5_0", CSEntryPoint, defines, csbc, cshtm); htmlBuilder.AppendFormat((vs.Length == 0) ? ".. " : "<a href=\"{0}\">vs</a> ", Path.GetFileName(vshtm)); htmlBuilder.AppendFormat((ps.Length == 0) ? ".. " : "<a href=\"{0}\">ps</a> ", Path.GetFileName(pshtm)); htmlBuilder.AppendFormat((hs.Length == 0) ? ".. " : "<a href=\"{0}\">hs</a> ", Path.GetFileName(hshtm)); htmlBuilder.AppendFormat((ds.Length == 0) ? ".. " : "<a href=\"{0}\">ds</a> ", Path.GetFileName(dshtm)); htmlBuilder.AppendFormat((gs.Length == 0) ? ".. " : "<a href=\"{0}\">gs</a> ", Path.GetFileName(gshtm)); htmlBuilder.AppendFormat((cs.Length == 0) ? ".. " : "<a href=\"{0}\">cs</a> ", Path.GetFileName(cshtm)); htmlBuilder.Append("[" + defines + "]<br>"); usdb.Add(new UsdbEntry(defines, ps, vs, gs, hs, ds, cs)); } htmlBuilder.Insert(includeInsert, "<b>Includes:</b>\r\n" + string.Join("", include.Includes.Select(s => " <i>" + s + "</i>\r\n")) + "\r\n"); buildContext.WriteReport(assetFile, htmlBuilder.ToString()); // // Write ubershader : // using (var fs = assetFile.OpenTargetStream(include.Includes)) { using (var bw = new BinaryWriter(fs)) { bw.WriteFourCC(UbershaderSignature); // params : // bytecodes : bw.Write(usdb.Count); foreach (var entry in usdb) { bw.Write(entry.Defines); bw.WriteFourCC(PSBytecodeSignature); bw.Write(entry.PSBytecode.Length); bw.Write(entry.PSBytecode); bw.WriteFourCC(VSBytecodeSignature); bw.Write(entry.VSBytecode.Length); bw.Write(entry.VSBytecode); bw.WriteFourCC(GSBytecodeSignature); bw.Write(entry.GSBytecode.Length); bw.Write(entry.GSBytecode); bw.WriteFourCC(HSBytecodeSignature); bw.Write(entry.HSBytecode.Length); bw.Write(entry.HSBytecode); bw.WriteFourCC(DSBytecodeSignature); bw.Write(entry.DSBytecode.Length); bw.Write(entry.DSBytecode); bw.WriteFourCC(CSBytecodeSignature); bw.Write(entry.CSBytecode.Length); bw.Write(entry.CSBytecode); } } } }