void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output) { const TStructure *structure = type.getStruct(); VarT variable; variable.name = name.c_str(); variable.arraySize = static_cast<unsigned int>(type.getArraySize()); if (!structure) { variable.type = GLVariableType(type); variable.precision = GLVariablePrecision(type); } else { // Note: this enum value is not exposed outside ANGLE variable.type = GL_STRUCT_ANGLEX; variable.structName = structure->name().c_str(); const TFieldList &fields = structure->fields(); for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++) { TField *field = fields[fieldIndex]; traverse(*field->type(), field->name(), &variable.fields); } } visitVariable(&variable); ASSERT(output); output->push_back(variable); }
void CollectVariables::visitVariable(const TIntermSymbol *variable, std::vector<Attribute> *infoList) const { ASSERT(variable); const TType &type = variable->getType(); ASSERT(!type.getStruct()); Attribute attribute; attribute.type = GLVariableType(type); attribute.precision = GLVariablePrecision(type); attribute.name = variable->getSymbol().c_str(); attribute.arraySize = static_cast<unsigned int>(type.getArraySize()); attribute.mappedName = TIntermTraverser::hash(variable->getSymbol(), mHashFunction).c_str(); attribute.location = variable->getType().getLayoutQualifier().location; infoList->push_back(attribute); }
// We want to check whether a uniform/varying is statically used // because we only count the used ones in packing computing. // Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count // toward varying counting if they are statically used in a fragment // shader. void CollectVariables::visitSymbol(TIntermSymbol *symbol) { ASSERT(symbol != NULL); ShaderVariable *var = NULL; const TString &symbolName = symbol->getSymbol(); if (IsVarying(symbol->getQualifier())) { var = FindVariable(symbolName, mVaryings); } else if (symbol->getType().getBasicType() == EbtInterfaceBlock) { UNREACHABLE(); } else if (symbolName == "gl_DepthRange") { ASSERT(symbol->getQualifier() == EvqUniform); if (!mDepthRangeAdded) { Uniform info; const char kName[] = "gl_DepthRange"; info.name = kName; info.mappedName = kName; info.type = GL_STRUCT_ANGLEX; info.arraySize = 0; info.precision = GL_NONE; info.staticUse = true; ShaderVariable nearInfo; const char kNearName[] = "near"; nearInfo.name = kNearName; nearInfo.mappedName = kNearName; nearInfo.type = GL_FLOAT; nearInfo.arraySize = 0; nearInfo.precision = GL_HIGH_FLOAT; nearInfo.staticUse = true; ShaderVariable farInfo; const char kFarName[] = "far"; farInfo.name = kFarName; farInfo.mappedName = kFarName; farInfo.type = GL_FLOAT; farInfo.arraySize = 0; farInfo.precision = GL_HIGH_FLOAT; farInfo.staticUse = true; ShaderVariable diffInfo; const char kDiffName[] = "diff"; diffInfo.name = kDiffName; diffInfo.mappedName = kDiffName; diffInfo.type = GL_FLOAT; diffInfo.arraySize = 0; diffInfo.precision = GL_HIGH_FLOAT; diffInfo.staticUse = true; info.fields.push_back(nearInfo); info.fields.push_back(farInfo); info.fields.push_back(diffInfo); mUniforms->push_back(info); mDepthRangeAdded = true; } } else { switch (symbol->getQualifier()) { case EvqAttribute: case EvqVertexIn: var = FindVariable(symbolName, mAttribs); break; case EvqFragmentOut: var = FindVariable(symbolName, mOutputVariables); break; case EvqUniform: { const TInterfaceBlock *interfaceBlock = symbol->getType().getInterfaceBlock(); if (interfaceBlock) { InterfaceBlock *namedBlock = FindVariable(interfaceBlock->name(), mInterfaceBlocks); ASSERT(namedBlock); var = FindVariable(symbolName, &namedBlock->fields); // Set static use on the parent interface block here namedBlock->staticUse = true; } else { var = FindVariable(symbolName, mUniforms); } // It's an internal error to reference an undefined user uniform ASSERT(symbolName.compare(0, 3, "gl_") != 0 || var); } break; case EvqFragCoord: if (!mFragCoordAdded) { Varying info; const char kName[] = "gl_FragCoord"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFragCoordAdded = true; } return; case EvqFrontFacing: if (!mFrontFacingAdded) { Varying info; const char kName[] = "gl_FrontFacing"; info.name = kName; info.mappedName = kName; info.type = GL_BOOL; info.arraySize = 0; info.precision = GL_NONE; info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mFrontFacingAdded = true; } return; case EvqPointCoord: if (!mPointCoordAdded) { Varying info; const char kName[] = "gl_PointCoord"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC2; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPointCoordAdded = true; } return; case EvqInstanceID: if (!mInstanceIDAdded) { Attribute info; const char kName[] = "gl_InstanceID"; info.name = kName; info.mappedName = kName; info.type = GL_INT; info.arraySize = 0; info.precision = GL_HIGH_INT; // Defined by spec. info.staticUse = true; info.location = -1; mAttribs->push_back(info); mInstanceIDAdded = true; } return; case EvqPosition: if (!mPositionAdded) { Varying info; const char kName[] = "gl_Position"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_HIGH_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPositionAdded = true; } return; case EvqPointSize: if (!mPointSizeAdded) { Varying info; const char kName[] = "gl_PointSize"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mPointSizeAdded = true; } return; case EvqLastFragData: if (!mLastFragDataAdded) { Varying info; const char kName[] = "gl_LastFragData"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = static_cast<const TVariable*>(mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100))->getConstPointer()->getIConst(); info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; info.isInvariant = mSymbolTable.isVaryingInvariant(kName); mVaryings->push_back(info); mLastFragDataAdded = true; } return; case EvqFragColor: if (!mFragColorAdded) { Attribute info; const char kName[] = "gl_FragColor"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = 0; info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; mOutputVariables->push_back(info); mFragColorAdded = true; } return; case EvqFragData: if (!mFragDataAdded) { Attribute info; const char kName[] = "gl_FragData"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT_VEC4; info.arraySize = static_cast<const TVariable *>( mSymbolTable.findBuiltIn("gl_MaxDrawBuffers", 100)) ->getConstPointer() ->getIConst(); info.precision = GL_MEDIUM_FLOAT; // Defined by spec. info.staticUse = true; mOutputVariables->push_back(info); mFragDataAdded = true; } return; case EvqFragDepthEXT: if (!mFragDepthEXTAdded) { Attribute info; const char kName[] = "gl_FragDepthEXT"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GLVariablePrecision(static_cast<const TVariable *>( mSymbolTable.findBuiltIn("gl_FragDepthEXT", 100)) ->getType()); info.staticUse = true; mOutputVariables->push_back(info); mFragDepthEXTAdded = true; } return; case EvqFragDepth: if (!mFragDepthAdded) { Attribute info; const char kName[] = "gl_FragDepth"; info.name = kName; info.mappedName = kName; info.type = GL_FLOAT; info.arraySize = 0; info.precision = GL_HIGH_FLOAT; info.staticUse = true; mOutputVariables->push_back(info); mFragDepthAdded = true; } return; default: break; } } if (var) { var->staticUse = true; } }