diff --git a/src/libANGLE/ProgramExecutable.cpp b/src/libANGLE/ProgramExecutable.cpp index c5a431ddc1..328c52406d 100644 --- a/src/libANGLE/ProgramExecutable.cpp +++ b/src/libANGLE/ProgramExecutable.cpp @@ -1816,6 +1816,19 @@ bool ProgramExecutable::gatherOutputTypes() for (unsigned int elementIndex = 0; elementIndex < elementCount; elementIndex++) { const unsigned int location = baseLocation + elementIndex; + if (location >= IMPLEMENTATION_MAX_DRAW_BUFFERS) + { + // Per-element glBindFragDataLocationEXT bindings can leave the + // base of an output array near maxDrawBuffers while the + // over-max guard in linkValidateOutputVariables() only checks + // *used* locations. Reject any element whose effective location + // exceeds the implementation limit so backends never see + // location >= IMPLEMENTATION_MAX_DRAW_BUFFERS. + *mInfoLog << "Fragment output " << outputVariable.name << " element " + << elementIndex << " resolves to location " << location + << " which exceeds IMPLEMENTATION_MAX_DRAW_BUFFERS."; + return false; + } ASSERT(location < mPod.activeOutputVariablesMask.size()); ASSERT(location < mPod.activeSecondaryOutputVariablesMask.size()); if (secondary)