// // Do an actual link on the given compile objects. // // Return: The return value of is really boolean, indicating // success or failure. // int ShLink( const ShHandle linkHandle, const ShHandle compHandles[], const int numHandles, ShHandle uniformMapHandle, short int** uniformsAccessed, int* numUniformsAccessed) { if (!InitThread()) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle); TLinker* linker = static_cast<TLinker*>(base->getAsLinker()); if (linker == 0) return 0; int returnValue; GlobalPoolAllocator.push(); returnValue = ShLinkExt(linkHandle, compHandles, numHandles); GlobalPoolAllocator.pop(); if (returnValue) return 1; return 0; }
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(); } }
// // Driver calls these to create and destroy compiler objects. // ShHandle ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output, const ShBuiltInResources *resources) { TShHandleBase *base = static_cast<TShHandleBase *>(ConstructCompiler(type, spec, output)); if (base == nullptr) { return 0; } TCompiler *compiler = base->getAsCompiler(); if (compiler == nullptr) { return 0; } // Generate built-in symbol table. if (!compiler->Init(*resources)) { Destruct(base); return 0; } return base; }
const std::vector<InterfaceBlock> *GetShaderStorageBlocks(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return &compiler->getShaderStorageBlocks(); }
int GetVertexShaderNumViews(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return compiler->getNumViews(); }
void ShDestruct(ShHandle handle) { if (handle == 0) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); if (base->getAsCompiler()) DeleteCompiler(base->getAsCompiler()); }
int GetGeometryShaderInvocations(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return compiler->getGeometryShaderInvocations(); }
GLenum GetGeometryShaderOutputPrimitiveType(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return GetGeometryShaderPrimitiveTypeEnum(compiler->getGeometryShaderOutputPrimitiveType()); }
bool HasValidGeometryShaderMaxVertices(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return compiler->getGeometryShaderMaxVertices() >= 0; }
bool HasValidGeometryShaderOutputPrimitiveType(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return compiler->getGeometryShaderOutputPrimitiveType() != EptUndefined; }
WorkGroupSize GetComputeShaderLocalGroupSize(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); return compiler->getComputeShaderLocalSize(); }
int GetGeometryShaderMaxVertices(const ShHandle handle) { ASSERT(handle); TShHandleBase *base = static_cast<TShHandleBase *>(handle); TCompiler *compiler = base->getAsCompiler(); ASSERT(compiler); int maxVertices = compiler->getGeometryShaderMaxVertices(); ASSERT(maxVertices >= 0); return maxVertices; }
// // 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()); }
// // 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 the index for OpenGL to use for knowing where a uniform lives. // // Return: The return value of is really boolean, indicating // success or failure. // int ShGetUniformLocation(const ShHandle handle, const char* name) { if (!InitThread()) return 0; if (handle == 0) return -1; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TUniformMap* uniformMap= base->getAsUniformMap(); if (uniformMap == 0) return -1; return uniformMap->getLocation(name); }
// // Return the resulting binary code from the link process. Structure // is machine dependent. // const void* ShGetExecutable(const ShHandle handle) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TLinker* linker = static_cast<TLinker*>(base->getAsLinker()); if (linker == 0) return 0; return linker->getObjectCode(); }
// // Return any object code. // const char* ShGetObjectCode(const ShHandle handle) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TInfoSink* infoSink; if (base->getAsCompiler()) infoSink = &(base->getAsCompiler()->getInfoSink()); return infoSink->obj.c_str(); }
// // Some attribute locations are off-limits to the linker... // int ShExcludeAttributes(const ShHandle handle, int *attributes, int count) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TLinker* linker = static_cast<TLinker*>(base->getAsLinker()); if (linker == 0) return 0; linker->setExcludedAttributes(attributes, count); return 1; }
// // Let the linker know where the predefined attributes have to live. // int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TLinker* linker = static_cast<TLinker*>(base->getAsLinker()); if (linker == 0) return 0; linker->setFixedAttributeBindings(table); return 1; }
// // 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[], size_t numStrings, int compileOptions) { if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; bool success = compiler->compile(shaderStrings, numStrings, compileOptions); return success ? 1 : 0; }
void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params) { if (!handle || !params) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TranslatorHLSL* translator = base->getAsTranslatorHLSL(); if (!translator) return; switch(pname) { case SH_ACTIVE_UNIFORMS_ARRAY: *params = (void*)&translator->getUniforms(); break; default: UNREACHABLE(); } }
// // Driver calls these to create and destroy compiler objects. // ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output, const ShBuiltInResources* resources) { TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output)); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; // Generate built-in symbol table. if (!compiler->Init(*resources)) { ShDestruct(base); return 0; } return reinterpret_cast<void*>(base); }
// // Return any compiler log of messages for the application. // const char* ShGetInfoLog(const ShHandle handle) { if (!InitThread()) return 0; if (handle == 0) return 0; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TInfoSink* infoSink = 0; if (base->getAsCompiler()) infoSink = &(base->getAsCompiler()->getInfoSink()); infoSink->info << infoSink->debug.c_str(); return infoSink->info.c_str(); }
static void getVariableInfo(ShShaderInfo varType, const ShHandle handle, int index, size_t* length, int* size, ShDataType* type, char* name, char* mappedName) { if (!handle || !size || !type || !name) return; ASSERT((varType == SH_ACTIVE_ATTRIBUTES) || (varType == SH_ACTIVE_UNIFORMS)); TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return; const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() : compiler->getUniforms(); 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; // This size must match that queried by // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH // in ShGetInfo, below. size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN; ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength)); strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength); name[activeUniformAndAttribLength - 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; } }
// // 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); }
void ShGetNameHashingEntry(const ShHandle handle, int index, char* name, char* hashedName) { if (!handle || !name || !hashedName || index < 0) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (!compiler) return; const NameMap& nameMap = compiler->getNameMap(); if (index >= static_cast<int>(nameMap.size())) return; NameMap::const_iterator it = nameMap.begin(); for (int i = 0; i < index; ++i) ++it; size_t len = it->first.length() + 1; size_t max_len = 0; ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len); if (len > max_len) { ASSERT(false); len = max_len; } strncpy(name, it->first.c_str(), len); // To be on the safe side in case the source is longer than expected. name[len - 1] = '\0'; len = it->second.length() + 1; max_len = 0; ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len); if (len > max_len) { ASSERT(false); len = max_len; } strncpy(hashedName, it->second.c_str(), len); // To be on the safe side in case the source is longer than expected. hashedName[len - 1] = '\0'; }
// // Do a full compile on the given strings for a single compilation unit // forming a complete stage. The result of the machine dependent compilation // is left in the provided compile object. // // Return: The return value is really boolean, indicating // success (1) or failure (0). // int ShCompile( const ShHandle handle, const char* const shaderStrings[], const int numStrings, const int* inputLengths, const EShOptimizationLevel optLevel, const TBuiltInResource* resources, int /*debugOptions*/, int defaultVersion, // use 100 for ES environment, 110 for desktop bool forwardCompatible, // give errors for use of deprecated features EShMessages messages // warnings/errors/AST; things to print out ) { // Map the generic handle to the C++ object if (handle == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); TIntermediate intermediate(compiler->getLanguage()); bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, "", optLevel, resources, defaultVersion, ENoProfile, false, forwardCompatible, messages, intermediate); // // Call the machine dependent compiler // if (success && intermediate.getTreeRoot() && optLevel != EShOptNoGeneration) success = compiler->compile(intermediate.getTreeRoot(), intermediate.getVersion(), intermediate.getProfile()); intermediate.removeTree(); // Throw away all the temporary memory used by the compilation process. // The push was done in the CompileDeferred() call above. GetThreadPoolAllocator().pop(); return success ? 1 : 0; }
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(); } }
void ShDestruct(ShHandle handle) { if (handle == 0) return; TShHandleBase* base = static_cast<TShHandleBase*>(handle); if (base->getAsCompiler()) DeleteCompiler(base->getAsCompiler()); else if (base->getAsLinker()) DeleteLinker(base->getAsLinker()); else if (base->getAsUniformMap()) DeleteUniformMap(base->getAsUniformMap()); }
// // This link method will be eventually used once the ICD supports the new linker interface // int ShLinkExt( const ShHandle linkHandle, const ShHandle compHandles[], const int numHandles) { if (linkHandle == 0 || numHandles == 0) return 0; THandleList cObjects; {// support MSVC++6.0 for (int i = 0; i < numHandles; ++i) { if (compHandles[i] == 0) return 0; TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]); if (base->getAsLinker()) { cObjects.push_back(base->getAsLinker()); } if (base->getAsCompiler()) cObjects.push_back(base->getAsCompiler()); if (cObjects[i] == 0) return 0; } } TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle); TLinker* linker = static_cast<TLinker*>(base->getAsLinker()); if (linker == 0) return 0; linker->infoSink.info.erase(); {// support MSVC++6.0 for (int i = 0; i < numHandles; ++i) { if (cObjects[i]->getAsCompiler()) { if (! cObjects[i]->getAsCompiler()->linkable()) { linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code."); return 0; } } } } bool ret = linker->link(cObjects); return ret ? 1 : 0; }