// 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.isArray()) size = type.getCumulativeArraySize(); else size = 1; } else { // Strip off the outer array dimension for those having an extra one. if (type.isArray() && qualifier.isArrayedIo(language)) { TType elementType(type, 0); size = computeTypeLocationSize(elementType); } else size = computeTypeLocationSize(type); } TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1); TRange componentRange(0, 3); if (qualifier.hasComponent()) { componentRange.start = qualifier.layoutComponent; componentRange.last = componentRange.start + type.getVectorSize() - 1; } 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())) { for (size_t r = 0; r < usedIo[set].size(); ++r) { if (range.overlap(usedIo[set][r])) { // there is a collision; pick one return std::max(locationRange.start, usedIo[set][r].location.start); } else if (locationRange.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) { // aliased-type mismatch typeCollision = true; return std::max(locationRange.start, usedIo[set][r].location.start); } } } usedIo[set].push_back(range); return -1; // no collision }