void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params) { if (!handle || !params) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; switch(pname) { case SH_INFO_LOG_LENGTH: *params = compiler->getInfoSink().info.size() + 1; break; case SH_OBJECT_CODE_LENGTH: *params = compiler->getInfoSink().obj.size() + 1; break; case SH_ACTIVE_UNIFORMS: *params = compiler->getUniforms().size(); break; case SH_ACTIVE_UNIFORM_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_ACTIVE_ATTRIBUTES: *params = compiler->getAttribs().size(); break; case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_VARYINGS: *params = compiler->getVaryings().size(); break; case SH_VARYING_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_MAPPED_NAME_MAX_LENGTH: // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to // handle array and struct dereferences. *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_NAME_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_HASHED_NAME_MAX_LENGTH: if (compiler->getHashFunction() == NULL) { *params = 0; } else { // 64 bits hashing output requires 16 bytes for hex // representation. const char HashedNamePrefix[] = HASHED_NAME_PREFIX; *params = 16 + sizeof(HashedNamePrefix); } break; case SH_HASHED_NAMES_COUNT: *params = compiler->getNameMap().size(); break; default: UNREACHABLE(); } }
// // Return any object code. // const std::string &ShGetObjectCode(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); TInfoSink &infoSink = compiler->getInfoSink(); return infoSink.obj.str(); }
// // Return any compiler log of messages for the application. // const std::string &GetInfoLog(const ShHandle handle) { TCompiler *compiler = GetCompilerFromHandle(handle); ASSERT(compiler); TInfoSink &infoSink = compiler->getInfoSink(); return infoSink.info.str(); }
// // Return any object code. // void ShGetObjectCode(const ShHandle handle, char* objCode) { if (!handle || !objCode) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; TInfoSink& infoSink = compiler->getInfoSink(); strcpy(objCode, infoSink.obj.c_str()); }
// // Return any compiler log of messages for the application. // void ShGetInfoLog(const ShHandle handle, char* infoLog) { if (!handle || !infoLog) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; TInfoSink& infoSink = compiler->getInfoSink(); strcpy(infoLog, infoSink.info.c_str()); }
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params) { if (!handle || !params) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; switch(pname) { case SH_INFO_LOG_LENGTH: *params = compiler->getInfoSink().info.size() + 1; break; case SH_OBJECT_CODE_LENGTH: *params = compiler->getInfoSink().obj.size() + 1; break; case SH_ACTIVE_UNIFORMS: *params = compiler->getUniforms().size(); break; case SH_ACTIVE_UNIFORM_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_ACTIVE_ATTRIBUTES: *params = compiler->getAttribs().size(); break; case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_MAPPED_NAME_MAX_LENGTH: // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to // handle array and struct dereferences. *params = 1 + MAX_SYMBOL_NAME_LEN; break; default: UNREACHABLE(); } }
// // Driver calls these to create and destroy compiler objects. // ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources) { if (!InitThread()) return 0; 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); }
// // Do an actual compile on the given strings. The result is left // in the given compile object. // // Return: The return value of ShCompile is really boolean, indicating // success or failure. // int ShCompile( const ShHandle handle, const char* const shaderStrings[], const int numStrings, const EShOptimizationLevel optLevel, int debugOptions ) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; GlobalPoolAllocator.push(); TInfoSink& infoSink = compiler->getInfoSink(); infoSink.info.erase(); infoSink.debug.erase(); infoSink.obj.erase(); if (numStrings == 0) return 1; TIntermediate intermediate(infoSink); TSymbolTable& symbolTable = compiler->getSymbolTable(); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink); parseContext.initializeExtensionBehavior(); GlobalParseContext = &parseContext; setInitialState(); InitPreprocessor(); // // Parse the application's shaders. All the following symbol table // work will be throw-away, so push a new allocation scope that can // be thrown away, then push a scope for the current shader's globals. // bool success = true; symbolTable.push(); if (!symbolTable.atGlobalLevel()) parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext); if (ret) success = false; if (success && parseContext.treeRoot) { if (optLevel == EShOptNoGeneration) parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation was requested."); else { success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); if (success) { if (debugOptions & EDebugOpIntermediate) intermediate.outputTree(parseContext.treeRoot); // // Call the machine dependent compiler // if (!compiler->compile(parseContext.treeRoot)) success = false; } } } else if (!success) { parseContext.infoSink.info.prefix(EPrefixError); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; if (debugOptions & EDebugOpIntermediate) intermediate.outputTree(parseContext.treeRoot); } else if (!parseContext.treeRoot) { parseContext.error(1, "Unexpected end of file.", "", ""); parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; success = false; if (debugOptions & EDebugOpIntermediate) intermediate.outputTree(parseContext.treeRoot); } intermediate.remove(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (!symbolTable.atBuiltInLevel()) symbolTable.pop(); FinalizePreprocessor(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }