예제 #1
0
        /// <summary>
        /// Processes the deferred.
        /// </summary>
        /// <returns><c>true</c>, if deferred was processed, <c>false</c> otherwise.</returns>
        /// <param name="shaderStrings">Shader strings.</param>
        /// <param name="defaultVersion">use 100 for ES environment, 110 for desktop</param>
        /// <param name="defaultProfile">Default profile.</param>
        /// <param name="forceDefaultVersionAndProfile">set version/profile to defaultVersion/defaultProfile regardless of the #version directive in the source code </param>
        /// <param name="forwardCompatible">give errors for use of deprecated features</param>
        /// <param name="messages">warnings/errors/AST; things to print out</param>
        /// <param name="processingContext">Processing context.</param>
        private bool ProcessDeferred(
            string[] shaderStrings,
            int defaultVersion,
            Profile defaultProfile,
            bool forceDefaultVersionAndProfile,
            bool forwardCompatible,
            MessageType messages,
            Func <ParseContext,
                  PreprocessorContext,
                  InputScanner,
                  bool,
                  bool> processingContext)
        {
            if (shaderStrings.Length == 0)
            {
                return(true);
            }

            // First, without using the preprocessor or parser, find the #version, so we know what
            // symbol tables, processing rules, etc. to set up.  This does not need the extra strings
            // outlined above, just the user shader.
            int     version;
            Profile profile;
            var     userInput = new InputScanner(shaderStrings, 0, 0);           // no preamble
            bool    versionNotFirstToken;
            bool    versionNotFirst = userInput.scanVersion(out version, out profile, out versionNotFirstToken);
            bool    versionNotFound = version == 0;

            if (forceDefaultVersionAndProfile)
            {
                if (((messages & MessageType.SuppressWarnings) == 0) && !versionNotFound &&
                    (version != defaultVersion || profile != defaultProfile))
                {
                    mInfoSink.Info
                    .Append("Warning, (version, profile) forced to be (")
                    .Append(defaultVersion.ToString())
                    .Append(", ")
                    .Append(ProfileName(defaultProfile))
                    .Append("), while in source code it is (")
                    .Append(version.ToString())
                    .Append(", ")
                    .Append(ProfileName(profile))
                    .Append(")\n");
                }

                if (versionNotFound)
                {
                    versionNotFirstToken = false;
                    versionNotFirst      = false;
                    versionNotFound      = false;
                }
                version = defaultVersion;
                profile = defaultProfile;
            }
            bool goodVersion = DeduceVersionProfile(
                mInfoSink,
                mLanguage,
                versionNotFirst,
                defaultVersion,
                ref version,
                ref profile);
            bool versionWillBeError  = (versionNotFound || (profile == Profile.EsProfile && version >= 300 && versionNotFirst));
            bool warnVersionNotFirst = false;

            if (!versionWillBeError && versionNotFirstToken)
            {
                if ((messages & MessageType.RelaxedErrors) > 0)
                {
                    warnVersionNotFirst = true;
                }
                else
                {
                    versionWillBeError = true;
                }
            }
            mIntermediate.setVersion(version);
            mIntermediate.setProfile(profile);
            //
            // Now we can process the full shader under proper symbols and rules.
            //

            var parseContext = new ParseContext(version, profile, mInfoSink, forwardCompatible, mSymbols, mIntermediate);
            var ppContext    = new PreprocessorContext(parseContext, mSymbols);

            parseContext.setPpContext(ppContext);
            if (!goodVersion)
            {
                parseContext.addError();
            }
            if (warnVersionNotFirst)
            {
                SourceLocation loc = new SourceLocation();
                parseContext.Warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
            }

            parseContext.initializeExtensionBehavior();

            var fullInput = new InputScanner(shaderStrings, 0, 0);

            bool success = processingContext(parseContext, ppContext, fullInput, versionWillBeError);

            return(success);
        }