static bool getSymbolInfo(ShHandle compiler, ANGLEShaderSymbolType symbolType, Vector<ANGLEShaderSymbol>& symbols) { switch (symbolType) { case SHADER_SYMBOL_TYPE_UNIFORM: { auto uniforms = ShGetUniforms(compiler); if (!uniforms) return false; for (const auto& uniform : *uniforms) getSymbolInfo(uniform, symbolType, symbols); break; } case SHADER_SYMBOL_TYPE_VARYING: { auto varyings = ShGetVaryings(compiler); if (!varyings) return false; for (const auto& varying : *varyings) getSymbolInfo(varying, symbolType, symbols); break; } case SHADER_SYMBOL_TYPE_ATTRIBUTE: { auto attributes = ShGetAttributes(compiler); if (!attributes) return false; for (const auto& attribute : *attributes) getSymbolInfo(attribute, symbolType, symbols); break; } default: ASSERT_NOT_REACHED(); return false; } return true; }
void ShaderD3D::parseAttributes(ShHandle compiler) { const std::string &hlsl = getTranslatedSource(); if (!hlsl.empty()) { mActiveAttributes = *GetShaderVariables(ShGetAttributes(compiler)); FilterInactiveVariables(&mActiveAttributes); } }
bool ShaderValidator::FindAttribMappedNameByUserName(const std::string& userName, const std::string** const out_mappedName) const { const std::vector<sh::Attribute>& attribs = *ShGetAttributes(mHandle); for (auto itr = attribs.begin(); itr != attribs.end(); ++itr) { if (itr->name == userName) { *out_mappedName = &(itr->mappedName); return true; } } return false; }
static void PrintActiveVariables(ShHandle compiler) { const std::vector<sh::Uniform> *uniforms = ShGetUniforms(compiler); const std::vector<sh::Varying> *varyings = ShGetVaryings(compiler); const std::vector<sh::Attribute> *attributes = ShGetAttributes(compiler); for (size_t varCategory = 0; varCategory < 3; ++varCategory) { size_t numVars = 0; std::string varCategoryName; if (varCategory == 0) { numVars = uniforms->size(); varCategoryName = "uniform"; } else if (varCategory == 1) { numVars = varyings->size(); varCategoryName = "varying"; } else { numVars = attributes->size(); varCategoryName = "attribute"; } for (size_t i = 0; i < numVars; ++i) { const sh::ShaderVariable *var; if (varCategory == 0) var = &((*uniforms)[i]); else if (varCategory == 1) var = &((*varyings)[i]); else var = &((*attributes)[i]); PrintVariable(varCategoryName, i, *var); } printf("\n"); } }
size_t ShaderValidator::NumAttributes() const { return ShGetAttributes(mHandle)->size(); }
void Shader::compile(Compiler *compiler) { mData.mTranslatedSource.clear(); mInfoLog.clear(); mData.mShaderVersion = 100; mData.mVaryings.clear(); mData.mUniforms.clear(); mData.mInterfaceBlocks.clear(); mData.mActiveAttributes.clear(); mData.mActiveOutputVariables.clear(); ShHandle compilerHandle = compiler->getCompilerHandle(mData.mShaderType); std::stringstream sourceStream; std::string sourcePath; int additionalOptions = mImplementation->prepareSourceAndReturnOptions(&sourceStream, &sourcePath); int compileOptions = (SH_OBJECT_CODE | SH_VARIABLES | additionalOptions); // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes // in fragment shaders. Shader compilation will fail. To provide a better error message we can // instruct the compiler to pre-validate. if (mRendererLimitations.shadersRequireIndexedLoopValidation) { compileOptions |= SH_VALIDATE_LOOP_INDEXING; } std::string sourceString = sourceStream.str(); std::vector<const char *> sourceCStrings; if (!sourcePath.empty()) { sourceCStrings.push_back(sourcePath.c_str()); } sourceCStrings.push_back(sourceString.c_str()); bool result = ShCompile(compilerHandle, &sourceCStrings[0], sourceCStrings.size(), compileOptions); if (!result) { mInfoLog = ShGetInfoLog(compilerHandle); TRACE("\n%s", mInfoLog.c_str()); mCompiled = false; return; } mData.mTranslatedSource = ShGetObjectCode(compilerHandle); #ifndef NDEBUG // Prefix translated shader with commented out un-translated shader. // Useful in diagnostics tools which capture the shader source. std::ostringstream shaderStream; shaderStream << "// GLSL\n"; shaderStream << "//\n"; size_t curPos = 0; while (curPos != std::string::npos) { size_t nextLine = mData.mSource.find("\n", curPos); size_t len = (nextLine == std::string::npos) ? std::string::npos : (nextLine - curPos + 1); shaderStream << "// " << mData.mSource.substr(curPos, len); curPos = (nextLine == std::string::npos) ? std::string::npos : (nextLine + 1); } shaderStream << "\n\n"; shaderStream << mData.mTranslatedSource; mData.mTranslatedSource = shaderStream.str(); #endif // Gather the shader information mData.mShaderVersion = ShGetShaderVersion(compilerHandle); mData.mVaryings = GetShaderVariables(ShGetVaryings(compilerHandle)); mData.mUniforms = GetShaderVariables(ShGetUniforms(compilerHandle)); mData.mInterfaceBlocks = GetShaderVariables(ShGetInterfaceBlocks(compilerHandle)); if (mData.mShaderType == GL_VERTEX_SHADER) { mData.mActiveAttributes = GetActiveShaderVariables(ShGetAttributes(compilerHandle)); } else { ASSERT(mData.mShaderType == GL_FRAGMENT_SHADER); // TODO(jmadill): Figure out why we only sort in the FS, and if we need to. std::sort(mData.mVaryings.begin(), mData.mVaryings.end(), CompareShaderVar); mData.mActiveOutputVariables = GetActiveShaderVariables(ShGetOutputVariables(compilerHandle)); } ASSERT(!mData.mTranslatedSource.empty()); mCompiled = mImplementation->postTranslateCompile(compiler, &mInfoLog); }