Skip to content
Snippets Groups Projects
Commit b8478d7e authored by John Kessenich's avatar John Kessenich
Browse files

glslang: Allow programmatically prepending code to a shader without worrying...

glslang: Allow programmatically prepending code to a shader without worrying about #version being first, to implement command-line-defined macros.  From Dejan Mircevski <deki@google.com>.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@31448 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent a49fe84a
No related branches found
No related tags found
No related merge requests found
...@@ -435,6 +435,7 @@ bool CompileDeferred( ...@@ -435,6 +435,7 @@ bool CompileDeferred(
const char* const shaderStrings[], const char* const shaderStrings[],
const int numStrings, const int numStrings,
const int* inputLengths, const int* inputLengths,
const char* customPreamble,
const EShOptimizationLevel optLevel, const EShOptimizationLevel optLevel,
const TBuiltInResource* resources, const TBuiltInResource* resources,
int defaultVersion, // use 100 for ES environment, 110 for desktop int defaultVersion, // use 100 for ES environment, 110 for desktop
...@@ -457,18 +458,20 @@ bool CompileDeferred( ...@@ -457,18 +458,20 @@ bool CompileDeferred(
// which lets the grammar accept what was a null (post preprocessing) shader. // which lets the grammar accept what was a null (post preprocessing) shader.
// //
// Shader will look like // Shader will look like
// string 0: preamble // string 0: system preamble
// string 1...numStrings: user's shader // string 1: custom preamble
// string numStrings+1: "int;" // string 2...numStrings+1: user's shader
// // string numStrings+2: "int;"
size_t* lengths = new size_t[numStrings + 2]; const int numPre = 2;
const char** strings = new const char*[numStrings + 2]; const int numPost = 1;
size_t* lengths = new size_t[numStrings + numPre + numPost];
const char** strings = new const char*[numStrings + numPre + numPost];
for (int s = 0; s < numStrings; ++s) { for (int s = 0; s < numStrings; ++s) {
strings[s + 1] = shaderStrings[s]; strings[s + numPre] = shaderStrings[s];
if (inputLengths == 0 || inputLengths[s] < 0) if (inputLengths == 0 || inputLengths[s] < 0)
lengths[s + 1] = strlen(shaderStrings[s]); lengths[s + numPre] = strlen(shaderStrings[s]);
else else
lengths[s + 1] = inputLengths[s]; lengths[s + numPre] = inputLengths[s];
} }
// First, without using the preprocessor or parser, find the #version, so we know what // First, without using the preprocessor or parser, find the #version, so we know what
...@@ -476,7 +479,7 @@ bool CompileDeferred( ...@@ -476,7 +479,7 @@ bool CompileDeferred(
// outlined above, just the user shader. // outlined above, just the user shader.
int version; int version;
EProfile profile; EProfile profile;
glslang::TInputScanner userInput(numStrings, &strings[1], &lengths[1]); // no preamble glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]); // no preamble
bool versionNotFirstToken; bool versionNotFirstToken;
bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFirst = userInput.scanVersion(version, profile, versionNotFirstToken);
bool versionNotFound = version == 0; bool versionNotFound = version == 0;
...@@ -534,9 +537,12 @@ bool CompileDeferred( ...@@ -534,9 +537,12 @@ bool CompileDeferred(
// Fill in the strings as outlined above. // Fill in the strings as outlined above.
strings[0] = parseContext.getPreamble(); strings[0] = parseContext.getPreamble();
lengths[0] = strlen(strings[0]); lengths[0] = strlen(strings[0]);
strings[numStrings + 1] = "\n int;"; strings[1] = customPreamble;
lengths[numStrings + 1] = strlen(strings[numStrings + 1]); lengths[1] = strlen(strings[1]);
TInputScanner fullInput(numStrings + 2, strings, lengths, 1, 1); assert(2 == numPre);
strings[numStrings + numPre] = "\n int;";
lengths[numStrings + numPre] = strlen(strings[numStrings + numPre]);
TInputScanner fullInput(numStrings + numPre + numPost, strings, lengths, numPre, numPost);
// Push a new symbol allocation scope that will get used for the shader's globals. // Push a new symbol allocation scope that will get used for the shader's globals.
symbolTable.push(); symbolTable.push();
...@@ -707,7 +713,7 @@ int ShCompile( ...@@ -707,7 +713,7 @@ int ShCompile(
compiler->infoSink.debug.erase(); compiler->infoSink.debug.erase();
TIntermediate intermediate(compiler->getLanguage()); TIntermediate intermediate(compiler->getLanguage());
bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, optLevel, resources, defaultVersion, forwardCompatible, messages, intermediate); bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, "", optLevel, resources, defaultVersion, forwardCompatible, messages, intermediate);
// //
// Call the machine dependent compiler // Call the machine dependent compiler
...@@ -966,7 +972,7 @@ public: ...@@ -966,7 +972,7 @@ public:
}; };
TShader::TShader(EShLanguage s) TShader::TShader(EShLanguage s)
: pool(0), stage(s) : pool(0), stage(s), preamble("")
{ {
infoSink = new TInfoSink; infoSink = new TInfoSink;
compiler = new TDeferredCompiler(stage, *infoSink); compiler = new TDeferredCompiler(stage, *infoSink);
...@@ -993,8 +999,10 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion ...@@ -993,8 +999,10 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
pool = new TPoolAllocator(); pool = new TPoolAllocator();
SetThreadPoolAllocator(*pool); SetThreadPoolAllocator(*pool);
if (! preamble)
preamble = "";
return CompileDeferred(compiler, strings, numStrings, nullptr, EShOptNone, builtInResources, defaultVersion, forwardCompatible, messages, *intermediate); return CompileDeferred(compiler, strings, numStrings, nullptr, preamble, EShOptNone, builtInResources, defaultVersion, forwardCompatible, messages, *intermediate);
} }
const char* TShader::getInfoLog() const char* TShader::getInfoLog()
......
...@@ -263,11 +263,13 @@ bool InitializeProcess(); ...@@ -263,11 +263,13 @@ bool InitializeProcess();
// Call once per process to tear down everything // Call once per process to tear down everything
void FinalizeProcess(); void FinalizeProcess();
// Make one TShader per shader that you will link into a program. Then // Make one TShader per shader that you will link into a program. Then provide
// provide the shader through setStrings(), then call parse(), then query // the shader through setStrings(), then call parse(), then query the info logs.
// the info logs. // Optionally use setPreamble() to set a special shader string that will be
// processed before all others but won't affect the validity of #version.
// //
// N.B.: Does not yet support having the same TShader instance being linked into multiple programs. // N.B.: Does not yet support having the same TShader instance being linked into
// multiple programs.
// //
// N.B.: Destruct a linked program *before* destructing the shaders linked into it. // N.B.: Destruct a linked program *before* destructing the shaders linked into it.
// //
...@@ -276,6 +278,7 @@ public: ...@@ -276,6 +278,7 @@ public:
explicit TShader(EShLanguage); explicit TShader(EShLanguage);
virtual ~TShader(); virtual ~TShader();
void setStrings(const char* const* s, int n) { strings = s; numStrings = n; } void setStrings(const char* const* s, int n) { strings = s; numStrings = n; }
void setPreamble(const char* s) { preamble = s; }
bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages); bool parse(const TBuiltInResource*, int defaultVersion, bool forwardCompatible, EShMessages);
const char* getInfoLog(); const char* getInfoLog();
...@@ -290,6 +293,7 @@ protected: ...@@ -290,6 +293,7 @@ protected:
TIntermediate* intermediate; TIntermediate* intermediate;
TInfoSink* infoSink; TInfoSink* infoSink;
const char* const* strings; const char* const* strings;
const char* preamble;
int numStrings; int numStrings;
friend class TProgram; friend class TProgram;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment