3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
// Recursively figure out how many bytes of xfb buffer are used by the given type.
// Return the size of type, in bytes.
// Sets containsDouble to true if the type contains a double.
// N.B. Caller must set containsDouble to false before calling.
Recursively figure out how many bytes of xfb buffer are used by the given type.
Return the size of type, in bytes.
Sets containsDouble to true if the type contains a double.
Recursively figure out how many bytes of xfb buffer are used by the given type . Return the size of type in bytes . Sets containsDouble to true if the type contains a double .
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& containsDouble) const
{
    if (type.isArray()) {
        assert(type.isExplicitlySizedArray());
        TType elementType(type, 0);
        return type.getOuterArraySize() * computeTypeXfbSize(elementType, containsDouble);
    }
    if (type.isStruct()) {
        unsigned int size = 0;
        bool structContainsDouble = false;
        for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
            TType memberType(type, member);
            "
            bool memberContainsDouble = false;
            int memberSize = computeTypeXfbSize(memberType, memberContainsDouble);
            if (memberContainsDouble) {
                structContainsDouble = true;
                RoundToPow2(size, 8);
            }
            size += memberSize;
        }
        if (structContainsDouble) {
            containsDouble = true;
            RoundToPow2(size, 8);
        }
        return size;
    }
    int numComponents;
    if (type.isScalar())
        numComponents = 1;
    else if (type.isVector())
        numComponents = type.getVectorSize();
    else if (type.isMatrix())
        numComponents = type.getMatrixCols() * type.getMatrixRows();
    else {
        assert(0);
        numComponents = 1;
    }
    if (type.getBasicType() == EbtDouble) {
        containsDouble = true;
        return 8 * numComponents;
    } else
        return 4 * numComponents;
}
unsigned int TIntermediate :: computeTypeXfbSize ( const TType & type , bool & containsDouble ) const { if ( type . isArray ( ) ) { assert ( type . isExplicitlySizedArray ( ) ) ; TType elementType ( type , 0 ) ; return type . getOuterArraySize ( ) * computeTypeXfbSize ( elementType , containsDouble ) ; } if ( type . isStruct ( ) ) { unsigned int size = 0 ; bool structContainsDouble = false ; for ( int member = 0 ; member < ( int ) type . getStruct ( ) -> size ( ) ; ++ member ) { TType memberType ( type , member ) ; bool memberContainsDouble = false ; int memberSize = computeTypeXfbSize ( memberType , memberContainsDouble ) ; if ( memberContainsDouble ) { structContainsDouble = true ; RoundToPow2 ( size , 8 ) ; } size += memberSize ; } if ( structContainsDouble ) { containsDouble = true ; RoundToPow2 ( size , 8 ) ; } return size ; } int numComponents ; if ( type . isScalar ( ) ) numComponents = 1 ; else if ( type . isVector ( ) ) numComponents = type . getVectorSize ( ) ; else if ( type . isMatrix ( ) ) numComponents = type . getMatrixCols ( ) * type . getMatrixRows ( ) ; else { assert ( 0 ) ; numComponents = 1 ; } if ( type . getBasicType ( ) == EbtDouble ) { containsDouble = true ; return 8 * numComponents ; } else return 4 * numComponents ; }
Recursively figure out how many bytes of xfb buffer are used by the given type.
Recursively figure out how many bytes of xfb buffer are used by the given type .
// "...if applied to an aggregate containing a double, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8. // ...within the qualified entity, subsequent components are each // assigned, in order, to the next available offset aligned to a multiple of // that component's size.  Aggregate types are flattened down to the component // level to get this sequence of components." // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness // "... if applied to // an aggregate containing a double, the offset must also be a multiple of 8, // and the space taken in the buffer will be a multiple of 8."