internal static byte[] Compile(string filepath, ShaderMacro[] macros, MyShaderProfile profile, string sourceDescriptor, bool optimize, bool invalidateCache, out bool wasCached, out string compileLog) { ProfilerShort.Begin("MyShaders.Compile"); var globalMacros = GlobalShaderMacros; if (globalMacros.Length != 0) { var macroList = new List <ShaderMacro>(); macroList.AddRange(globalMacros); macroList.AddRange(macros); macros = macroList.ToArray(); } string function = ProfileEntryPoint(profile); string profileName = ProfileToString(profile); wasCached = false; compileLog = null; ProfilerShort.Begin("MyShaders.Preprocess"); string errors; string preprocessedSource = PreprocessShader(filepath, macros, out errors); if (preprocessedSource == null) { compileLog = errors; return(null); } // modify preprocessor to be readable for NSight if (MyCompilationSymbols.EnableShaderDebuggingInNSight) { preprocessedSource = Regex.Replace(preprocessedSource, "#line [^\n]*\n", ""); } MyShaderIdentity identity = null; if (!invalidateCache && !MyCompilationSymbols.EnableShaderDebuggingInNSight) { identity = MyShaderCache.ComputeShaderIdentity(preprocessedSource, profile); byte[] cached; if (MyShaderCache.TryFetch(identity, out cached)) { wasCached = true; ProfilerShort.End(); ProfilerShort.End(); return(cached); } } ProfilerShort.End(); try { string descriptor = sourceDescriptor + " " + profile + " " + macros.GetString(); CompilationResult compilationResult; if (MyCompilationSymbols.EnableShaderDebuggingInNSight) { if (MyCompilationSymbols.EnableShaderPreprocessorInNSight) { compilationResult = ShaderBytecode.Compile(preprocessedSource, function, profileName, 0, 0, macros, new MyIncludeProcessor(filepath)); } else { compilationResult = ShaderBytecode.CompileFromFile(filepath, function, profileName, 0, 0, macros, new MyIncludeProcessor(filepath)); } } else { compilationResult = ShaderBytecode.Compile(preprocessedSource, function, profileName, optimize ? ShaderFlags.OptimizationLevel3 : ShaderFlags.None, EffectFlags.None, filepath); } if (DUMP_CODE) { var disassembly = compilationResult.Bytecode.Disassemble(DisassemblyFlags.EnableColorCode | DisassemblyFlags.EnableInstructionNumbering); string asmPath; if (MyRender11.DebugMode) { asmPath = Path.GetFileName(descriptor + "__DEBUG.html"); } else { asmPath = Path.GetFileName(descriptor + "__O3.html"); } using (var writer = new StreamWriter(Path.Combine(MyFileSystem.ContentPath, "ShaderOutput", asmPath))) { writer.Write(disassembly); } } if (compilationResult.Message != null) { compileLog = compilationResult.Message; } if (!MyCompilationSymbols.EnableShaderDebuggingInNSight && compilationResult.Bytecode != null && compilationResult.Bytecode.Data.Length > 0) { MyShaderCache.Store(identity, compilationResult.Bytecode.Data); } return(compilationResult.Bytecode != null ? compilationResult.Bytecode.Data : null); } catch (Exception e) { Debug.WriteLine(preprocessedSource); compileLog = e.Message; } finally { ProfilerShort.End(); } return(null); }
internal static byte[] Compile(string source, ShaderMacro[] macros, MyShadersDefines.Profiles profile, string sourceDescriptor, bool optimize, bool invalidateCache, out bool wasCached, out string compileLog) { ProfilerShort.Begin("MyShaders.Compile"); string function = MyShadersDefines.ProfileEntryPoint(profile); string profileName = MyShadersDefines.ProfileToString(profile); wasCached = false; compileLog = null; ProfilerShort.Begin("MyShaders.Preprocess"); string preprocessedSource = PreprocessShader(source, macros); var key = MyShaderCache.CalculateKey(preprocessedSource, function, profileName); if (!invalidateCache) { var cached = MyShaderCache.TryFetch(key); if (cached != null) { wasCached = true; ProfilerShort.End(); ProfilerShort.End(); return(cached); } } ProfilerShort.End(); try { string descriptor = sourceDescriptor + " " + profile + " " + macros.GetString(); CompilationResult compilationResult = ShaderBytecode.Compile(preprocessedSource, function, profileName, optimize ? ShaderFlags.OptimizationLevel3 : 0, 0, null, null, descriptor); if (DUMP_CODE) { var disassembly = compilationResult.Bytecode.Disassemble(DisassemblyFlags.EnableColorCode | DisassemblyFlags.EnableInstructionNumbering); string asmPath; if (MyRender11.DebugMode) { asmPath = Path.GetFileName(descriptor + "__DEBUG.html"); } else { asmPath = Path.GetFileName(descriptor + "__O3.html"); } using (var writer = new StreamWriter(Path.Combine(MyFileSystem.ContentPath, "ShaderOutput", asmPath))) { writer.Write(disassembly); } } if (compilationResult.Message != null) { compileLog = ExtendedErrorMessage(source, compilationResult.Message) + DumpShaderSource(key, preprocessedSource); } if (compilationResult.Bytecode.Data.Length > 0) { MyShaderCache.Store(key.ToString(), compilationResult.Bytecode.Data); } return(compilationResult.Bytecode.Data); } catch (CompilationException e) { Debug.WriteLine(preprocessedSource); compileLog = ExtendedErrorMessage(source, e.Message) + DumpShaderSource(key, preprocessedSource); } finally { ProfilerShort.End(); } return(null); }