예제 #1
0
        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);
        }
예제 #2
0
        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] = "";
            }
        }
예제 #3
0
 internal TShader(InfoSink sink, ShaderLanguage language, GLSLIntermediate intermediate, SymbolLookup symbols)
 {
     mInfoSink     = sink;
     mLanguage     = language;
     mIntermediate = intermediate;
     mSymbols      = symbols;
 }
예제 #4
0
        public bool Run(string fileName, out string result)
        {
            ShaderLanguage stage = FindLanguage(fileName);

            using (var fs = File.OpenRead(fileName))
            {
                return(Run(fs, stage, out result));
            }
        }
예제 #5
0
        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));
        }
예제 #6
0
        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));
        }
예제 #7
0
        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;
            }
        }
예제 #8
0
        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.");
            }
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
 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);
 }
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }