/// <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); }