3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
// as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
// typeCollision is set to true if there is no direct collision, but the types in the same location
// are different.
//
Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
as the accumulation is done.

Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.

typeCollision is set to true if there is no direct collision, but the types in the same location
are different.
Accumulate locations used for inputs outputs and uniforms and check for collisions as the accumulation is done . Returns < 0 if no collision > = 0 if collision and the value returned is a colliding value . typeCollision is set to true if there is no direct collision but the types in the same location are different .
int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type, bool& typeCollision)
{
    typeCollision = false;
    int set;
    if (qualifier.isPipeInput())
        set = 0;
    else if (qualifier.isPipeOutput())
        set = 1;
    else if (qualifier.storage == EvqUniform)
        set = 2;
    else if (qualifier.storage == EvqBuffer)
        set = 3;
    else
        return -1;
    int size;
    if (qualifier.isUniformOrBuffer()) {
        if (type.isExplicitlySizedArray())
            size = type.getCumulativeArraySize();
        else
            size = 1;
    } else {
        if (type.isArray() && qualifier.isArrayedIo(language)) {
            TType elementType(type, 0);
            size = computeTypeLocationSize(elementType);
        } else
            size = computeTypeLocationSize(type);
    }
     Almost always, dealing with components means a single location is involved.
     The exception is a dvec3. From the spec:
     "A dvec3 will consume all four components of the first location and components 0 and 1 of
     the second location. This leaves components 2 and 3 available for other component-qualified
     declarations."
     That means, without ever mentioning a component, a component range
     for a different location gets specified, if it's not a vertex shader input. (!)
     (A vertex shader input will show using only one location, even for a dvec3/4.)
     So, for the case of dvec3, we need two independent ioRanges.
    int collision = -1;  no collision
    if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
        (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
         Dealing with dvec3 in/out split across two locations.
         Need two io-ranges.
         The case where the dvec3 doesn't start at component 0 was previously caught as overflow.
         First range:
        TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
        TRange componentRange(0, 3);
        TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
         check for collisions
        collision = checkLocationRange(set, range, type, typeCollision);
        if (collision < 0) {
            usedIo[set].push_back(range);
             Second range:
            TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
            TRange componentRange2(0, 1);
            TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
             check for collisions
            collision = checkLocationRange(set, range2, type, typeCollision);
            if (collision < 0)
                usedIo[set].push_back(range2);
        }
    } else {
         Not a dvec3 in/out split across two locations, generic path.
         Need a single IO-range block.
        TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
        TRange componentRange(0, 3);
        if (qualifier.hasComponent() || type.getVectorSize() > 0) {
            int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
            if (qualifier.hasComponent())
                componentRange.start = qualifier.layoutComponent;
            componentRange.last  = componentRange.start + consumedComponents - 1;
        }
         combine location and component ranges
        TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
         check for collisions, except for vertex inputs on desktop
        if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()))
            collision = checkLocationRange(set, range, type, typeCollision);
        if (collision < 0)
            usedIo[set].push_back(range);
    }
    return collision;
}
int TIntermediate :: addUsedLocation ( const TQualifier & qualifier , const TType & type , bool & typeCollision ) { typeCollision = false ; int set ; if ( qualifier . isPipeInput ( ) ) set = 0 ; else if ( qualifier . isPipeOutput ( ) ) set = 1 ; else if ( qualifier . storage == EvqUniform ) set = 2 ; else if ( qualifier . storage == EvqBuffer ) set = 3 ; else return -1 ; int size ; if ( qualifier . isUniformOrBuffer ( ) ) { if ( type . isExplicitlySizedArray ( ) ) size = type . getCumulativeArraySize ( ) ; else size = 1 ; } else { if ( type . isArray ( ) && qualifier . isArrayedIo ( language ) ) { TType elementType ( type , 0 ) ; size = computeTypeLocationSize ( elementType ) ; } else size = computeTypeLocationSize ( type ) ; } int collision = -1 ; if ( size == 2 && type . getBasicType ( ) == EbtDouble && type . getVectorSize ( ) == 3 && ( qualifier . isPipeInput ( ) || qualifier . isPipeOutput ( ) ) ) { TRange locationRange ( qualifier . layoutLocation , qualifier . layoutLocation ) ; TRange componentRange ( 0 , 3 ) ; TIoRange range ( locationRange , componentRange , type . getBasicType ( ) , 0 ) ; collision = checkLocationRange ( set , range , type , typeCollision ) ; if ( collision < 0 ) { usedIo [ set ] . push_back ( range ) ; TRange locationRange2 ( qualifier . layoutLocation + 1 , qualifier . layoutLocation + 1 ) ; TRange componentRange2 ( 0 , 1 ) ; TIoRange range2 ( locationRange2 , componentRange2 , type . getBasicType ( ) , 0 ) ; collision = checkLocationRange ( set , range2 , type , typeCollision ) ; if ( collision < 0 ) usedIo [ set ] . push_back ( range2 ) ; } } else { TRange locationRange ( qualifier . layoutLocation , qualifier . layoutLocation + size - 1 ) ; TRange componentRange ( 0 , 3 ) ; if ( qualifier . hasComponent ( ) || type . getVectorSize ( ) > 0 ) { int consumedComponents = type . getVectorSize ( ) * ( type . getBasicType ( ) == EbtDouble ? 2 : 1 ) ; if ( qualifier . hasComponent ( ) ) componentRange . start = qualifier . layoutComponent ; componentRange . last = componentRange . start + consumedComponents - 1 ; } TIoRange range ( locationRange , componentRange , type . getBasicType ( ) , qualifier . hasIndex ( ) ? qualifier . layoutIndex : 0 ) ; if ( ! ( profile != EEsProfile && language == EShLangVertex && qualifier . isPipeInput ( ) ) ) collision = checkLocationRange ( set , range , type , typeCollision ) ; if ( collision < 0 ) usedIo [ set ] . push_back ( range ) ; } return collision ; }
Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
as the accumulation is done.
Accumulate locations used for inputs outputs and uniforms and check for collisions as the accumulation is done .
// Strip off the outer array dimension for those having an extra one. // Locations, and components within locations. // // Almost always, dealing with components means a single location is involved. // The exception is a dvec3. From the spec: // // "A dvec3 will consume all four components of the first location and components 0 and 1 of // the second location. This leaves components 2 and 3 available for other component-qualified // declarations." // // That means, without ever mentioning a component, a component range // for a different location gets specified, if it's not a vertex shader input. (!) // (A vertex shader input will show using only one location, even for a dvec3/4.) // // So, for the case of dvec3, we need two independent ioRanges. // no collision // Dealing with dvec3 in/out split across two locations. // Need two io-ranges. // The case where the dvec3 doesn't start at component 0 was previously caught as overflow. // First range: // check for collisions // Second range: // check for collisions // Not a dvec3 in/out split across two locations, generic path. // Need a single IO-range block. // combine location and component ranges // check for collisions, except for vertex inputs on desktop