Clean up/resolve a bunch of TODO, which included implementing pixel_center_integer and origin_upper_left and adjusting what versions see legacy texturing names.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23874 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
c36e1d8e51
commit
8ec55cdcd2
28 changed files with 374 additions and 160 deletions
|
|
@ -297,7 +297,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||
// but not always.
|
||||
int resultSize;
|
||||
switch (op) {
|
||||
// TODO: functionality: constant folding: finish listing exceptions to size here
|
||||
// TODO: 3.0 functionality: constant folding: finish listing exceptions to size here
|
||||
case EOpDeterminant:
|
||||
case EOpAny:
|
||||
case EOpAll:
|
||||
|
|
@ -481,7 +481,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||
break;
|
||||
}
|
||||
|
||||
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
|
||||
// TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
|
||||
|
||||
case EOpSinh:
|
||||
case EOpCosh:
|
||||
|
|
@ -665,7 +665,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||
|
||||
switch (aggrNode->getOp()) {
|
||||
|
||||
// TODO: Functionality: constant folding: the rest of the ops have to be fleshed out
|
||||
// TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
|
||||
|
||||
case EOpModf:
|
||||
case EOpDistance:
|
||||
|
|
|
|||
|
|
@ -621,8 +621,9 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
// (Per-stage functions below.)
|
||||
//
|
||||
if ((profile == EEsProfile && version == 100) ||
|
||||
profile == ECompatibilityProfile ||
|
||||
version < 150) {
|
||||
profile == ECompatibilityProfile ||
|
||||
(profile == ECoreProfile && version < 420) ||
|
||||
profile == ENoProfile) {
|
||||
commonBuiltins.append(
|
||||
"vec4 texture2D(sampler2D, vec2);"
|
||||
|
||||
|
|
@ -634,8 +635,9 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
"\n");
|
||||
}
|
||||
|
||||
if (profile != EEsProfile &&
|
||||
(profile == ECompatibilityProfile || version < 150)) {
|
||||
if ( profile == ECompatibilityProfile ||
|
||||
(profile == ECoreProfile && version < 420) ||
|
||||
profile == ENoProfile) {
|
||||
commonBuiltins.append(
|
||||
"vec4 texture1D(sampler1D, float);"
|
||||
|
||||
|
|
@ -651,8 +653,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
"vec4 shadow2DProj(sampler2DShadow, vec4);"
|
||||
|
||||
"\n");
|
||||
|
||||
// TODO: functionality: non-ES legacy texturing for Lod, others?
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -686,6 +686,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
//============================================================================
|
||||
//
|
||||
// Prototypes for built-in functions seen by vertex shaders only.
|
||||
// (Except legacy lod functions, where it depends which release they are
|
||||
// vertex only.)
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
|
|
@ -698,8 +700,16 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
//
|
||||
// Original-style texture Functions with lod.
|
||||
//
|
||||
if (profile != EEsProfile || version == 100) {
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
TString* s;
|
||||
if (version < 130)
|
||||
s = &stageBuiltins[EShLangVertex];
|
||||
else
|
||||
s = &commonBuiltins;
|
||||
if ((profile == EEsProfile && version == 100) ||
|
||||
profile == ECompatibilityProfile ||
|
||||
(profile == ECoreProfile && version < 420) ||
|
||||
profile == ENoProfile) {
|
||||
s->append(
|
||||
"vec4 texture2DLod(sampler2D, vec2, float);"
|
||||
"vec4 texture2DProjLod(sampler2D, vec3, float);"
|
||||
"vec4 texture2DProjLod(sampler2D, vec4, float);"
|
||||
|
|
@ -707,8 +717,10 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
|
||||
"\n");
|
||||
}
|
||||
if (profile != EEsProfile && version > 100) {
|
||||
stageBuiltins[EShLangVertex].append(
|
||||
if ( profile == ECompatibilityProfile ||
|
||||
(profile == ECoreProfile && version < 420) ||
|
||||
profile == ENoProfile) {
|
||||
s->append(
|
||||
"vec4 texture1DLod(sampler1D, float, float);"
|
||||
"vec4 texture1DProjLod(sampler1D, vec2, float);"
|
||||
"vec4 texture1DProjLod(sampler1D, vec4, float);"
|
||||
|
|
@ -982,7 +994,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
if (version >= 430) {
|
||||
stageBuiltins[EShLangCompute].append(
|
||||
"in uvec3 gl_NumWorkGroups;"
|
||||
// TODO: compute shader: constant with no initializer "const uvec3 gl_WorkGroupSize;"
|
||||
// TODO: 4.3 functionality: compute shader: constant with no initializer "const uvec3 gl_WorkGroupSize;"
|
||||
|
||||
"in uvec3 gl_WorkGroupID;"
|
||||
"in uvec3 gl_LocalInvocationID;"
|
||||
|
|
@ -1184,7 +1196,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
//============================================================================
|
||||
|
||||
if (version >= 400) {
|
||||
// TODO: tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
|
||||
// TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
|
||||
stageBuiltins[EShLangTessControl].append(
|
||||
"const int gl_MaxPatchVertices = 32;"
|
||||
);
|
||||
|
|
@ -1242,7 +1254,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
|
|||
//============================================================================
|
||||
|
||||
if (version >= 400) {
|
||||
// TODO: tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
|
||||
// TODO: 4.0 tessellation: gl_MaxPatchVertices below needs to move to resources mechanism
|
||||
stageBuiltins[EShLangTessEvaluation].append(
|
||||
"const int gl_MaxPatchVertices = 32;"
|
||||
);
|
||||
|
|
@ -2084,6 +2096,9 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||
//
|
||||
switch(language) {
|
||||
case EShLangVertex:
|
||||
case EShLangTessControl:
|
||||
case EShLangTessEvaluation:
|
||||
case EShLangGeometry:
|
||||
SpecialQualifier("gl_Position", EvqPosition, symbolTable);
|
||||
SpecialQualifier("gl_PointSize", EvqPointSize, symbolTable);
|
||||
SpecialQualifier("gl_ClipVertex", EvqClipVertex, symbolTable);
|
||||
|
|
@ -2091,12 +2106,6 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||
SpecialQualifier("gl_InstanceID", EvqInstanceId, symbolTable);
|
||||
break;
|
||||
|
||||
case EShLangTessControl:
|
||||
case EShLangTessEvaluation:
|
||||
case EShLangGeometry:
|
||||
// TODO: desktop functionality: support new stages: note it is probably best to stop adding/using special qualifiers, given the passthrough nature of these stages
|
||||
break;
|
||||
|
||||
case EShLangFragment:
|
||||
SpecialQualifier("gl_FrontFacing", EvqFace, symbolTable);
|
||||
SpecialQualifier("gl_FragCoord", EvqFragCoord, symbolTable);
|
||||
|
|
@ -2106,7 +2115,7 @@ void IdentifyBuiltIns(int version, EProfile profile, EShLanguage language, TSymb
|
|||
break;
|
||||
|
||||
case EShLangCompute:
|
||||
// TODO: desktop functionality: support new stages
|
||||
// TODO: 4.3 desktop functionality: compute special variables
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -867,7 +867,7 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag
|
|||
//
|
||||
|
||||
//if (ftransformUsed) {
|
||||
// TODO: desktop: track ftransform() usage
|
||||
// TODO: 1.1 lowering functionality: track ftransform() usage
|
||||
// addSymbolLinkageNode(root, symbolTable, "gl_Vertex");
|
||||
// addSymbolLinkageNode(root, symbolTable, "gl_ModelViewProjectionMatrix");
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
|
|||
contextPragma(true, false), loopNestingLevel(0), structNestingLevel(0),
|
||||
tokensBeforeEOF(false), currentScanner(0),
|
||||
numErrors(0), parsingBuiltins(pb), afterEOF(false),
|
||||
anyIndexLimits(false)
|
||||
anyIndexLimits(false), fragCoordUsedBeforeRedeclaration(false)
|
||||
{
|
||||
// ensure we always have a linkage node, even if empty, to simplify tree topology algorithms
|
||||
linkage = new TIntermAggregate;
|
||||
|
|
@ -412,11 +412,15 @@ TIntermTyped* TParseContext::handleVariable(TSourceLoc loc, TSymbol* symbol, TSt
|
|||
if (variable->getType().getQualifier().storage == EvqConst)
|
||||
node = intermediate.addConstantUnion(variable->getConstArray(), variable->getType(), loc);
|
||||
else {
|
||||
// break sharing with built-ins
|
||||
TType* type;
|
||||
if (variable->isReadOnly()) {
|
||||
type = new TType;
|
||||
// break sharing with built-ins
|
||||
type->deepCopy(variable->getType());
|
||||
|
||||
// track use of unredeclared gl_FragCoord
|
||||
if (variable->getName() == "gl_FragCoord")
|
||||
fragCoordUsedBeforeRedeclaration = true;
|
||||
} else
|
||||
type = &variable->getWritableType();
|
||||
node = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), *type, loc);
|
||||
|
|
@ -473,6 +477,8 @@ TIntermTyped* TParseContext::handleBracketDereference(TSourceLoc loc, TIntermTyp
|
|||
error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable");
|
||||
if (base->getBasicType() == EbtBlock)
|
||||
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing block array");
|
||||
else if (language == EShLangFragment && base->getQualifier().storage == EvqVaryingOut)
|
||||
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader ouput array");
|
||||
else if (base->getBasicType() == EbtSampler && version >= 130) {
|
||||
const char* explanation = "variable indexing sampler array";
|
||||
requireProfile(base->getLoc(), ECoreProfile | ECompatibilityProfile, explanation);
|
||||
|
|
@ -923,7 +929,7 @@ TIntermTyped* TParseContext::handleFunctionCall(TSourceLoc loc, TFunction* fnCal
|
|||
}
|
||||
|
||||
// generic error recovery
|
||||
// TODO: coding: localize all the error recoveries that look like this
|
||||
// TODO: simplification: localize all the error recoveries that look like this, and taking type into account to reduce cascades
|
||||
if (result == 0) {
|
||||
TConstUnionArray unionArray(1);
|
||||
unionArray[0].setDConst(0.0);
|
||||
|
|
@ -1895,19 +1901,18 @@ void TParseContext::declareArray(TSourceLoc loc, TString& identifier, const TTyp
|
|||
|
||||
void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int index)
|
||||
{
|
||||
TIntermSymbol* symbolNode = node->getAsSymbolNode();
|
||||
if (! symbolNode) {
|
||||
// TODO: functionality: unsized arrays: handle members of blocks
|
||||
return;
|
||||
}
|
||||
|
||||
// maybe there is nothing to do...
|
||||
// TODO: functionality: unsized arrays: is the node sharing the array type with the symbol table?
|
||||
if (symbolNode->getType().getMaxArraySize() > index)
|
||||
TIntermTyped* typedNode = node->getAsTyped();
|
||||
if (typedNode->getType().getMaxArraySize() > index)
|
||||
return;
|
||||
|
||||
// something to do...
|
||||
|
||||
// TODO: 1.50 linker: unsized block member array: 'node' could be an expression for a dereference
|
||||
TIntermSymbol* symbolNode = node->getAsSymbolNode();
|
||||
if (! symbolNode)
|
||||
return;
|
||||
|
||||
TSymbol* symbol = symbolTable.find(symbolNode->getName());
|
||||
assert(symbol);
|
||||
if (symbol == 0)
|
||||
|
|
@ -1919,7 +1924,7 @@ void TParseContext::updateMaxArraySize(TSourceLoc loc, TIntermNode *node, int in
|
|||
}
|
||||
|
||||
// For read-only built-ins, add a new variable for holding the maximum array size of an implicitly-sized shared array.
|
||||
// TODO: functionality: unsized arrays: is this new array type shared with the node?
|
||||
// TODO: desktop linker: unsized arrays: is this new array type shared with the node?
|
||||
if (symbol->isReadOnly()) {
|
||||
symbol = symbolTable.copyUp(symbol);
|
||||
|
||||
|
|
@ -1959,7 +1964,7 @@ void TParseContext::nonInitConstCheck(TSourceLoc loc, TString& identifier, TType
|
|||
//
|
||||
// Returns a redeclared and type-modified variable if a redeclarated occurred.
|
||||
//
|
||||
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, bool& newDeclaration)
|
||||
TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType, bool& newDeclaration)
|
||||
{
|
||||
if (profile == EEsProfile || ! builtInName(identifier) || symbolTable.atBuiltInLevel())
|
||||
return 0;
|
||||
|
|
@ -2003,7 +2008,53 @@ TSymbol* TParseContext::redeclareBuiltinVariable(TSourceLoc loc, const TString&
|
|||
}
|
||||
|
||||
// Now, modify the type of the copy, as per the type of the current redeclaration.
|
||||
// TODO: functionality: verify type change is allowed and make the change in type
|
||||
|
||||
TQualifier& symbolQualifier = symbol->getWritableType().getQualifier();
|
||||
if (identifier == "gl_FrontColor" ||
|
||||
identifier == "gl_BackColor" ||
|
||||
identifier == "gl_FrontSecondaryColor" ||
|
||||
identifier == "gl_BackSecondaryColor" ||
|
||||
identifier == "gl_SecondaryColor" ||
|
||||
identifier == "gl_Color") {
|
||||
symbolQualifier.flat = qualifier.flat;
|
||||
symbolQualifier.smooth = qualifier.smooth;
|
||||
symbolQualifier.nopersp = qualifier.nopersp;
|
||||
if (qualifier.hasLayout())
|
||||
error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str());
|
||||
if (qualifier.isMemory() || qualifier.isAuxiliary() || symbol->getType().getQualifier().storage != qualifier.storage)
|
||||
error(loc, "cannot change storage, memory, or auxiliary qualification of", "redeclaration", symbol->getName().c_str());
|
||||
} else if (identifier == "gl_TexCoord" ||
|
||||
identifier == "gl_ClipDistance") {
|
||||
if (qualifier.hasLayout() || qualifier.isMemory() || qualifier.isAuxiliary() ||
|
||||
qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
||||
symbolQualifier.storage != qualifier.storage)
|
||||
error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str());
|
||||
} else if (identifier == "gl_FragCoord") {
|
||||
if (fragCoordUsedBeforeRedeclaration)
|
||||
error(loc, "cannot redeclare after use", "gl_FragCoord", "");
|
||||
// Note: this did not catch the case of 1) declare, 2) use, 3) declare again, because the "use" was of a redeclaration, and so didn't set fragCoordUsedBeforeRedeclaration.
|
||||
// (and that's what the rules are too, as long as #3 matches #1)
|
||||
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
||||
qualifier.isMemory() || qualifier.isAuxiliary())
|
||||
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
||||
if (identifier == "gl_FragCoord" && qualifier.storage != EvqVaryingIn)
|
||||
error(loc, "cannot change input storage qualification of", "redeclaration", symbol->getName().c_str());
|
||||
if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() ||
|
||||
publicType.originUpperLeft != intermediate.getOriginUpperLeft()))
|
||||
error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str());
|
||||
if (publicType.pixelCenterInteger)
|
||||
intermediate.setPixelCenterInteger();
|
||||
if (publicType.originUpperLeft)
|
||||
intermediate.setOriginUpperLeft();
|
||||
} else if (identifier == "gl_FragDepth") {
|
||||
if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat ||
|
||||
qualifier.isMemory() || qualifier.isAuxiliary())
|
||||
error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str());
|
||||
if (qualifier.storage != EvqVaryingOut)
|
||||
error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str());
|
||||
// TODO 4.2: gl_FragDepth redeclaration
|
||||
}
|
||||
// TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
|
@ -2062,7 +2113,7 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
|
|||
if (language == EShLangGeometry && block->getType().isArray() && block->getType().getQualifier().storage == EvqVaryingIn)
|
||||
inputArraySymbolResizeList.push_back(block);
|
||||
|
||||
// TODO: semantics: block redeclaration: instance array size matching?
|
||||
// TODO: SSO/4.10 semantics: block redeclaration: instance array size matching
|
||||
|
||||
// Edit and error check the container against the redeclaration
|
||||
// - remove unused members
|
||||
|
|
@ -2085,7 +2136,7 @@ bool TParseContext::redeclareBuiltinBlock(TSourceLoc loc, TTypeList& typeList, c
|
|||
else
|
||||
member = type.getStruct()->erase(member);
|
||||
|
||||
// TODO: semantics: block redeclaration: member type/qualifier matching
|
||||
// TODO: SSO/4.10 semantics: block redeclaration: member type/qualifier matching
|
||||
}
|
||||
|
||||
symbolTable.insert(*block);
|
||||
|
|
@ -2306,36 +2357,48 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||
}
|
||||
if (language == EShLangGeometry || language == EShLangTessEvaluation) {
|
||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||
publicType.geometry = ElgTriangles;
|
||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry) {
|
||||
if (id == TQualifier::getGeometryString(ElgPoints)) {
|
||||
publicType.geometry = ElgPoints;
|
||||
publicType.shaderQualifiers.geometry = ElgPoints;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLineStrip)) {
|
||||
publicType.geometry = ElgLineStrip;
|
||||
publicType.shaderQualifiers.geometry = ElgLineStrip;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLines)) {
|
||||
publicType.geometry = ElgLines;
|
||||
publicType.shaderQualifiers.geometry = ElgLines;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
|
||||
publicType.geometry = ElgLinesAdjacency;
|
||||
publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
|
||||
publicType.geometry = ElgTrianglesAdjacency;
|
||||
publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
|
||||
publicType.geometry = ElgTriangleStrip;
|
||||
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// TODO: tessellation evaluation
|
||||
// TODO: 4.0 tessellation evaluation
|
||||
}
|
||||
}
|
||||
if (language == EShLangFragment) {
|
||||
if (id == "origin_upper_left") {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left");
|
||||
publicType.shaderQualifiers.originUpperLeft = true;
|
||||
return;
|
||||
}
|
||||
if (id == "pixel_center_integer") {
|
||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer");
|
||||
publicType.shaderQualifiers.pixelCenterInteger = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
error(loc, "unrecognized layout identifier, or qualifier requires assignemnt (e.g., binding = 4)", id.c_str(), "");
|
||||
|
|
@ -2345,6 +2408,12 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||
// type information for error checking.
|
||||
void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType, TString& id, int value)
|
||||
{
|
||||
if (value < 0) {
|
||||
error(loc, "cannot be negative", "layout qualifier value", "");
|
||||
return;
|
||||
// TODO: 4.4: test the above, once expressions are allowed; until then, can't even express a negative location
|
||||
}
|
||||
|
||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||
if (id == "location") {
|
||||
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "location");
|
||||
|
|
@ -2367,11 +2436,11 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||
if (language == EShLangGeometry) {
|
||||
if (id == "invocations") {
|
||||
profileRequires(loc, ECompatibilityProfile | ECoreProfile, 400, 0, "invocations");
|
||||
publicType.invocations = value;
|
||||
publicType.shaderQualifiers.invocations = value;
|
||||
return;
|
||||
}
|
||||
if (id == "max_vertices") {
|
||||
publicType.maxVertices = value;
|
||||
publicType.shaderQualifiers.maxVertices = value;
|
||||
return;
|
||||
}
|
||||
if (id == "stream") {
|
||||
|
|
@ -2380,16 +2449,13 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||
}
|
||||
}
|
||||
error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
|
||||
|
||||
// TODO: semantics: error check: make sure locations are non-overlapping across the whole stage
|
||||
// TODO: semantics: error check: output arrays can only be indexed with a constant (es 300)
|
||||
}
|
||||
|
||||
//
|
||||
// Merge characteristics of the 'src' qualifier into the 'dst', at the TPublicType level,
|
||||
// which means for layout-qualifier information not kept per qualifier.
|
||||
//
|
||||
void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TPublicType& dst, const TPublicType& src)
|
||||
void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TShaderQualifiers& dst, const TShaderQualifiers& src)
|
||||
{
|
||||
if (src.geometry != ElgNone)
|
||||
dst.geometry = src.geometry;
|
||||
|
|
@ -2397,6 +2463,10 @@ void TParseContext::mergeShaderLayoutQualifiers(TSourceLoc loc, TPublicType& dst
|
|||
dst.invocations = src.invocations;
|
||||
if (src.maxVertices != 0)
|
||||
dst.maxVertices = src.maxVertices;
|
||||
if (src.pixelCenterInteger)
|
||||
dst.pixelCenterInteger = src.pixelCenterInteger;
|
||||
if (src.originUpperLeft)
|
||||
dst.originUpperLeft = src.originUpperLeft;
|
||||
}
|
||||
|
||||
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone
|
||||
|
|
@ -2464,11 +2534,11 @@ void TParseContext::layoutTypeCheck(TSourceLoc loc, const TSymbol& symbol)
|
|||
// an array of size N, all elements of the array from binding through binding + N – 1 must be within this
|
||||
// range."
|
||||
//
|
||||
// TODO: binding error checking against limits, arrays
|
||||
// TODO: 4.2 binding limits: binding error checking against limits, arrays
|
||||
//
|
||||
if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock)
|
||||
error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", "");
|
||||
// TODO: atomic counter functionality: include in test above
|
||||
// TODO: 4.2 functionality: atomic counter: include in test above
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2527,15 +2597,15 @@ void TParseContext::layoutQualifierCheck(TSourceLoc loc, const TQualifier& quali
|
|||
}
|
||||
|
||||
// For places that can't have shader-level layout qualifiers
|
||||
void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TPublicType& publicType)
|
||||
void TParseContext::checkNoShaderLayouts(TSourceLoc loc, const TShaderQualifiers& shaderQualifiers)
|
||||
{
|
||||
const char* message = "can only apply to a standalone qualifier";
|
||||
|
||||
if (publicType.geometry != ElgNone)
|
||||
error(loc, message, TQualifier::getGeometryString(publicType.geometry), "");
|
||||
if (publicType.invocations > 0)
|
||||
if (shaderQualifiers.geometry != ElgNone)
|
||||
error(loc, message, TQualifier::getGeometryString(shaderQualifiers.geometry), "");
|
||||
if (shaderQualifiers.invocations > 0)
|
||||
error(loc, message, "invocations", "");
|
||||
if (publicType.maxVertices > 0)
|
||||
if (shaderQualifiers.maxVertices > 0)
|
||||
error(loc, message, "max_vertices", "");
|
||||
}
|
||||
|
||||
|
|
@ -2658,7 +2728,7 @@ const TFunction* TParseContext::findFunction400(TSourceLoc loc, const TFunction&
|
|||
// Returns a subtree node that computes an initializer, if needed.
|
||||
// Returns 0 if there is no code to execute for initialization.
|
||||
//
|
||||
TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
|
||||
TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier, const TPublicType& publicType, TArraySizes* arraySizes, TIntermTyped* initializer)
|
||||
{
|
||||
TType type(publicType);
|
||||
|
||||
|
|
@ -2672,9 +2742,12 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||
if (! type.getQualifier().hasStream() && language == EShLangGeometry && type.getQualifier().storage == EvqVaryingOut)
|
||||
type.getQualifier().layoutStream = globalOutputDefaults.layoutStream;
|
||||
|
||||
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
|
||||
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
|
||||
|
||||
// Check for redeclaration of built-ins and/or attempting to declare a reserved name
|
||||
bool newDeclaration = false; // true if a new entry gets added to the symbol table
|
||||
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, newDeclaration);
|
||||
TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers, newDeclaration);
|
||||
if (! symbol)
|
||||
reservedErrorCheck(loc, identifier);
|
||||
|
||||
|
|
@ -2698,6 +2771,8 @@ TIntermNode* TParseContext::declareVariable(TSourceLoc loc, TString& identifier,
|
|||
// non-array case
|
||||
if (! symbol)
|
||||
symbol = declareNonArray(loc, identifier, type, newDeclaration);
|
||||
else if (type != symbol->getType())
|
||||
error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
|
||||
}
|
||||
|
||||
// Deal with initializer
|
||||
|
|
@ -2859,7 +2934,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
|
|||
arrayType.setArraySizes(type);
|
||||
arrayType.changeArraySize(initList->getSequence().size());
|
||||
TType elementType;
|
||||
elementType.shallowCopy(arrayType); // TODO: arrays of arrays: combine this with deref.
|
||||
elementType.shallowCopy(arrayType); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
||||
elementType.dereference();
|
||||
for (size_t i = 0; i < initList->getSequence().size(); ++i) {
|
||||
initList->getSequence()[i] = convertInitializerList(loc, elementType, initList->getSequence()[i]->getAsTyped());
|
||||
|
|
@ -2884,7 +2959,7 @@ TIntermTyped* TParseContext::convertInitializerList(TSourceLoc loc, const TType&
|
|||
return 0;
|
||||
}
|
||||
TType vectorType;
|
||||
vectorType.shallowCopy(type); // TODO: arrays of arrays: combine this with deref.
|
||||
vectorType.shallowCopy(type); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
||||
vectorType.dereference();
|
||||
for (int i = 0; i < type.getMatrixCols(); ++i) {
|
||||
initList->getSequence()[i] = convertInitializerList(loc, vectorType, initList->getSequence()[i]->getAsTyped());
|
||||
|
|
@ -2925,7 +3000,7 @@ TIntermTyped* TParseContext::addConstructor(TSourceLoc loc, TIntermNode* node, c
|
|||
TType elementType;
|
||||
elementType.shallowCopy(type);
|
||||
if (type.isArray())
|
||||
elementType.dereference(); // TODO: arrays of arrays: combine this with shallowCopy
|
||||
elementType.dereference(); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
||||
|
||||
bool singleArg;
|
||||
if (aggrNode) {
|
||||
|
|
@ -3280,43 +3355,43 @@ void TParseContext::addQualifierToExisting(TSourceLoc loc, TQualifier qualifier,
|
|||
//
|
||||
void TParseContext::updateStandaloneQualifierDefaults(TSourceLoc loc, const TPublicType& publicType)
|
||||
{
|
||||
if (publicType.maxVertices) {
|
||||
if (! intermediate.setMaxVertices(publicType.maxVertices))
|
||||
if (publicType.shaderQualifiers.maxVertices) {
|
||||
if (! intermediate.setMaxVertices(publicType.shaderQualifiers.maxVertices))
|
||||
error(loc, "cannot change previously set layout value", "max_vertices", "");
|
||||
}
|
||||
if (publicType.invocations) {
|
||||
if (! intermediate.setInvocations(publicType.invocations))
|
||||
if (publicType.shaderQualifiers.invocations) {
|
||||
if (! intermediate.setInvocations(publicType.shaderQualifiers.invocations))
|
||||
error(loc, "cannot change previously set layout value", "invocations", "");
|
||||
}
|
||||
if (publicType.geometry != ElgNone) {
|
||||
if (publicType.shaderQualifiers.geometry != ElgNone) {
|
||||
if (publicType.qualifier.storage == EvqVaryingIn) {
|
||||
switch (publicType.geometry) {
|
||||
switch (publicType.shaderQualifiers.geometry) {
|
||||
case ElgPoints:
|
||||
case ElgLines:
|
||||
case ElgLinesAdjacency:
|
||||
case ElgTriangles:
|
||||
case ElgTrianglesAdjacency:
|
||||
if (intermediate.setInputPrimitive(publicType.geometry))
|
||||
if (intermediate.setInputPrimitive(publicType.shaderQualifiers.geometry))
|
||||
checkInputArrayConsistency(loc);
|
||||
else
|
||||
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
error(loc, "cannot change previously set input primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
|
||||
break;
|
||||
default:
|
||||
error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
error(loc, "does not apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
|
||||
}
|
||||
} else if (publicType.qualifier.storage == EvqVaryingOut) {
|
||||
switch (publicType.geometry) {
|
||||
switch (publicType.shaderQualifiers.geometry) {
|
||||
case ElgPoints:
|
||||
case ElgLineStrip:
|
||||
case ElgTriangleStrip:
|
||||
if (! intermediate.setOutputPrimitive(publicType.geometry))
|
||||
error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
if (! intermediate.setOutputPrimitive(publicType.shaderQualifiers.geometry))
|
||||
error(loc, "cannot change previously set output primitive", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
|
||||
break;
|
||||
default:
|
||||
error(loc, "does not only apply to output", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
error(loc, "does not only apply to output", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
|
||||
}
|
||||
} else
|
||||
error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.geometry), "");
|
||||
error(loc, "cannot be used here", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), "");
|
||||
}
|
||||
|
||||
const TQualifier& qualifier = publicType.qualifier;
|
||||
|
|
@ -3472,7 +3547,7 @@ TIntermNode* TParseContext::addSwitch(TSourceLoc loc, TIntermTyped* expression,
|
|||
return switchNode;
|
||||
}
|
||||
|
||||
// TODO: constant folding: these should use a follow a fully folded model now, and probably move to Constant.cpp scheme.
|
||||
// TODO: simplification: constant folding: these should use a follow a fully folded model now, and probably move to Constant.cpp scheme.
|
||||
|
||||
//
|
||||
// This function returns the tree representation for the vector field(s) being accessed from a constant vector.
|
||||
|
|
@ -3552,7 +3627,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
|
|||
TIntermTyped* typedNode;
|
||||
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
|
||||
TType arrayElementType;
|
||||
arrayElementType.shallowCopy(node->getType()); // TODO: arrays of arrays: combine this with deref.
|
||||
arrayElementType.shallowCopy(node->getType()); // TODO: 4.3 simplification: arrays of arrays: combine this with deref.
|
||||
arrayElementType.dereference();
|
||||
|
||||
if (index >= node->getType().getArraySize() || index < 0) {
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ public:
|
|||
void precisionQualifierCheck(TSourceLoc, TPublicType&);
|
||||
void parameterSamplerCheck(TSourceLoc, TStorageQualifier qualifier, const TType& type);
|
||||
bool containsSampler(const TType& type);
|
||||
TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, bool& newDeclaration);
|
||||
TSymbol* redeclareBuiltinVariable(TSourceLoc, const TString&, const TQualifier&, const TShaderQualifiers&, bool& newDeclaration);
|
||||
bool redeclareBuiltinBlock(TSourceLoc, TTypeList& typeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes);
|
||||
void paramCheck(TSourceLoc, const TStorageQualifier&, TType* type);
|
||||
void nestedBlockCheck(TSourceLoc);
|
||||
|
|
@ -134,17 +134,17 @@ public:
|
|||
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&);
|
||||
void setLayoutQualifier(TSourceLoc, TPublicType&, TString&, int);
|
||||
void mergeShaderLayoutQualifiers(TSourceLoc, TPublicType& dst, const TPublicType& src);
|
||||
void mergeShaderLayoutQualifiers(TSourceLoc, TShaderQualifiers& dst, const TShaderQualifiers& src);
|
||||
void mergeObjectLayoutQualifiers(TSourceLoc, TQualifier& dest, const TQualifier& src);
|
||||
void layoutTypeCheck(TSourceLoc, const TSymbol&);
|
||||
void layoutQualifierCheck(TSourceLoc, const TQualifier&);
|
||||
void checkNoShaderLayouts(TSourceLoc, const TPublicType&);
|
||||
void checkNoShaderLayouts(TSourceLoc, const TShaderQualifiers&);
|
||||
|
||||
const TFunction* findFunction(TSourceLoc loc, const TFunction& call, bool& builtIn);
|
||||
const TFunction* findFunctionExact(TSourceLoc loc, const TFunction& call, bool& builtIn);
|
||||
const TFunction* findFunction120(TSourceLoc loc, const TFunction& call, bool& builtIn);
|
||||
const TFunction* findFunction400(TSourceLoc loc, const TFunction& call, bool& builtIn);
|
||||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
TIntermNode* declareVariable(TSourceLoc, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0);
|
||||
TIntermTyped* addConstructor(TSourceLoc, TIntermNode*, const TType&, TOperator);
|
||||
TIntermTyped* constructStruct(TIntermNode*, const TType&, int, TSourceLoc);
|
||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermNode*, TSourceLoc, bool subset);
|
||||
|
|
@ -241,7 +241,7 @@ protected:
|
|||
TIdSetType inductiveLoopIds;
|
||||
bool anyIndexLimits;
|
||||
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||
// TODO: desktop functionality: track use of gl_FragDepth before redeclaration
|
||||
bool fragCoordUsedBeforeRedeclaration;
|
||||
|
||||
//
|
||||
// Geometry shader input arrays:
|
||||
|
|
|
|||
|
|
@ -779,13 +779,13 @@ declaration
|
|||
}
|
||||
| type_qualifier IDENTIFIER SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$2.string);
|
||||
$$ = 0;
|
||||
}
|
||||
| type_qualifier IDENTIFIER identifier_list SEMICOLON {
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
$3->push_back($2.string);
|
||||
parseContext.addQualifierToExisting($1.loc, $1.qualifier, *$3);
|
||||
$$ = 0;
|
||||
|
|
@ -797,7 +797,7 @@ block_structure
|
|||
--parseContext.structNestingLevel;
|
||||
parseContext.blockName = $2.string;
|
||||
parseContext.pipeInOutFix($1.loc, $1.qualifier);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.currentBlockQualifier = $1.qualifier;
|
||||
$$.loc = $1.loc;
|
||||
$$.typeList = $5;
|
||||
|
|
@ -919,7 +919,7 @@ parameter_declaration
|
|||
if ($1.qualifier.precision != EpqNone)
|
||||
$$.param.type->getQualifier().precision = $1.qualifier.precision;
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
|
||||
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
|
||||
}
|
||||
|
|
@ -937,7 +937,7 @@ parameter_declaration
|
|||
if ($1.qualifier.precision != EpqNone)
|
||||
$$.param.type->getQualifier().precision = $1.qualifier.precision;
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.parameterSamplerCheck($2.loc, $1.qualifier.storage, *$$.param.type);
|
||||
parseContext.paramCheck($1.loc, $1.qualifier.storage, $$.param.type);
|
||||
}
|
||||
|
|
@ -1038,7 +1038,8 @@ fully_specified_type
|
|||
if ($2.arraySizes && parseContext.arrayQualifierError($2.loc, $1.qualifier))
|
||||
$2.arraySizes = 0;
|
||||
|
||||
parseContext.checkNoShaderLayouts($2.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($2.loc, $1.shaderQualifiers);
|
||||
parseContext.mergeShaderLayoutQualifiers($2.loc, $2.shaderQualifiers, $1.shaderQualifiers);
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
parseContext.precisionQualifierCheck($2.loc, $2);
|
||||
|
||||
|
|
@ -1095,7 +1096,7 @@ layout_qualifier_id_list
|
|||
}
|
||||
| layout_qualifier_id_list COMMA layout_qualifier_id {
|
||||
$$ = $1;
|
||||
parseContext.mergeShaderLayoutQualifiers($2.loc, $$, $3);
|
||||
parseContext.mergeShaderLayoutQualifiers($2.loc, $$.shaderQualifiers, $3.shaderQualifiers);
|
||||
parseContext.mergeObjectLayoutQualifiers($2.loc, $$.qualifier, $3.qualifier);
|
||||
}
|
||||
|
||||
|
|
@ -1134,7 +1135,7 @@ type_qualifier
|
|||
if ($$.basicType == EbtVoid)
|
||||
$$.basicType = $2.basicType;
|
||||
|
||||
parseContext.mergeShaderLayoutQualifiers($$.loc, $$, $2);
|
||||
parseContext.mergeShaderLayoutQualifiers($$.loc, $$.shaderQualifiers, $2.shaderQualifiers);
|
||||
parseContext.mergeQualifiers($$.loc, $$.qualifier, $2.qualifier, false);
|
||||
}
|
||||
;
|
||||
|
|
@ -1569,7 +1570,7 @@ type_specifier_nonarray
|
|||
$$.setMatrix(4, 4);
|
||||
}
|
||||
| ATOMIC_UINT {
|
||||
// TODO: 4.2 functionality: add type
|
||||
// TODO: 4.2 functionality: add atomic_uint type
|
||||
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
|
||||
$$.basicType = EbtInt;
|
||||
}
|
||||
|
|
@ -2051,7 +2052,7 @@ struct_declaration
|
|||
|
||||
$$ = $3;
|
||||
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1);
|
||||
parseContext.checkNoShaderLayouts($1.loc, $1.shaderQualifiers);
|
||||
parseContext.voidErrorCheck($2.loc, (*$3)[0].type->getFieldName(), $2.basicType);
|
||||
parseContext.mergeQualifiers($2.loc, $2.qualifier, $1.qualifier, true);
|
||||
parseContext.precisionQualifierCheck($2.loc, $2);
|
||||
|
|
|
|||
|
|
@ -585,6 +585,12 @@ void TIntermediate::outputTree(TInfoSink& infoSink)
|
|||
infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
|
||||
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
||||
}
|
||||
if (language == EShLangFragment) {
|
||||
if (pixelCenterInteger)
|
||||
infoSink.debug << "gl_FragCoord pixel center is integer\n";
|
||||
if (originUpperLeft)
|
||||
infoSink.debug << "gl_FragCoord origin is upper left\n";
|
||||
}
|
||||
|
||||
if (treeRoot == 0)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
|||
(profile == EEsProfile && unit.profile != EEsProfile))
|
||||
error(infoSink, "Cannot mix ES profile with non-ES profile shaders\n");
|
||||
|
||||
if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger)
|
||||
error(infoSink, "gl_FragCoord redeclarations must match across shaders\n");
|
||||
|
||||
if (unit.treeRoot == 0)
|
||||
return;
|
||||
|
||||
|
|
@ -101,7 +104,7 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
|||
//
|
||||
void TIntermediate::mergeBodies(TInfoSink& infoSink, TIntermSequence& globals, const TIntermSequence& unitGlobals)
|
||||
{
|
||||
// TODO: Performance: Processing in alphabetical order will be faster
|
||||
// TODO: link-time performance: Processing in alphabetical order will be faster
|
||||
|
||||
// Error check the global objects, not including the linker objects
|
||||
for (unsigned int child = 0; child < globals.size() - 1; ++child) {
|
||||
|
|
@ -157,8 +160,6 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
|||
//
|
||||
// This function only does one of intra- or cross-stage matching per call.
|
||||
//
|
||||
// TODO: Linker Functionality: this function is under active development
|
||||
//
|
||||
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
|
||||
{
|
||||
bool writeTypeComparison = false;
|
||||
|
|
@ -340,7 +341,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
|
|||
bool fragOutWithNoLocation = false;
|
||||
int numFragOut = 0;
|
||||
|
||||
// TODO: maps for location collision checking
|
||||
// TODO: linker functionality: location collision checking
|
||||
|
||||
TIntermSequence& linkObjects = findLinkerObjects();
|
||||
for (size_t i = 0; i < linkObjects.size(); ++i) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class TSymbol;
|
|||
class TIntermediate {
|
||||
public:
|
||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), treeRoot(0), profile(p), version(v), numMains(0), numErrors(0),
|
||||
invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone) { }
|
||||
invocations(0), maxVertices(0), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false) { }
|
||||
|
||||
void setVersion(int v) { version = v; }
|
||||
int getVersion() const { return version; }
|
||||
|
|
@ -129,6 +129,10 @@ public:
|
|||
outputPrimitive = p;
|
||||
return true;
|
||||
}
|
||||
void setOriginUpperLeft() { originUpperLeft = true; }
|
||||
bool getOriginUpperLeft() const { return originUpperLeft; }
|
||||
void setPixelCenterInteger() { pixelCenterInteger = true; }
|
||||
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
||||
|
||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||
void merge(TInfoSink&, TIntermediate&);
|
||||
|
|
@ -157,6 +161,8 @@ protected:
|
|||
int maxVertices;
|
||||
TLayoutGeometry inputPrimitive;
|
||||
TLayoutGeometry outputPrimitive;
|
||||
bool pixelCenterInteger;
|
||||
bool originUpperLeft;
|
||||
|
||||
// for detecting recursion: pair is <caller, callee>
|
||||
struct TCall {
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * ppToken)
|
|||
return '.';
|
||||
}
|
||||
case '/':
|
||||
// TODO: preprocessor: use the Scan.cpp comment scanner
|
||||
// TODO: preprocessor simplification: use the Scan.cpp comment scanner
|
||||
ch = pp->currentInput->getch(pp, pp->currentInput, ppToken);
|
||||
if (ch == '/') {
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ void TPpContext::RewindTokenStream(TokenStream *pTok)
|
|||
|
||||
int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken)
|
||||
{
|
||||
//TODO: PP: why is this different than byte_scan
|
||||
//TODO: preprocessor simplification: why is this different than byte_scan
|
||||
|
||||
char tokenText[TPpToken::maxTokenLength + 1];
|
||||
int ltoken, len;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue