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); }
TString Std140PaddingHelper::postPaddingString(const TType &type, bool useHLSLRowMajorPacking) { if (!type.isMatrix() && !type.isArray() && type.getBasicType() != EbtStruct) { return ""; } int numComponents = 0; TStructure *structure = type.getStruct(); if (type.isMatrix()) { // This method can also be called from structureString, which does not use layout qualifiers. // Thus, use the method parameter for determining the matrix packing. // // Note HLSL row major packing corresponds to GL API column-major, and vice-versa, since we // wish to always transpose GL matrices to play well with HLSL's matrix array indexing. // const bool isRowMajorMatrix = !useHLSLRowMajorPacking; const GLenum glType = GLVariableType(type); numComponents = gl::MatrixComponentCount(glType, isRowMajorMatrix); } else if (structure) { const TString &structName = QualifiedStructNameString(*structure, useHLSLRowMajorPacking, true); numComponents = mStructElementIndexes->find(structName)->second; if (numComponents == 0) { return ""; } } else { const GLenum glType = GLVariableType(type); numComponents = gl::VariableComponentCount(glType); } TString padding; for (int paddingOffset = numComponents; paddingOffset < 4; paddingOffset++) { padding += " float pad_" + next() + ";\n"; } return padding; }
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); }
int Std140PaddingHelper::prePadding(const TType &type) { if (type.getBasicType() == EbtStruct || type.isMatrix() || type.isArray()) { // no padding needed, HLSL will align the field to a new register mElementIndex = 0; return 0; } const GLenum glType = GLVariableType(type); const int numComponents = gl::VariableComponentCount(glType); if (numComponents >= 4) { // no padding needed, HLSL will align the field to a new register mElementIndex = 0; return 0; } if (mElementIndex + numComponents > 4) { // no padding needed, HLSL will align the field to a new register mElementIndex = numComponents; return 0; } const int alignment = numComponents == 3 ? 4 : numComponents; const int paddingOffset = (mElementIndex % alignment); const int paddingCount = (paddingOffset != 0 ? (alignment - paddingOffset) : 0); mElementIndex += paddingCount; mElementIndex += numComponents; mElementIndex %= 4; return paddingCount; }