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
|
|
@ -433,6 +433,108 @@ const TFunction* TParseContextBase::selectFunction(
|
|||
return incumbent;
|
||||
}
|
||||
|
||||
//
|
||||
// Look at a '.' field selector string and change it into numerical selectors
|
||||
// for a vector or scalar.
|
||||
//
|
||||
// Always return some form of swizzle, so the result is always usable.
|
||||
//
|
||||
void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize,
|
||||
TSwizzleSelectors<TVectorSelector>& selector)
|
||||
{
|
||||
// Too long?
|
||||
if (compString.size() > TSwizzleSelectors<TVectorSelector>::maxSelectors)
|
||||
error(loc, "vector swizzle too long", compString.c_str(), "");
|
||||
|
||||
// Use this to test that all swizzle characters are from the same swizzle-namespace-set
|
||||
enum {
|
||||
exyzw,
|
||||
ergba,
|
||||
estpq,
|
||||
} fieldSet[TSwizzleSelectors<TVectorSelector>::maxSelectors];
|
||||
|
||||
// Decode the swizzle string.
|
||||
int size = std::min(TSwizzleSelectors<TVectorSelector>::maxSelectors, (int)compString.size());
|
||||
for (int i = 0; i < size; ++i) {
|
||||
switch (compString[i]) {
|
||||
case 'x':
|
||||
selector.push_back(0);
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'r':
|
||||
selector.push_back(0);
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 's':
|
||||
selector.push_back(0);
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
|
||||
case 'y':
|
||||
selector.push_back(1);
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'g':
|
||||
selector.push_back(1);
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 't':
|
||||
selector.push_back(1);
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
|
||||
case 'z':
|
||||
selector.push_back(2);
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'b':
|
||||
selector.push_back(2);
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 'p':
|
||||
selector.push_back(2);
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
selector.push_back(3);
|
||||
fieldSet[i] = exyzw;
|
||||
break;
|
||||
case 'a':
|
||||
selector.push_back(3);
|
||||
fieldSet[i] = ergba;
|
||||
break;
|
||||
case 'q':
|
||||
selector.push_back(3);
|
||||
fieldSet[i] = estpq;
|
||||
break;
|
||||
|
||||
default:
|
||||
error(loc, "unknown swizzle selection", compString.c_str(), "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Additional error checking.
|
||||
for (int i = 0; i < selector.size(); ++i) {
|
||||
if (selector[i] >= vecSize) {
|
||||
error(loc, "vector swizzle selection out of range", compString.c_str(), "");
|
||||
selector.resize(i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (i > 0 && fieldSet[i] != fieldSet[i-1]) {
|
||||
error(loc, "vector swizzle selectors not from the same set", compString.c_str(), "");
|
||||
selector.resize(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure it is valid.
|
||||
if (selector.size() == 0)
|
||||
selector.push_back(0);
|
||||
}
|
||||
|
||||
//
|
||||
// Make the passed-in variable information become a member of the
|
||||
// global uniform block. If this doesn't exist yet, make it.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue