3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
// Recursively figure out how many locations are used up by an input or output type.
// Return the size of type, as measured by "locations".
Recursively figure out how many locations are used up by an input or output type.
Return the size of type, as measured by "locations".
Recursively figure out how many locations are used up by an input or output type . Return the size of type as measured by " locations " .
int TIntermediate::computeTypeLocationSize(const TType& type) const
{
    if (type.isArray()) {
        TType elementType(type, 0);
        if (type.isImplicitlySizedArray()) {
            return computeTypeLocationSize(elementType);
        } else
            return type.getOuterArraySize() * computeTypeLocationSize(elementType);
    }
    if (type.isStruct()) {
        int size = 0;
        for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
            TType memberType(type, member);
            size += computeTypeLocationSize(memberType);
        }
        return size;
    }
    if (type.isScalar())
        return 1;
    if (type.isVector()) {
        if (language == EShLangVertex && type.getQualifier().isPipeInput())
            return 1;
        if (type.getBasicType() == EbtDouble && type.getVectorSize() > 2)
            return 2;
        else
            return 1;
    }
    if (type.isMatrix()) {
        TType columnType(type, 0);
        return type.getMatrixCols() * computeTypeLocationSize(columnType);
    }
    assert(0);
    return 1;
}
int TIntermediate :: computeTypeLocationSize ( const TType & type ) const { if ( type . isArray ( ) ) { TType elementType ( type , 0 ) ; if ( type . isImplicitlySizedArray ( ) ) { return computeTypeLocationSize ( elementType ) ; } else return type . getOuterArraySize ( ) * computeTypeLocationSize ( elementType ) ; } if ( type . isStruct ( ) ) { int size = 0 ; for ( int member = 0 ; member < ( int ) type . getStruct ( ) -> size ( ) ; ++ member ) { TType memberType ( type , member ) ; size += computeTypeLocationSize ( memberType ) ; } return size ; } if ( type . isScalar ( ) ) return 1 ; if ( type . isVector ( ) ) { if ( language == EShLangVertex && type . getQualifier ( ) . isPipeInput ( ) ) return 1 ; if ( type . getBasicType ( ) == EbtDouble && type . getVectorSize ( ) > 2 ) return 2 ; else return 1 ; } if ( type . isMatrix ( ) ) { TType columnType ( type , 0 ) ; return type . getMatrixCols ( ) * computeTypeLocationSize ( columnType ) ; } assert ( 0 ) ; return 1 ; }
Recursively figure out how many locations are used up by an input or output type.
Recursively figure out how many locations are used up by an input or output type .
// "If the declared input is an array of size n and each element takes m locations, it will be assigned m * n // consecutive locations..." // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness // TODO: are there valid cases of having an implicitly-sized array with a location?  If so, running this code too early. // "The locations consumed by block and structure members are determined by applying the rules above // recursively..." // ES: "If a shader input is any scalar or vector type, it will consume a single location." // Desktop: "If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex // shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while // types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will // consume only a single location, in all stages." // "If the declared input is an n x m single- or double-precision matrix, ... // The number of locations assigned for each matrix will be the same as // for an n-element array of m-component vectors..."