void ShGetVariableInfo(const ShHandle handle, ShShaderInfo varType, int index, size_t* length, int* size, ShDataType* type, ShPrecisionType* precision, int* staticUse, char* name, char* mappedName) { if (!handle || !size || !type || !precision || !staticUse || !name) return; ASSERT((varType == SH_ACTIVE_ATTRIBUTES) || (varType == SH_ACTIVE_UNIFORMS) || (varType == SH_VARYINGS)); TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return; const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() : (varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() : compiler->getVaryings()); if (index < 0 || index >= static_cast<int>(varList.size())) return; const TVariableInfo& varInfo = varList[index]; if (length) *length = varInfo.name.size(); *size = varInfo.size; *type = varInfo.type; switch (varInfo.precision) { case EbpLow: *precision = SH_PRECISION_LOWP; break; case EbpMedium: *precision = SH_PRECISION_MEDIUMP; break; case EbpHigh: *precision = SH_PRECISION_HIGHP; break; default: // Some types does not support precision, for example, boolean. *precision = SH_PRECISION_UNDEFINED; break; } *staticUse = varInfo.staticUse ? 1 : 0; // This size must match that queried by // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH // in ShGetInfo, below. size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN; ASSERT(checkVariableMaxLengths(handle, variableLength)); strncpy(name, varInfo.name.c_str(), variableLength); name[variableLength - 1] = 0; if (mappedName) { // This size must match that queried by // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN; ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength)); strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength); mappedName[maxMappedNameLength - 1] = 0; } }
// // 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, const TBuiltInResource* resources, 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(); compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); if (numStrings == 0) return 1; TIntermediate intermediate(compiler->infoSink); TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]); generateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage()); TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->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"); if (parseContext.insertBuiltInArrayAtGlobalLevel()) success = false; 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 or linking 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); } intermediate.remove(parseContext.treeRoot); // // Ensure symbol table is returned to the built-in level, // throwing away all but the built-ins. // while (! symbolTable.atSharedBuiltInLevel()) symbolTable.pop(); FinalizePreprocessor(); // // Throw away all the temporary memory used by the compilation process. // GlobalPoolAllocator.pop(); return success ? 1 : 0; }