diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index a14a2dbd..07e52579 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -46,6 +46,17 @@ extern "C" { SH_IMPORT_EXPORT void ShOutputHtml(); } +// Command-line options +enum TOptions { + EOptionNone = 0x000, + EOptionIntermediate = 0x001, + EOptionSuppressInfolog = 0x002, + EOptionMemoryLeakMode = 0x004, + EOptionRelaxedErrors = 0x008, + EOptionGiveWarnings = 0x010, + EOptionsLinkProgram = 0x020, +}; + // // Return codes from main. // @@ -109,7 +120,7 @@ void GenerateResources(TBuiltInResource& resources) } glslang::TWorklist Worklist; -int DebugOptions = 0; +int Options = 0; bool Delay = false; bool ProcessArguments(int argc, char* argv[]) @@ -123,20 +134,20 @@ bool ProcessArguments(int argc, char* argv[]) Delay = true; break; case 'i': - DebugOptions |= EDebugOpIntermediate; + Options |= EOptionIntermediate; break; case 'l': - DebugOptions |= EDebugOpMemoryLeakMode; + Options |= EOptionsLinkProgram; + break; + case 'm': + Options |= EOptionMemoryLeakMode; break; case 'r': - DebugOptions |= EDebugOpRelaxedErrors; + Options |= EOptionRelaxedErrors; break; case 's': - DebugOptions |= EDebugOpSuppressInfolog; + Options |= EOptionSuppressInfolog; break; - case 't': - DebugOptions |= EDebugOpTexturePrototypes; - break; default: return false; } @@ -155,21 +166,21 @@ unsigned int #ifdef _WIN32 __stdcall #endif - CompileShaders(void*) +CompileShaders(void*) { ShHandle compiler; std::string shaderName; while (Worklist.remove(shaderName)) { - compiler = ShConstructCompiler(FindLanguage(shaderName), DebugOptions); + compiler = ShConstructCompiler(FindLanguage(shaderName), Options); if (compiler == 0) return false; TBuiltInResource resources; GenerateResources(resources); - CompileFile(shaderName.c_str(), compiler, DebugOptions, &resources); + CompileFile(shaderName.c_str(), compiler, Options, &resources); - if (! (DebugOptions & EDebugOpSuppressInfolog)) + if (! (Options & EOptionSuppressInfolog)) puts(ShGetInfoLog(compiler)); ShDestruct(compiler); @@ -231,6 +242,7 @@ int C_DECL main(int argc, char* argv[]) // .tese = tessellation evaluation // .geom = geometry // .frag = fragment +// .comp = compute // EShLanguage FindLanguage(const std::string& name) { @@ -261,7 +273,7 @@ EShLanguage FindLanguage(const std::string& name) // // Read a file's data into a string, and compile it using ShCompile // -bool CompileFile(const char *fileName, ShHandle compiler, int debugOptions, const TBuiltInResource *resources) +bool CompileFile(const char *fileName, ShHandle compiler, int Options, const TBuiltInResource *resources) { int ret; char** shaderStrings = ReadFileData(fileName); @@ -280,18 +292,20 @@ bool CompileFile(const char *fileName, ShHandle compiler, int debugOptions, cons return false; EShMessages messages = EShMsgDefault; - if (debugOptions & EDebugOpRelaxedErrors) + if (Options & EOptionRelaxedErrors) messages = (EShMessages)(messages | EShMsgRelaxedErrors); - for (int i = 0; i < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++i) { - for (int j = 0; j < ((debugOptions & EDebugOpMemoryLeakMode) ? 100 : 1); ++j) { - //ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, resources, debugOptions, 100, false, messages); - ret = ShCompile(compiler, shaderStrings, NumShaderStrings, 0, EShOptNone, resources, debugOptions, 100, false, messages); + if (Options & EOptionIntermediate) + messages = (EShMessages)(messages | EShMsgAST); + for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) { + for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) { + //ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, resources, Options, 100, false, messages); + ret = ShCompile(compiler, shaderStrings, NumShaderStrings, 0, EShOptNone, resources, Options, 100, false, messages); //const char* multi[4] = { "# ve", "rsion", " 300 e", "s" }; //const char* multi[7] = { "/", "/", "\\", "\n", "\n", "#", "version 300 es" }; - //ret = ShCompile(compiler, multi, 4, 0, EShOptNone, resources, debugOptions, 100, false, messages); + //ret = ShCompile(compiler, multi, 4, 0, EShOptNone, resources, Options, 100, false, messages); } - if (debugOptions & EDebugOpMemoryLeakMode) + if (Options & EOptionMemoryLeakMode) glslang::OS_DumpMemoryCounters(); } @@ -319,7 +333,8 @@ void usage() "To get other information, use one of the following options:\n" "-i: intermediate tree (glslang AST) is printed out\n" "-d: delay exit\n" - "-l: memory leak mode\n" + "-l: link validation of all input files\n" + "-m: memory leak mode\n" "-s: silent mode\n" "-r: relaxed semantic error-checking mode\n"); } diff --git a/Todo.txt b/Todo.txt index 19ac666b..d7c4cbd8 100644 --- a/Todo.txt +++ b/Todo.txt @@ -1,8 +1,4 @@ -Current functionality level: ESSL 3.0 - -Error checking - - compile-time check for static recursion - - location layout range/overlap semantics +Current functionality level: ESSL 3.0 Performance @@ -27,6 +23,7 @@ Link Validation - type consistency check of uniforms, globals, ins, and outs, both variables and blocks - location/component/binding/index/offset match check - location/component aliasing (except desktop vertex shader inputs) + - location layout range/overlap semantics - geometry shader input array sizes and input layout qualifier declaration - compute shader layout(local_size_*) matching - mixed es/non-es profiles diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index 50ec8e40..627fcbff 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -572,7 +572,7 @@ protected: bool userDefined; // used for user defined function names bool optimize; bool debug; - TPragmaTable *pragmaTable; + TPragmaTable* pragmaTable; }; // @@ -634,6 +634,7 @@ public: visitAggregate(0), visitLoop(0), visitBranch(0), + visitSwitch(0), depth(0), preVisit(true), postVisit(false), diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 174aa55a..4693d8b0 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -198,9 +198,10 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newConstArray = new TConstUnion[objectSize]; for (int i = 0; i < objectSize; i++) { switch (getType().getBasicType()) { + case EbtDouble: case EbtFloat: newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst()); - break; + break; case EbtInt: if (rightUnionArray[i] == 0) { @@ -438,6 +439,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, switch (op) { case EOpNegative: switch (getType().getBasicType()) { + case EbtDouble: case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break; case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break; case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; diff --git a/glslang/MachineIndependent/RemoveTree.cpp b/glslang/MachineIndependent/RemoveTree.cpp index 8b5220d6..ee72a728 100644 --- a/glslang/MachineIndependent/RemoveTree.cpp +++ b/glslang/MachineIndependent/RemoveTree.cpp @@ -88,6 +88,20 @@ void RemoveConstantUnion(TIntermConstantUnion* node, TIntermTraverser*) delete node; } +bool RemoveLoop(bool /*preVisit*/ , TIntermLoop* node, TIntermTraverser*) +{ + delete node; + + return true; +} + +bool RemoveBranch(bool /*preVisit*/ , TIntermBranch* node, TIntermTraverser*) +{ + delete node; + + return true; +} + // // Entry point. // @@ -95,12 +109,14 @@ void RemoveAllTreeNodes(TIntermNode* root) { TIntermTraverser it; - it.visitAggregate = RemoveAggregate; - it.visitBinary = RemoveBinary; - it.visitConstantUnion = RemoveConstantUnion; - it.visitSelection = RemoveSelection; it.visitSymbol = RemoveSymbol; + it.visitConstantUnion = RemoveConstantUnion; + it.visitBinary = RemoveBinary; it.visitUnary = RemoveUnary; + it.visitAggregate = RemoveAggregate; + it.visitSelection = RemoveSelection; + it.visitLoop = RemoveLoop; + it.visitBranch = RemoveBranch; it.visitSwitch = RemoveSwitch; it.preVisit = false; diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 188a24cb..5fb6a7d7 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -413,10 +413,10 @@ int ShCompile( const int* inputLengths, const EShOptimizationLevel optLevel, const TBuiltInResource* resources, - int debugOptions, + int debugOptions, // currently unused int defaultVersion, // use 100 for ES environment, 110 for desktop bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages // warnings/errors + EShMessages messages // warnings/errors/AST; things to print out ) { if (! InitThread()) @@ -513,6 +513,10 @@ int ShCompile( success = false; intermediate.addSymbolLinkageNodes(parseContext.treeRoot, parseContext.linkage, parseContext.language, symbolTable); + // Clean up the symbol table before deallocating the pool memory it used. + // The AST is self-sufficient now, so it can be done before the rest of compilation/linking. + delete symbolTableMemory; + if (success && parseContext.treeRoot) { if (optLevel == EShOptNoGeneration) parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested."); @@ -520,7 +524,7 @@ int ShCompile( success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); if (success) { - if (debugOptions & EDebugOpIntermediate) + if (messages & EShMsgAST) intermediate.outputTree(parseContext.treeRoot); // @@ -534,15 +538,11 @@ int ShCompile( parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; - if (debugOptions & EDebugOpIntermediate) + if (messages & EShMsgAST) intermediate.outputTree(parseContext.treeRoot); } intermediate.remove(parseContext.treeRoot); - - // Clean up the symbol table before deallocating the pool memory it used. - delete symbolTableMemory; - // // Throw away all the temporary memory used by the compilation process. // diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index a6b05734..833b299c 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -120,7 +120,8 @@ typedef enum { enum EShMessages { EShMsgDefault = 0, // default is to give all required errors and extra warnings EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input - EShMsgSuppressWarnings = (1 << 1) // suppress all warnings, except those required by the specification + EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification + EShMsgAST = (1 << 2), // print the AST intermediate representation }; // @@ -177,18 +178,6 @@ SH_IMPORT_EXPORT int ShCompile( EShMessages messages = EShMsgDefault // warnings and errors ); - -// -// Similar to ShCompile, but accepts an opaque handle to an -// intermediate language structure. -// -SH_IMPORT_EXPORT int ShCompileIntermediate( - ShHandle compiler, - ShHandle intermediate, - const EShOptimizationLevel, - int debuggable // boolean - ); - SH_IMPORT_EXPORT int ShLink( const ShHandle, // linker object const ShHandle h[], // compiler objects to link together @@ -228,20 +217,8 @@ SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int co // SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name); -enum TDebugOptions { - EDebugOpNone = 0x000, - EDebugOpIntermediate = 0x001, - EDebugOpAssembly = 0x002, - EDebugOpObjectCode = 0x004, - EDebugOpLinkMaps = 0x008, - EDebugOpSuppressInfolog = 0x010, - EDebugOpMemoryLeakMode = 0x020, - EDebugOpTexturePrototypes = 0x040, - EDebugOpRelaxedErrors = 0x080, - EDebugOpGiveWarnings = 0x100, -}; #ifdef __cplusplus - } + } // end extern "C" #endif #endif // _COMPILER_INTERFACE_INCLUDED_