Commit e4249f02 by alokp@chromium.org

Refactored the way symbol tables are initialized and stored. This was done in…

Refactored the way symbol tables are initialized and stored. This was done in response to the addition of EShSpec. Symbol table entries depend on three things - language, spec (not now but may eventually), and built-in resources. We used to build two global symbol-tables - one for each language. During each compile, one of the symbol table was copied and resource-specific stuff was added. I have moved the symbol table to TCompiler that gets initilized when compiler is created and reused for each compile. This makes it much cleaner and extensible in case a spec requires special entries to be added to the symbol table. PS: Sorry for the long CL, but all of it needed to be done in one CL. I have verified that everything still compiles and passes all conformance tests. Review URL: http://codereview.appspot.com/1864044 git-svn-id: https://angleproject.googlecode.com/svn/trunk@351 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 6db8cab4
...@@ -70,7 +70,7 @@ typedef void* ShHandle; ...@@ -70,7 +70,7 @@ typedef void* ShHandle;
// //
// Driver calls these to create and destroy compiler objects. // Driver calls these to create and destroy compiler objects.
// //
ShHandle ShConstructCompiler(EShLanguage, EShSpec); // one per shader ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
void ShDestruct(ShHandle); void ShDestruct(ShHandle);
// //
...@@ -85,7 +85,6 @@ int ShCompile( ...@@ -85,7 +85,6 @@ int ShCompile(
const char* const shaderStrings[], const char* const shaderStrings[],
const int numStrings, const int numStrings,
const EShOptimizationLevel, const EShOptimizationLevel,
const TBuiltInResource *resources,
int debugOptions int debugOptions
); );
......
...@@ -22,12 +22,12 @@ enum TFailCode { ...@@ -22,12 +22,12 @@ enum TFailCode {
}; };
static EShLanguage FindLanguage(char *lang); static EShLanguage FindLanguage(char *lang);
bool CompileFile(char *fileName, ShHandle, int, const TBuiltInResource*); bool CompileFile(char *fileName, ShHandle, int);
void usage(); void usage();
void FreeFileData(char **data); void FreeFileData(char **data);
char** ReadFileData(char *fileName); char** ReadFileData(char *fileName);
void LogMsg(char* msg, const char* name, const int num, const char* logName); void LogMsg(char* msg, const char* name, const int num, const char* logName);
int ShOutputMultipleStrings(char ** );
//Added to accomodate the multiple strings. //Added to accomodate the multiple strings.
int OutputMultipleStrings = 1; int OutputMultipleStrings = 1;
...@@ -48,61 +48,77 @@ void GenerateResources(TBuiltInResource& resources) ...@@ -48,61 +48,77 @@ void GenerateResources(TBuiltInResource& resources)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int numCompilers = 0; TFailCode failCode = ESuccess;
bool compileFailed = false;
int debugOptions = 0; int debugOptions = 0;
bool writeObjectCode = false; bool writeObjectCode = false;
int i;
ShHandle compilers[EShLangCount]; int numCompiles = 0;
ShHandle vertexCompiler = 0;
ShHandle fragmentCompiler = 0;
ShInitialize(); ShInitialize();
TBuiltInResource resources;
GenerateResources(resources);
argc--; argc--;
argv++; argv++;
for (; argc >= 1; argc--, argv++) { for (; (argc >= 1) && (failCode == ESuccess); argc--, argv++) {
if (argv[0][0] == '-' || argv[0][0] == '/') { if (argv[0][0] == '-' || argv[0][0] == '/') {
switch (argv[0][1]) { switch (argv[0][1]) {
case 'i': debugOptions |= EDebugOpIntermediate; break; case 'i': debugOptions |= EDebugOpIntermediate; break;
case 'o': writeObjectCode = true; break; case 'o': writeObjectCode = true; break;
default: usage(); return EFailUsage; default: failCode = EFailUsage;
} }
} else { } else {
compilers[numCompilers] = ShConstructCompiler(FindLanguage(argv[0]), EShSpecGLES2); ShHandle compiler = 0;
if (compilers[numCompilers] == 0) switch (FindLanguage(argv[0])) {
return EFailCompilerCreate; case EShLangVertex:
++numCompilers; if (vertexCompiler == 0)
vertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
TBuiltInResource resources; compiler = vertexCompiler;
GenerateResources(resources); break;
if (!CompileFile(argv[0], compilers[numCompilers-1], debugOptions, &resources)) case EShLangFragment:
compileFailed = true; if (fragmentCompiler == 0)
} fragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
compiler = fragmentCompiler;
break;
default: break;
} }
if (compiler) {
bool compiled = CompileFile(argv[0], compiler, debugOptions);
if (!numCompilers) { LogMsg("BEGIN", "COMPILER", numCompiles, "INFO LOG");
usage(); puts(ShGetInfoLog(compiler));
return EFailUsage; LogMsg("END", "COMPILER", numCompiles, "INFO LOG");
}
for (i = 0; i < numCompilers; ++i) { if (compiled && writeObjectCode) {
LogMsg("BEGIN", "COMPILER", i, "INFO LOG"); LogMsg("BEGIN", "COMPILER", numCompiles, "OBJ CODE");
puts(ShGetInfoLog(compilers[i])); puts(ShGetObjectCode(compiler));
LogMsg("END", "COMPILER", i, "INFO LOG"); LogMsg("END", "COMPILER", numCompiles, "OBJ CODE");
}
if (!compiled)
failCode = EFailCompile;
++numCompiles;
} else {
failCode = EFailCompilerCreate;
} }
if (writeObjectCode) {
for (i = 0; i < numCompilers; ++i) {
LogMsg("BEGIN", "COMPILER", i, "OBJ CODE");
puts(ShGetObjectCode(compilers[i]));
LogMsg("END", "COMPILER", i, "OBJ CODE");
} }
} }
for (i = 0; i < numCompilers; ++i) if ((vertexCompiler == 0) && (fragmentCompiler == 0))
ShDestruct(compilers[i]); failCode = EFailUsage;
if (failCode == EFailUsage)
usage();
if (vertexCompiler)
ShDestruct(vertexCompiler);
if (fragmentCompiler)
ShDestruct(fragmentCompiler);
ShFinalize(); ShFinalize();
return compileFailed ? EFailCompile : ESuccess;
return failCode;
} }
// //
...@@ -133,7 +149,7 @@ static EShLanguage FindLanguage(char *name) ...@@ -133,7 +149,7 @@ static EShLanguage FindLanguage(char *name)
// //
// Read a file's data into a string, and compile it using ShCompile // Read a file's data into a string, and compile it using ShCompile
// //
bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBuiltInResource *resources) bool CompileFile(char *fileName, ShHandle compiler, int debugOptions)
{ {
int ret; int ret;
char **data = ReadFileData(fileName); char **data = ReadFileData(fileName);
...@@ -141,7 +157,7 @@ bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBui ...@@ -141,7 +157,7 @@ bool CompileFile(char *fileName, ShHandle compiler, int debugOptions, const TBui
if (!data) if (!data)
return false; return false;
ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, resources, debugOptions); ret = ShCompile(compiler, data, OutputMultipleStrings, EShOptNone, debugOptions);
FreeFileData(data); FreeFileData(data);
...@@ -229,13 +245,3 @@ void LogMsg(char* msg, const char* name, const int num, const char* logName) ...@@ -229,13 +245,3 @@ void LogMsg(char* msg, const char* name, const int num, const char* logName)
"#### %s %s INFO LOG ####\n", msg, name, num, logName); "#### %s %s INFO LOG ####\n", msg, name, num, logName);
} }
int ShOutputMultipleStrings(char** argv)
{
if(!(abs(OutputMultipleStrings = atoi(*argv)))||((OutputMultipleStrings >5 || OutputMultipleStrings < 1)? 1:0)){
printf("Invalid Command Line Argument after -c option.\n"
"Usage: -c <integer> where integer =[1,5]\n"
"This option must be specified before the input file path\n");
return 0;
}
return 1;
}
...@@ -14,26 +14,14 @@ ...@@ -14,26 +14,14 @@
#include "compiler/intermediate.h" #include "compiler/intermediate.h"
void TBuiltIns::initialize() //============================================================================
//
// Prototypes for built-in functions seen by both vertex and fragment shaders.
//
//============================================================================
static TString BuiltInFunctionsCommon()
{ {
// TString s;
// Initialize all the built-in strings for parsing.
//
TString BuiltInFunctions;
TString BuiltInFunctionsVertex;
TString BuiltInFunctionsFragment;
TString StandardUniforms;
TString VertexDefaultPrecision;
TString FragmentDefaultPrecision;
{
//============================================================================
//
// Prototypes for built-in functions seen by both vertex and fragment shaders.
//
//============================================================================
TString& s = BuiltInFunctions;
// //
// Angle and Trigonometric Functions. // Angle and Trigonometric Functions.
...@@ -334,41 +322,43 @@ void TBuiltIns::initialize() ...@@ -334,41 +322,43 @@ void TBuiltIns::initialize()
// //
// Noise functions. // Noise functions.
// //
// s.append(TString("float noise1(float x);")); //s.append(TString("float noise1(float x);"));
// s.append(TString("float noise1(vec2 x);")); //s.append(TString("float noise1(vec2 x);"));
// s.append(TString("float noise1(vec3 x);")); //s.append(TString("float noise1(vec3 x);"));
// s.append(TString("float noise1(vec4 x);")); //s.append(TString("float noise1(vec4 x);"));
// s.append(TString("vec2 noise2(float x);")); //s.append(TString("vec2 noise2(float x);"));
// s.append(TString("vec2 noise2(vec2 x);")); //s.append(TString("vec2 noise2(vec2 x);"));
// s.append(TString("vec2 noise2(vec3 x);")); //s.append(TString("vec2 noise2(vec3 x);"));
// s.append(TString("vec2 noise2(vec4 x);")); //s.append(TString("vec2 noise2(vec4 x);"));
// s.append(TString("vec3 noise3(float x);")); //s.append(TString("vec3 noise3(float x);"));
// s.append(TString("vec3 noise3(vec2 x);")); //s.append(TString("vec3 noise3(vec2 x);"));
// s.append(TString("vec3 noise3(vec3 x);")); //s.append(TString("vec3 noise3(vec3 x);"));
// s.append(TString("vec3 noise3(vec4 x);")); //s.append(TString("vec3 noise3(vec4 x);"));
// s.append(TString("vec4 noise4(float x);")); //s.append(TString("vec4 noise4(float x);"));
// s.append(TString("vec4 noise4(vec2 x);")); //s.append(TString("vec4 noise4(vec2 x);"));
// s.append(TString("vec4 noise4(vec3 x);")); //s.append(TString("vec4 noise4(vec3 x);"));
// s.append(TString("vec4 noise4(vec4 x);")); //s.append(TString("vec4 noise4(vec4 x);"));
s.append(TString("\n")); s.append(TString("\n"));
} return s;
{ }
//============================================================================
//
// Prototypes for built-in functions seen by vertex shaders only.
//
//============================================================================
TString& s = BuiltInFunctionsVertex; //============================================================================
//
// Prototypes for built-in functions seen by vertex shaders only.
//
//============================================================================
static TString BuiltInFunctionsVertex()
{
TString s;
// //
// Geometric Functions. // Geometric Functions.
// //
s.append(TString("vec4 ftransform();")); //s.append(TString("vec4 ftransform();"));
// //
// Texture Functions. // Texture Functions.
...@@ -376,19 +366,20 @@ void TBuiltIns::initialize() ...@@ -376,19 +366,20 @@ void TBuiltIns::initialize()
s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);")); s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);")); s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);")); s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);")); s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
s.append(TString("\n")); s.append(TString("\n"));
} return s;
{ }
//============================================================================
//
// Prototypes for built-in functions seen by fragment shaders only.
//
//============================================================================
TString& s = BuiltInFunctionsFragment; //============================================================================
//
// Prototypes for built-in functions seen by fragment shaders only.
//
//============================================================================
static TString BuiltInFunctionsFragment()
{
TString s;
// //
// Texture Functions. // Texture Functions.
...@@ -396,18 +387,17 @@ void TBuiltIns::initialize() ...@@ -396,18 +387,17 @@ void TBuiltIns::initialize()
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);")); s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);")); s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);")); s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);")); s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
// s.append(TString("float dFdx(float p);")); //s.append(TString("float dFdx(float p);"));
// s.append(TString("vec2 dFdx(vec2 p);")); //s.append(TString("vec2 dFdx(vec2 p);"));
// s.append(TString("vec3 dFdx(vec3 p);")); //s.append(TString("vec3 dFdx(vec3 p);"));
// s.append(TString("vec4 dFdx(vec4 p);")); //s.append(TString("vec4 dFdx(vec4 p);"));
// s.append(TString("float dFdy(float p);")); //s.append(TString("float dFdy(float p);"));
// s.append(TString("vec2 dFdy(vec2 p);")); //s.append(TString("vec2 dFdy(vec2 p);"));
// s.append(TString("vec3 dFdy(vec3 p);")); //s.append(TString("vec3 dFdy(vec3 p);"));
// s.append(TString("vec4 dFdy(vec4 p);")); //s.append(TString("vec4 dFdy(vec4 p);"));
s.append(TString("float fwidth(float p);")); s.append(TString("float fwidth(float p);"));
s.append(TString("vec2 fwidth(vec2 p);")); s.append(TString("vec2 fwidth(vec2 p);"));
...@@ -415,15 +405,17 @@ void TBuiltIns::initialize() ...@@ -415,15 +405,17 @@ void TBuiltIns::initialize()
s.append(TString("vec4 fwidth(vec4 p);")); s.append(TString("vec4 fwidth(vec4 p);"));
s.append(TString("\n")); s.append(TString("\n"));
} return s;
{ }
//============================================================================
//
// Standard Uniforms
//
//============================================================================
TString& s = StandardUniforms; //============================================================================
//
// Standard uniforms.
//
//============================================================================
static TString StandardUniforms()
{
TString s;
// //
// Depth range in window coordinates // Depth range in window coordinates
...@@ -436,87 +428,107 @@ void TBuiltIns::initialize() ...@@ -436,87 +428,107 @@ void TBuiltIns::initialize()
s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;")); s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
s.append(TString("\n")); s.append(TString("\n"));
} return s;
{ }
//============================================================================
//
// Default precision for vertex shaders.
//
//============================================================================
TString& s = VertexDefaultPrecision; //============================================================================
//
// Default precision for vertex shaders.
//
//============================================================================
static TString DefaultPrecisionVertex()
{
TString s;
s.append(TString("precision highp int;")); s.append(TString("precision highp int;"));
s.append(TString("precision highp float;")); s.append(TString("precision highp float;"));
s.append(TString("\n")); s.append(TString("\n"));
} return s;
{ }
//============================================================================
//
// Default precision for fragment shaders.
//
//============================================================================
TString& s = FragmentDefaultPrecision; //============================================================================
//
// Default precision for fragment shaders.
//
//============================================================================
static TString DefaultPrecisionFragment()
{
TString s;
s.append(TString("precision mediump int;")); s.append(TString("precision mediump int;"));
// No default precision for float in fragment shaders // No default precision for float in fragment shaders
s.append(TString("\n")); s.append(TString("\n"));
} return s;
}
builtInStrings[EShLangFragment].push_back(FragmentDefaultPrecision); //============================================================================
builtInStrings[EShLangFragment].push_back(BuiltInFunctions.c_str()); //
builtInStrings[EShLangFragment].push_back(BuiltInFunctionsFragment); // Implementation dependent built-in constants.
builtInStrings[EShLangFragment].push_back(StandardUniforms); //
//============================================================================
static TString BuiltInConstants(const TBuiltInResource &resources)
{
TStringStream s;
s << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
s << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
s << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
s << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
s << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
s << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
s << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
s << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
builtInStrings[EShLangVertex].push_back(VertexDefaultPrecision); return s.str();
builtInStrings[EShLangVertex].push_back(BuiltInFunctions);
builtInStrings[EShLangVertex].push_back(BuiltInFunctionsVertex);
builtInStrings[EShLangVertex].push_back(StandardUniforms);
} }
void TBuiltIns::initialize(const TBuiltInResource &resources) void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources)
{ {
TStringStream builtIns; switch (language) {
case EShLangFragment:
builtInStrings.push_back(DefaultPrecisionFragment());
builtInStrings.push_back(BuiltInFunctionsCommon());
builtInStrings.push_back(BuiltInFunctionsFragment());
builtInStrings.push_back(StandardUniforms());
break;
// Implementation dependent constants case EShLangVertex:
builtIns << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";"; builtInStrings.push_back(DefaultPrecisionVertex());
builtIns << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";"; builtInStrings.push_back(BuiltInFunctionsCommon());
builtInStrings.push_back(BuiltInFunctionsVertex());
builtInStrings.push_back(StandardUniforms());
break;
builtIns << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";"; default: assert(false && "Language not supported");
builtIns << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";"; }
builtIns << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
builtIns << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
builtIns << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
builtIns << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
builtInStrings[EShLangFragment].push_back(builtIns.str()); builtInStrings.push_back(BuiltInConstants(resources));
builtInStrings[EShLangVertex].push_back(builtIns.str());
} }
void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable) void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TSymbolTable& symbolTable)
{ {
// //
// First, insert some special built-in variables that are not in // First, insert some special built-in variables that are not in
// the built-in header files. // the built-in header files.
// //
switch(language) { switch(language) {
case EShLangFragment:
case EShLangFragment: {
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
}
break; break;
case EShLangVertex: case EShLangVertex:
symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4))); symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1))); symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
break; break;
default: break;
default: assert(false && "Language not supported");
} }
// //
...@@ -578,27 +590,20 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable) ...@@ -578,27 +590,20 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
symbolTable.relateToOperator("any", EOpAny); symbolTable.relateToOperator("any", EOpAny);
symbolTable.relateToOperator("all", EOpAll); symbolTable.relateToOperator("all", EOpAll);
switch(language) // Map language-specific operators.
{ switch(language) {
case EShLangVertex: case EShLangVertex:
break; break;
case EShLangFragment: case EShLangFragment:
// symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
// symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
// symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
break; break;
default: assert(false && "Language not supported"); default: break;
} }
}
void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) // Finally add resource-specific variables.
{
//
// First, insert some special built-in variables that are not in
// the built-in header files.
//
switch(language) { switch(language) {
case EShLangFragment: { case EShLangFragment: {
// Set up gl_FragData. The array size. // Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true); TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
...@@ -606,14 +611,7 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBu ...@@ -606,14 +611,7 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBu
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
} }
break; break;
default: break; default: break;
} }
} }
const char* GetPreprocessorBuiltinString()
{
static const char *PreprocessorBuiltinString = "";
return PreprocessorBuiltinString;
}
...@@ -18,18 +18,17 @@ typedef TVector<TString> TBuiltInStrings; ...@@ -18,18 +18,17 @@ typedef TVector<TString> TBuiltInStrings;
class TBuiltIns { class TBuiltIns {
public: public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
void initialize();
void initialize(const TBuiltInResource& resources); void initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources);
TBuiltInStrings* getBuiltInStrings() { return builtInStrings; } const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
protected: protected:
TBuiltInStrings builtInStrings[EShLangCount]; TBuiltInStrings builtInStrings;
}; };
void IdentifyBuiltIns(EShLanguage, TSymbolTable&); void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
void IdentifyBuiltIns(EShLanguage, TSymbolTable&, const TBuiltInResource &resources); TSymbolTable& symbolTable);
bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink&, TSymbolTable*, EShLanguage language = EShLangCount);
bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource *resources, TSymbolTable*);
const char* GetPreprocessorBuiltinString();
extern "C" int InitPreprocessor(void); extern "C" int InitPreprocessor(void);
extern "C" int FinalizePreprocessor(void); extern "C" int FinalizePreprocessor(void);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "GLSLANG/ShaderLang.h" #include "GLSLANG/ShaderLang.h"
#include "compiler/InfoSink.h" #include "compiler/InfoSink.h"
#include "compiler/SymbolTable.h"
class TCompiler; class TCompiler;
class TIntermNode; class TIntermNode;
...@@ -40,18 +41,24 @@ public: ...@@ -40,18 +41,24 @@ public:
TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { } TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { }
virtual ~TCompiler() { } virtual ~TCompiler() { }
EShLanguage getLanguage() { return language; } EShLanguage getLanguage() const { return language; }
EShSpec getSpec() { return spec; } EShSpec getSpec() const { return spec; }
virtual TInfoSink& getInfoSink() { return infoSink; } TSymbolTable& getSymbolTable() { return symbolTable; }
TInfoSink& getInfoSink() { return infoSink; }
virtual bool compile(TIntermNode* root) = 0; virtual bool compile(TIntermNode* root) = 0;
virtual TCompiler* getAsCompiler() { return this; } virtual TCompiler* getAsCompiler() { return this; }
TInfoSink infoSink;
protected: protected:
EShLanguage language; EShLanguage language;
EShSpec spec; EShSpec spec;
// Built-in symbol table for the given language, spec, and resources.
// It is preserved from compile-to-compile.
TSymbolTable symbolTable;
// Output sink.
TInfoSink infoSink;
}; };
// //
......
...@@ -17,15 +17,68 @@ ...@@ -17,15 +17,68 @@
#include "compiler/ShHandle.h" #include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h" #include "compiler/SymbolTable.h"
// static bool InitializeSymbolTable(
// A symbol table for each language. Each has a different const TBuiltInStrings& builtInStrings,
// set of built-ins, and we want to preserve that from EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
// compile to compile. TInfoSink& infoSink, TSymbolTable& symbolTable)
// {
TSymbolTable* SymbolTables[EShLangCount]; TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink);
GlobalParseContext = &parseContext;
setInitialState();
assert(symbolTable.isEmpty());
//
// Parse the built-ins. This should only happen once per
// language symbol table.
//
// Push the symbol table to give it an initial scope. This
// push should not have a corresponding pop, so that built-ins
// are preserved, and the test for an empty table fails.
//
symbolTable.push();
//Initialize the Preprocessor
if (InitPreprocessor())
{
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
return false;
}
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
{
const char* builtInShaders[1];
int builtInLengths[1];
builtInShaders[0] = (*i).c_str();
builtInLengths[0] = (int) (*i).size();
if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0)
{
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
return false;
}
}
IdentifyBuiltIns(language, spec, resources, symbolTable);
FinalizePreprocessor();
return true;
}
static bool GenerateBuiltInSymbolTable(
EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
TInfoSink& infoSink, TSymbolTable& symbolTable)
{
TBuiltIns builtIns;
builtIns.initialize(language, spec, resources);
return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable);
}
TPoolAllocator* PerProcessGPA = 0;
// //
// This is the platform independent interface between an OGL driver // This is the platform independent interface between an OGL driver
// and the shading language compiler. // and the shading language compiler.
...@@ -37,42 +90,7 @@ TPoolAllocator* PerProcessGPA = 0; ...@@ -37,42 +90,7 @@ TPoolAllocator* PerProcessGPA = 0;
// //
int ShInitialize() int ShInitialize()
{ {
TInfoSink infoSink; bool ret = InitProcess();
bool ret = true;
if (!InitProcess())
return 0;
// This method should be called once per process. If its called by multiple threads, then
// we need to have thread synchronization code around the initialization of per process
// global pool allocator
if (!PerProcessGPA) {
TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
builtInPoolAllocator->push();
TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
SetGlobalPoolAllocatorPtr(builtInPoolAllocator);
TSymbolTable symTables[EShLangCount];
GenerateBuiltInSymbolTable(0, infoSink, symTables);
PerProcessGPA = new TPoolAllocator(true);
PerProcessGPA->push();
SetGlobalPoolAllocatorPtr(PerProcessGPA);
SymbolTables[EShLangVertex] = new TSymbolTable;
SymbolTables[EShLangVertex]->copyTable(symTables[EShLangVertex]);
SymbolTables[EShLangFragment] = new TSymbolTable;
SymbolTables[EShLangFragment]->copyTable(symTables[EShLangFragment]);
SetGlobalPoolAllocatorPtr(gPoolAllocator);
symTables[EShLangVertex].pop();
symTables[EShLangFragment].pop();
builtInPoolAllocator->popAll();
delete builtInPoolAllocator;
}
return ret ? 1 : 0; return ret ? 1 : 0;
} }
...@@ -81,12 +99,21 @@ int ShInitialize() ...@@ -81,12 +99,21 @@ int ShInitialize()
// Driver calls these to create and destroy compiler objects. // Driver calls these to create and destroy compiler objects.
// //
ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec) ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
{ {
if (!InitThread()) if (!InitThread())
return 0; return 0;
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec)); TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return 0;
// Generate built-in symbol table.
if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) {
ShDestruct(base);
return 0;
}
return reinterpret_cast<void*>(base); return reinterpret_cast<void*>(base);
} }
...@@ -107,98 +134,9 @@ void ShDestruct(ShHandle handle) ...@@ -107,98 +134,9 @@ void ShDestruct(ShHandle handle)
// //
int ShFinalize() int ShFinalize()
{ {
if (PerProcessGPA) {
PerProcessGPA->popAll();
delete PerProcessGPA;
PerProcessGPA = 0;
}
for (int i = 0; i < EShLangCount; ++i) {
delete SymbolTables[i];
SymbolTables[i] = 0;
}
return 1; return 1;
} }
bool GenerateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable* symbolTables, EShLanguage language)
{
TBuiltIns builtIns;
if (resources) {
builtIns.initialize(*resources);
InitializeSymbolTable(builtIns.getBuiltInStrings(), language, infoSink, resources, symbolTables);
} else {
builtIns.initialize();
InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangVertex, infoSink, resources, symbolTables);
InitializeSymbolTable(builtIns.getBuiltInStrings(), EShLangFragment, infoSink, resources, symbolTables);
}
return true;
}
bool InitializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource* resources, TSymbolTable* symbolTables)
{
TIntermediate intermediate(infoSink);
TSymbolTable* symbolTable;
if (resources)
symbolTable = symbolTables;
else
symbolTable = &symbolTables[language];
// TODO(alokp): Investigate if a parse-context is necessary here and
// if symbol-table can be shared between GLES2 and WebGL specs.
TParseContext parseContext(*symbolTable, intermediate, language, EShSpecGLES2, infoSink);
GlobalParseContext = &parseContext;
setInitialState();
assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
//
// Parse the built-ins. This should only happen once per
// language symbol table.
//
// Push the symbol table to give it an initial scope. This
// push should not have a corresponding pop, so that built-ins
// are preserved, and the test for an empty table fails.
//
symbolTable->push();
//Initialize the Preprocessor
int ret = InitPreprocessor();
if (ret) {
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
return false;
}
for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
i != BuiltInStrings[parseContext.language].end();
++i) {
const char* builtInShaders[1];
int builtInLengths[1];
builtInShaders[0] = (*i).c_str();
builtInLengths[0] = (int) (*i).size();
if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) {
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
return false;
}
}
if (resources) {
IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
} else {
IdentifyBuiltIns(parseContext.language, *symbolTable);
}
FinalizePreprocessor();
return true;
}
// //
// Do an actual compile on the given strings. The result is left // Do an actual compile on the given strings. The result is left
// in the given compile object. // in the given compile object.
...@@ -211,7 +149,6 @@ int ShCompile( ...@@ -211,7 +149,6 @@ int ShCompile(
const char* const shaderStrings[], const char* const shaderStrings[],
const int numStrings, const int numStrings,
const EShOptimizationLevel optLevel, const EShOptimizationLevel optLevel,
const TBuiltInResource* resources,
int debugOptions int debugOptions
) )
{ {
...@@ -227,7 +164,7 @@ int ShCompile( ...@@ -227,7 +164,7 @@ int ShCompile(
return 0; return 0;
GlobalPoolAllocator.push(); GlobalPoolAllocator.push();
TInfoSink& infoSink = compiler->infoSink; TInfoSink& infoSink = compiler->getInfoSink();
infoSink.info.erase(); infoSink.info.erase();
infoSink.debug.erase(); infoSink.debug.erase();
infoSink.obj.erase(); infoSink.obj.erase();
...@@ -236,13 +173,10 @@ int ShCompile( ...@@ -236,13 +173,10 @@ int ShCompile(
return 1; return 1;
TIntermediate intermediate(infoSink); TIntermediate intermediate(infoSink);
TSymbolTable symbolTable(*SymbolTables[compiler->getLanguage()]); TSymbolTable& symbolTable = compiler->getSymbolTable();
GenerateBuiltInSymbolTable(resources, infoSink, &symbolTable, compiler->getLanguage());
TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink);
parseContext.initializeExtensionBehavior(); parseContext.initializeExtensionBehavior();
GlobalParseContext = &parseContext; GlobalParseContext = &parseContext;
setInitialState(); setInitialState();
...@@ -301,7 +235,7 @@ int ShCompile( ...@@ -301,7 +235,7 @@ int ShCompile(
// Ensure symbol table is returned to the built-in level, // Ensure symbol table is returned to the built-in level,
// throwing away all but the built-ins. // throwing away all but the built-ins.
// //
while (! symbolTable.atSharedBuiltInLevel()) while (!symbolTable.atBuiltInLevel())
symbolTable.pop(); symbolTable.pop();
FinalizePreprocessor(); FinalizePreprocessor();
......
...@@ -31,9 +31,9 @@ ...@@ -31,9 +31,9 @@
// //
#include <assert.h> #include <assert.h>
#include "compiler/Common.h"
#include "compiler/intermediate.h"
#include "compiler/InfoSink.h" #include "compiler/InfoSink.h"
#include "compiler/intermediate.h"
// //
// Symbol base class. (Can build functions or variables out of these...) // Symbol base class. (Can build functions or variables out of these...)
...@@ -239,13 +239,6 @@ public: ...@@ -239,13 +239,6 @@ public:
// //
} }
TSymbolTable(TSymbolTable& symTable)
{
table.push_back(symTable.table[0]);
precisionStack.push_back( symTable.precisionStack[0] );
uniqueId = symTable.uniqueId;
}
~TSymbolTable() ~TSymbolTable()
{ {
// level 0 is always built In symbols, so we never pop that out // level 0 is always built In symbols, so we never pop that out
...@@ -259,9 +252,8 @@ public: ...@@ -259,9 +252,8 @@ public:
// globals are at level 1. // globals are at level 1.
// //
bool isEmpty() { return table.size() == 0; } bool isEmpty() { return table.size() == 0; }
bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); } bool atBuiltInLevel() { return table.size() == 1; }
bool atSharedBuiltInLevel() { return table.size() == 1; } bool atGlobalLevel() { return table.size() <= 2; }
bool atGlobalLevel() { return table.size() <= 3; }
void push() void push()
{ {
table.push_back(new TSymbolTableLevel); table.push_back(new TSymbolTableLevel);
...@@ -297,7 +289,7 @@ public: ...@@ -297,7 +289,7 @@ public:
return symbol; return symbol;
} }
TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 3); return table[2]; } TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); } void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
int getMaxSymbolId() { return uniqueId; } int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const; void dump(TInfoSink &infoSink) const;
...@@ -329,7 +321,6 @@ public: ...@@ -329,7 +321,6 @@ public:
protected: protected:
int currentLevel() const { return static_cast<int>(table.size()) - 1; } int currentLevel() const { return static_cast<int>(table.size()) - 1; }
bool atDynamicBuiltInLevel() { return table.size() == 2; }
std::vector<TSymbolTableLevel*> table; std::vector<TSymbolTableLevel*> table;
typedef std::map< TBasicType, TPrecision > PrecisionStackLevel; typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
......
...@@ -34,8 +34,18 @@ Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(cont ...@@ -34,8 +34,18 @@ Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(cont
if (result) if (result)
{ {
mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2); TBuiltInResource resources;
mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2); resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
resources.maxVaryingVectors = MAX_VARYING_VECTORS;
resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
} }
} }
...@@ -267,18 +277,7 @@ void Shader::compileToHLSL(void *compiler) ...@@ -267,18 +277,7 @@ void Shader::compileToHLSL(void *compiler)
delete[] mInfoLog; delete[] mInfoLog;
mInfoLog = NULL; mInfoLog = NULL;
TBuiltInResource resources; int result = ShCompile(compiler, &mSource, 1, EShOptNone, EDebugOpNone);
resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
resources.maxVaryingVectors = MAX_VARYING_VECTORS;
resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
int result = ShCompile(compiler, &mSource, 1, EShOptNone, &resources, EDebugOpNone);
const char *obj = ShGetObjectCode(compiler); const char *obj = ShGetObjectCode(compiler);
const char *info = ShGetInfoLog(compiler); const char *info = ShGetInfoLog(compiler);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment