Front-ends: Non-functional: Rationalize vector and matrix swizzles.
This reduces code duplication in a few ways, and better encapsulates vector swizzle representation.
This commit is contained in:
parent
0a76a1870c
commit
c142c88967
12 changed files with 269 additions and 340 deletions
|
|
@ -258,106 +258,6 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sub- vector and matrix fields
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Look at a '.' field selector string and change it into offsets
|
||||
// for a vector or scalar
|
||||
//
|
||||
// Returns true if there is no error.
|
||||
//
|
||||
bool TParseContext::parseVectorFields(const TSourceLoc& loc, const TString& compString, int vecSize, TVectorFields& fields)
|
||||
{
|
||||
fields.num = (int)compString.size();
|
||||
if (fields.num > 4) {
|
||||
error(loc, "illegal vector field selection", compString.c_str(), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
enum {
|
||||
exyzw,
|
||||
ergba,
|
||||
estpq,
|
||||
} fieldSet[4];
|
||||
|
||||
for (int i = 0; i < fields.num; ++i) {
|
||||
switch (compString[i]) {
|
||||
case 'x':
|
||||
fields.offsets[i] = 0;
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'r':
|
||||
fields.offsets[i] = 0;
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 's':
|
||||
fields.offsets[i] = 0;
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
case 'y':
|
||||
fields.offsets[i] = 1;
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'g':
|
||||
fields.offsets[i] = 1;
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 't':
|
||||
fields.offsets[i] = 1;
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
case 'z':
|
||||
fields.offsets[i] = 2;
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'b':
|
||||
fields.offsets[i] = 2;
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 'p':
|
||||
fields.offsets[i] = 2;
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
fields.offsets[i] = 3;
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'a':
|
||||
fields.offsets[i] = 3;
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 'q':
|
||||
fields.offsets[i] = 3;
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
default:
|
||||
error(loc, "illegal vector field selection", compString.c_str(), "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < fields.num; ++i) {
|
||||
if (fields.offsets[i] >= vecSize) {
|
||||
error(loc, "vector field selection out of range", compString.c_str(), "");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
if (fieldSet[i] != fieldSet[i-1]) {
|
||||
error(loc, "illegal - vector component fields not from the same set", compString.c_str(), "");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing a variable identifier in the grammar.
|
||||
//
|
||||
|
|
@ -781,17 +681,14 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
|
||||
}
|
||||
|
||||
TVectorFields fields;
|
||||
if (! parseVectorFields(loc, field, base->getVectorSize(), fields)) {
|
||||
fields.num = 1;
|
||||
fields.offsets[0] = 0;
|
||||
}
|
||||
TSwizzleSelectors<TVectorSelector> selectors;
|
||||
parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
|
||||
|
||||
if (base->isScalar()) {
|
||||
if (fields.num == 1)
|
||||
if (selectors.size() == 1)
|
||||
return result;
|
||||
else {
|
||||
TType type(base->getBasicType(), EvqTemporary, fields.num);
|
||||
TType type(base->getBasicType(), EvqTemporary, selectors.size());
|
||||
// Swizzle operations propagate specialization-constantness
|
||||
if (base->getQualifier().isSpecConstant())
|
||||
type.getQualifier().makeSpecConstant();
|
||||
|
|
@ -800,17 +697,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||
}
|
||||
|
||||
if (base->getType().getQualifier().isFrontEndConstant())
|
||||
result = intermediate.foldSwizzle(base, fields, loc);
|
||||
result = intermediate.foldSwizzle(base, selectors, loc);
|
||||
else {
|
||||
if (fields.num == 1) {
|
||||
TIntermTyped* index = intermediate.addConstantUnion(fields.offsets[0], loc);
|
||||
if (selectors.size() == 1) {
|
||||
TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
|
||||
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
|
||||
} else {
|
||||
TString vectorString = field;
|
||||
TIntermTyped* index = intermediate.addSwizzle(fields, loc);
|
||||
TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
|
||||
result = intermediate.addIndex(EOpVectorSwizzle, base, index, loc);
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, (int)vectorString.size()));
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
|
||||
}
|
||||
// Swizzle operations propagate specialization-constantness
|
||||
if (base->getType().getQualifier().isSpecConstant())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue