Hash :
19571818
Author :
Date :
2013-08-12T15:26:34
Add more robust support for interpolation and storage qualifiers with varyings for GLSL ES 3.00. This fixes some conformance failures in the dEQP varying link tests, particularly with ints and the flat keyword. TRAC #23745 Signed-off-by: Nicolas Capens Signed-off-by: Shannon Woods
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/ValidateOutputs.h"
#include "compiler/InfoSink.h"
#include "compiler/InitializeParseContext.h"
#include "compiler/ParseHelper.h"
ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers)
: mSink(sink),
mMaxDrawBuffers(maxDrawBuffers),
mNumErrors(0),
mHasUnspecifiedOutputLocation(false)
{
}
void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
{
TString name = symbol->getSymbol();
TQualifier qualifier = symbol->getQualifier();
if (mVisitedSymbols.count(name) == 1)
return;
mVisitedSymbols.insert(name);
if (qualifier == EvqFragmentOut)
{
const TType &type = symbol->getType();
const int location = type.getLayoutQualifier().location;
if (mHasUnspecifiedOutputLocation)
{
error(symbol->getLine(), "must explicitly specify all locations when using multiple fragment outputs", name.c_str());
}
else if (location == -1)
{
mHasUnspecifiedOutputLocation = true;
}
else
{
OutputMap::iterator mapEntry = mOutputMap.find(location);
if (mapEntry == mOutputMap.end())
{
const int elementCount = type.isArray() ? type.getArraySize() : 1;
if (location + elementCount > mMaxDrawBuffers)
{
error(symbol->getLine(), "output location must be < MAX_DRAW_BUFFERS", name.c_str());
}
for (int elementIndex = 0; elementIndex < elementCount; elementIndex++)
{
const int offsetLocation = location + elementIndex;
mOutputMap[offsetLocation] = symbol;
}
}
else
{
std::stringstream strstr;
strstr << "conflicting output locations with previously defined output '"
<< mapEntry->second->getSymbol() << "'";
error(symbol->getLine(), strstr.str().c_str(), name.c_str());
}
}
}
}
void ValidateOutputs::error(TSourceLoc loc, const char *reason, const char* token)
{
mSink.prefix(EPrefixError);
mSink.location(loc);
mSink << "'" << token << "' : " << reason << "\n";
mNumErrors++;
}