ShaderCompiler::ShaderParser class

Parses and lowers the ".shader" input language.

Public static functions

static auto ParseDocuments(StringView content, SmallVectorImpl<ShaderDocument>& documents, Diagnostic& diag) -> bool
static void SplitLines(StringView content, SmallVectorImpl<SourceLine>& lines)
static void StripComments(SmallVectorImpl<SourceLine>& lines)
static auto ExpandIncludes(String& content, StringView baseDir, FileReader& reader, std::int32_t depth, String& error) -> bool
static auto BuildStageSource(const ShaderDocument& document, bool vertexStage, StringView define, bool softwareRenderer = false, bool noDynamicBranching = false) -> String
static auto DirectoryOf(StringView path) -> String

Function documentation

static bool ShaderCompiler::ShaderParser::ParseDocuments(StringView content, SmallVectorImpl<ShaderDocument>& documents, Diagnostic& diag)

Parses the whole (include-expanded) file content and lowers it into one or more ShaderDocuments. Custom-mode files (the default, no "shader_type" statement) produce exactly one document; "shader_type canvas_item;" files produce the primary document plus, when "batched <Name>;" is present, its batched twin.

static void ShaderCompiler::ShaderParser::SplitLines(StringView content, SmallVectorImpl<SourceLine>& lines)

Splits raw file content into lines (handles CRLF/CR and backslash-newline continuations)

static void ShaderCompiler::ShaderParser::StripComments(SmallVectorImpl<SourceLine>& lines)

Removes line comments and block comments in place (newlines and line numbering are preserved)

static bool ShaderCompiler::ShaderParser::ExpandIncludes(String& content, StringView baseDir, FileReader& reader, std::int32_t depth, String& error)

Expands #include "relative/path" lines recursively (textually), relative to baseDir, reading files through reader (the offline tool passes a filesystem reader, the engine passes its own virtual filesystem). Runs on the raw text before parsing, so both reflection and the emitted sources see the included text inlined. As a consequence, line numbers in diagnostics refer to the include-expanded stream.

static String ShaderCompiler::ShaderParser::BuildStageSource(const ShaderDocument& document, bool vertexStage, StringView define, bool softwareRenderer = false, bool noDynamicBranching = false)

Builds the compilable GLSL source of one stage (baked variant define + "#line 1" + shared prelude + stage body). The conditionals naming SOFTWARE_RENDERER or NO_DYNAMIC_BRANCHING are resolved here according to softwareRenderer and noDynamicBranching, like the stage macros are at assembly time - the built sources never contain either macro itself. Both the "#ifdef"/"#ifndef" forms (with an optional "#else" and the matching "#endif") and "#if"/"#elif" expressions built from them are recognized, so one directive can replace a nest of them ("#if !SOFTWARE_RENDERER && !NO_DYNAMIC_BRANCHING"). An expression that also names a macro this resolver does not own ("#if DITHER && !SOFTWARE_RENDERER") keeps its conditional for the GLSL compiler and loses only the backend macros.

Whatever conditional survives is then lowered for the GLSL preprocessor that will read it: a purely boolean "#if" collapses to "#ifdef"/"#ifndef" or has its flags wrapped in "defined(...)", because the ES profiles reject an undefined macro inside an "#if" expression - see LowerEmittedCondition.

Both default to false, so an emission that passes neither comes out byte-for-byte unchanged. Only the offline GLSL-to-C++ software-fragment transpiler sets softwareRenderer, so a shader can carry a cheaper software-renderer variant of a too-expensive fragment path. Only the PlayStation 3 emission sets noDynamicBranching: a fragment stage that compiles to NV40 IF/LOOP/BRK control flow does not survive that toolchain - the branch body overwrites registers the surrounding code is still holding, which silently corrupted the textured background's horizon tint - so a shader gates any dynamically branching block on it.

static String ShaderCompiler::ShaderParser::DirectoryOf(StringView path)

Returns the directory part of path, or "." if it has none