private String ReplaceExtension(String outFile, ShaderLanguage sl) { for (int i = 0; i < shaderExtensions.Length; i++) { String OldExt = Path.GetExtension(outFile); OldExt = OldExt.Remove(0, 1); if (OldExt == shaderExtensions[i]) { String NewExt; if (OldExt == "src_tesc" && sl == ShaderLanguage.MSL) { NewExt = ".vert.tesc.comp"; } else if (OldExt == "src_tese" && sl == ShaderLanguage.MSL) { NewExt = ".tese.vert"; } else { NewExt = "." + shaderOutputExtensions[i]; } OldExt = "." + OldExt; return(outFile.Replace(OldExt, NewExt)); } } return(outFile); }
void FindShaderMacros(String content, ShaderLanguage language, out string[] macros) { // Format: // USERMACRO: SAMPLE_COUNT [1,2,4] String pattern = @"// USERMACRO: ([A-Za-z0-9_]+) \[([0-9]+(,[0-9]+)*)\]"; Regex regex = new Regex(pattern); var matches = regex.Matches(content); List <ShaderMacro[]> table = new List <ShaderMacro[]>(); for (int i = 0; i < matches.Count; ++i) { table.Add(null); } for (int i = 0; i < matches.Count; ++i) { String definition = matches[i].Groups[1].Value; String[] values = matches[i].Groups[2].Value.Trim().Split(','); table[i] = new ShaderMacro[values.Length]; for (int j = 0; j < table[i].Length; ++j) { table[i][j] = new ShaderMacro { definition = definition, value = values[j], }; } } IEnumerable <string> results = new List <string> { null }; String format; switch (language) { case ShaderLanguage.HLSL: format = " -D {0}={1} "; break; case ShaderLanguage.VULKAN_GLSL: format = " \"-D {0}={1}\" "; break; default: format = ""; break; } foreach (var list in table) { // cross join the current result with each member of the next list results = results.SelectMany(o => list.Select(s => o + String.Format(format, s.definition, s.value))); } macros = results.ToArray(); if (macros.Length == 1 && macros[0] == null) { macros[0] = ""; } }
internal TShader(InfoSink sink, ShaderLanguage language, GLSLIntermediate intermediate, SymbolLookup symbols) { mInfoSink = sink; mLanguage = language; mIntermediate = intermediate; mSymbols = symbols; }
public bool Run(string fileName, out string result) { ShaderLanguage stage = FindLanguage(fileName); using (var fs = File.OpenRead(fileName)) { return(Run(fs, stage, out result)); } }
public bool Preprocess(ShaderLanguage stage, string[] shaderStrings, out string result) { var messageType = SetMessageOptions(MessageType.Default); var shader = new TShader(mInfoSink, stage, mIntermediate, mSymbols); shader.setStrings(shaderStrings); int defaultVersion = (Options & (int)TOptions.DefaultDesktop) > 0 ? 110: 100; return(shader.preprocess(defaultVersion, Profile.NoProfile, false, false, messageType, out result)); }
public bool Run(Stream fs, ShaderLanguage stage, out string result) { string shaderStrings = null; using (var sr = new StreamReader(fs)) { // shaderStrings = fs shaderStrings = sr.ReadToEnd(); } return(Preprocess(stage, new string[] { shaderStrings }, out result)); }
void DetermineShaderLanguage(String content, out ShaderLanguage language) { String vulkanPattern = "#version \\d+( core)?"; Regex regex = new Regex(vulkanPattern); if (regex.IsMatch(content)) { language = ShaderLanguage.VULKAN_GLSL; } else { language = ShaderLanguage.HLSL; } }
public void SetSource(ShaderLanguage language, string source) { switch (language) { case ShaderLanguage.GLSL: { #if OPENGL OpenGLShader = new OpenGLShader(this, source); #endif break; } default: throw new Exception("Unsupported Shader Language Provided."); } }
public override Effect CompileEffect(ShaderLanguage language, string effectSource) { string tempFile = Path.GetTempFileName(); using (var stream = new StreamWriter(tempFile)) { stream.WriteLine(effectSource); } string compilationErrors = ""; try { var effect = Direct3D.Effect.FromFile(mDisplay.D3D_Device.Device, tempFile, null, null, null, SlimDX.Direct3D9.ShaderFlags.Debug, null, out compilationErrors); return(new HlslEffect(effect)); } catch (Direct3D.Direct3D9Exception e) { throw new AgateShaderCompilerException(compilationErrors, e); } }
public bool Preprocess(ShaderLanguage stage, string[] shaderStrings, out string result) { var messageType = SetMessageOptions(MessageType.Default); var shader = new TShader(mInfoSink, stage, mIntermediate, mSymbols); shader.setStrings (shaderStrings); int defaultVersion = (Options & (int) TOptions.DefaultDesktop) > 0 ? 110: 100; return shader.preprocess (defaultVersion, Profile.NoProfile, false, false, messageType, out result); }
public bool Run(Stream fs, ShaderLanguage stage, out string result) { string shaderStrings = null; using(var sr = new StreamReader(fs)) { // shaderStrings = fs shaderStrings = sr.ReadToEnd(); } return Preprocess (stage, new string[]{shaderStrings}, out result); }
static bool DeduceVersionProfile(InfoSink infoSink, ShaderLanguage stage, bool versionNotFirst, int defaultVersion, ref int version, ref Profile profile) { const int FirstProfileVersion = 150; bool correct = true; // Get a good version... if (version == 0) { version = defaultVersion; // infoSink.info.message(EPrefixWarning, "#version: statement missing; use #version on first line of shader"); } // Get a good profile... if (profile == Profile.NoProfile) { if (version == 300 || version == 310) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: versions 300 and 310 require specifying the 'es' profile"); profile = Profile.EsProfile; } else if (version == 100) { profile = Profile.EsProfile; } else if (version >= FirstProfileVersion) { profile = Profile.CoreProfile; } else { profile = Profile.NoProfile; } } else { // a profile was provided... if (version < 150) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: versions before 150 do not allow a profile token"); if (version == 100) { profile = Profile.EsProfile; } else { profile = Profile.NoProfile; } } else if (version == 300 || version == 310) { if (profile != Profile.EsProfile) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: versions 300 and 310 support only the es profile"); } profile = Profile.EsProfile; } else { if (profile == Profile.EsProfile) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: only version 300 and 310 support the es profile"); if (version >= FirstProfileVersion) { profile = Profile.CoreProfile; } else { profile = Profile.NoProfile; } } // else: typical desktop case... e.g., "#version 410 core" } } // Correct for stage type... switch (stage) { case ShaderLanguage.Geometry: if ((profile == Profile.EsProfile && version < 310) || (profile != Profile.EsProfile && version < 150)) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: geometry shaders require es profile with version 310 or non-es profile with version 150 or above"); version = (profile == Profile.EsProfile) ? 310 : 150; if (profile == Profile.EsProfile || profile == Profile.NoProfile) { profile = Profile.CoreProfile; } } break; case ShaderLanguage.TessControl: case ShaderLanguage.TessEvaluation: if ((profile == Profile.EsProfile && version < 310) || (profile != Profile.EsProfile && version < 150)) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: tessellation shaders require es profile with version 310 or non-es profile with version 150 or above"); version = (profile == Profile.EsProfile) ? 310 : 400; // 150 supports the extension, correction is to 400 which does not if (profile == Profile.EsProfile || profile == Profile.NoProfile) { profile = Profile.CoreProfile; } } break; case ShaderLanguage.Compute: if ((profile == Profile.EsProfile && version < 310) || (profile != Profile.EsProfile && version < 420)) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 420 or above"); version = profile == Profile.EsProfile ? 310 : 430; // 420 supports the extension, correction is to 430 which does not profile = Profile.CoreProfile; } break; default: break; } if (profile == Profile.EsProfile && version >= 300 && versionNotFirst) { correct = false; infoSink.Info.WriteMessage(PrefixType.Error, "#version: statement must appear first in es-profile shader; before comments or newlines"); } // A metacheck on the condition of the compiler itself... switch (version) { // ES versions case 100: case 300: // versions are complete break; // Desktop versions case 110: case 120: case 130: case 140: case 150: case 330: // versions are complete break; case 310: case 400: case 410: case 420: case 430: case 440: case 450: infoSink.Info .Append("Warning, version ") .Append(version.ToString()) .Append(" is not yet complete; most version-specific features are present, but some are missing.\n"); break; default: infoSink.Info .Append("Warning, version ") .Append(version.ToString()) .Append(" is unknown.\n"); break; } return(correct); }