diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp | 98 |
1 files changed, 64 insertions, 34 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp index ac1c10d6b0..cd37aeacd1 100644 --- a/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp +++ b/src/3rdparty/angle/src/compiler/translator/ValidateOutputs.cpp @@ -9,11 +9,23 @@ #include "compiler/translator/InitializeParseContext.h" #include "compiler/translator/ParseContext.h" -ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers) - : mSink(sink), +namespace +{ +void error(int *errorCount, TInfoSinkBase &sink, const TIntermSymbol &symbol, const char *reason) +{ + sink.prefix(EPrefixError); + sink.location(symbol.getLine()); + sink << "'" << symbol.getSymbol() << "' : " << reason << "\n"; + (*errorCount)++; +} + +} // namespace + +ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers) + : TIntermTraverser(true, false, false), mMaxDrawBuffers(maxDrawBuffers), - mNumErrors(0), - mHasUnspecifiedOutputLocation(false) + mAllowUnspecifiedOutputLocationResolution( + IsExtensionEnabled(extBehavior, "GL_EXT_blend_func_extended")) { } @@ -29,50 +41,68 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) if (qualifier == EvqFragmentOut) { - const TType &type = symbol->getType(); - const int location = type.getLayoutQualifier().location; - - if (mHasUnspecifiedOutputLocation) + if (symbol->getType().getLayoutQualifier().location == -1) { - error(symbol->getLine(), "must explicitly specify all locations when using multiple fragment outputs", name.c_str()); + mUnspecifiedLocationOutputs.push_back(symbol); } - else if (location == -1) + else { - mHasUnspecifiedOutputLocation = true; + mOutputs.push_back(symbol); } - else + } +} + +int ValidateOutputs::validateAndCountErrors(TInfoSinkBase &sink) const +{ + OutputVector validOutputs(mMaxDrawBuffers); + int errorCount = 0; + + for (const auto &symbol : mOutputs) + { + const TType &type = symbol->getType(); + const size_t elementCount = static_cast<size_t>(type.isArray() ? type.getArraySize() : 1); + const size_t location = static_cast<size_t>(type.getLayoutQualifier().location); + + ASSERT(type.getLayoutQualifier().location != -1); + + if (location + elementCount <= validOutputs.size()) { - OutputMap::iterator mapEntry = mOutputMap.find(location); - if (mapEntry == mOutputMap.end()) + for (size_t elementIndex = 0; elementIndex < elementCount; elementIndex++) { - const int elementCount = type.isArray() ? type.getArraySize() : 1; - if (location + elementCount > mMaxDrawBuffers) + const size_t offsetLocation = location + elementIndex; + if (validOutputs[offsetLocation]) { - error(symbol->getLine(), "output location must be < MAX_DRAW_BUFFERS", name.c_str()); + std::stringstream strstr; + strstr << "conflicting output locations with previously defined output '" + << validOutputs[offsetLocation]->getSymbol() << "'"; + error(&errorCount, sink, *symbol, strstr.str().c_str()); } - - for (int elementIndex = 0; elementIndex < elementCount; elementIndex++) + else { - const int offsetLocation = location + elementIndex; - mOutputMap[offsetLocation] = symbol; + validOutputs[offsetLocation] = symbol; } } - else + } + else + { + if (elementCount > 0) { - std::stringstream strstr; - strstr << "conflicting output locations with previously defined output '" - << mapEntry->second->getSymbol() << "'"; - - error(symbol->getLine(), strstr.str().c_str(), name.c_str()); + error(&errorCount, sink, *symbol, + elementCount > 1 ? "output array locations would exceed MAX_DRAW_BUFFERS" + : "output location must be < MAX_DRAW_BUFFERS"); } } } -} -void ValidateOutputs::error(TSourceLoc loc, const char *reason, const char* token) -{ - mSink.prefix(EPrefixError); - mSink.location(loc); - mSink << "'" << token << "' : " << reason << "\n"; - mNumErrors++; + if (!mAllowUnspecifiedOutputLocationResolution && + ((!mOutputs.empty() && !mUnspecifiedLocationOutputs.empty()) || + mUnspecifiedLocationOutputs.size() > 1)) + { + for (const auto &symbol : mUnspecifiedLocationOutputs) + { + error(&errorCount, sink, *symbol, + "must explicitly specify all locations when using multiple fragment outputs"); + } + } + return errorCount; } |