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
@ -15,11 +15,9 @@ ERROR: 0:63: 'bitwise-or assign' : not supported for this version or the enabled
|
||||
ERROR: 0:63: 'assign' : cannot convert from 'temp bool' to 'temp float'
|
||||
ERROR: 0:79: ':' : wrong operand types: no operation ':' exists that takes a left-hand operand of type 'temp 4-component vector of float' and a right operand of type 'temp 4X4 matrix of float' (or there is no acceptable conversion)
|
||||
ERROR: 0:79: 'assign' : cannot convert from 'temp 4X4 matrix of float' to 'fragColor 4-component vector of float FragColor'
|
||||
ERROR: 0:82: 'xr' : illegal - vector component fields not from the same set
|
||||
ERROR: 0:83: 'xyxyx' : illegal vector field selection
|
||||
ERROR: 0:83: 'scalar swizzle' : not supported for this version or the enabled extensions
|
||||
ERROR: 0:83: 'xy' : vector field selection out of range
|
||||
ERROR: 0:84: 'z' : vector field selection out of range
|
||||
ERROR: 0:82: 'xr' : vector swizzle selectors not from the same set
|
||||
ERROR: 0:83: 'xyxyx' : vector swizzle too long
|
||||
ERROR: 0:84: 'z' : vector swizzle selection out of range
|
||||
ERROR: 0:85: 'assign' : l-value required
|
||||
ERROR: 0:91: 'int' : overloaded functions must have the same return type
|
||||
ERROR: 0:91: 'main' : function already has a body
|
||||
@ -52,7 +50,7 @@ ERROR: 0:191: 'shadow2DProjGradARB' : required extension not requested: GL_ARB_s
|
||||
ERROR: 0:209: 'shadow2DRectProjGradARB' : no matching overloaded function found
|
||||
ERROR: 0:209: 'assign' : cannot convert from 'const float' to 'temp 4-component vector of float'
|
||||
ERROR: 0:212: 'sampler2DRect' : Reserved word.
|
||||
ERROR: 53 compilation errors. No code generated.
|
||||
ERROR: 51 compilation errors. No code generated.
|
||||
|
||||
|
||||
Shader version: 120
|
||||
@ -251,10 +249,23 @@ ERROR: node is still EOpNull!
|
||||
0:82 'gl_FragColor' (fragColor 4-component vector of float FragColor)
|
||||
0:82 Constant:
|
||||
0:82 0 (const int)
|
||||
0:83 direct index (temp float)
|
||||
0:83 'gl_FragColor' (fragColor 4-component vector of float FragColor)
|
||||
0:83 Constant:
|
||||
0:83 0 (const int)
|
||||
0:83 vector swizzle (temp 2-component vector of float)
|
||||
0:83 vector swizzle (temp 4-component vector of float)
|
||||
0:83 'gl_FragColor' (fragColor 4-component vector of float FragColor)
|
||||
0:83 Sequence
|
||||
0:83 Constant:
|
||||
0:83 0 (const int)
|
||||
0:83 Constant:
|
||||
0:83 1 (const int)
|
||||
0:83 Constant:
|
||||
0:83 0 (const int)
|
||||
0:83 Constant:
|
||||
0:83 1 (const int)
|
||||
0:83 Sequence
|
||||
0:83 Constant:
|
||||
0:83 0 (const int)
|
||||
0:83 Constant:
|
||||
0:83 1 (const int)
|
||||
0:84 direct index (temp float)
|
||||
0:84 'centTexCoord' (centroid smooth in 2-component vector of float)
|
||||
0:84 Constant:
|
||||
|
@ -18,9 +18,9 @@ ERROR: 0:40: 'j' : undeclared identifier
|
||||
ERROR: 0:40: '=' : cannot convert from 'temp float' to 'temp int'
|
||||
ERROR: 0:44: 'jj' : undeclared identifier
|
||||
ERROR: 0:44: '=' : cannot convert from 'temp float' to 'temp int'
|
||||
ERROR: 0:54: 'y' : vector field selection out of range
|
||||
ERROR: 0:62: 'xxxxx' : illegal vector field selection
|
||||
ERROR: 0:63: 'xxy' : vector field selection out of range
|
||||
ERROR: 0:54: 'y' : vector swizzle selection out of range
|
||||
ERROR: 0:62: 'xxxxx' : vector swizzle too long
|
||||
ERROR: 0:63: 'xxy' : vector swizzle selection out of range
|
||||
ERROR: 0:66: 'binding' : cannot declare a default, include a type or full declaration
|
||||
ERROR: 0:69: 'location/component/index' : cannot declare a default, use a full declaration
|
||||
ERROR: 0:70: 'input block' : not supported in this stage: vertex
|
||||
@ -124,8 +124,10 @@ ERROR: node is still EOpNull!
|
||||
0:61 'smeared' (temp 3-component vector of float)
|
||||
0:61 Construct vec3 (temp 3-component vector of float)
|
||||
0:61 'f' (temp float)
|
||||
0:62 'f' (temp float)
|
||||
0:63 'f' (temp float)
|
||||
0:62 Construct vec4 (temp 4-component vector of float)
|
||||
0:62 'f' (temp float)
|
||||
0:63 Construct vec2 (temp 2-component vector of float)
|
||||
0:63 'f' (temp float)
|
||||
0:88 Function Definition: bar23444( (global void)
|
||||
0:88 Function Parameters:
|
||||
0:? Sequence
|
||||
|
@ -1,6 +1,8 @@
|
||||
cppComplexExpr.vert
|
||||
ERROR: 0:46: 'xyxwx' : illegal vector field selection
|
||||
ERROR: 0:46: 'xyxwx' : illegal vector field selection
|
||||
ERROR: 0:46: 'xyxwx' : vector swizzle too long
|
||||
ERROR: 0:46: 'xyxwx' : vector swizzle too long
|
||||
ERROR: 0:46: 'return' : cannot convert return value to function return type
|
||||
WARNING: 0:46: 'return' : type conversion on return values was not explicitly allowed until version 420
|
||||
ERROR: 0:66: '#define' : Macro redefined; different substitutions: BIG
|
||||
ERROR: 0:81: 'preprocessor evaluation' : bad expression
|
||||
ERROR: 0:81: '#if' : unexpected tokens following directive
|
||||
@ -47,7 +49,7 @@ ERROR: 0:0: 'preprocessor evaluation' : division by 0
|
||||
ERROR: 0:3: 'preprocessor evaluation' : bad expression
|
||||
ERROR: 0:3: 'preprocessor evaluation' : division by 0
|
||||
ERROR: 0:10001: '' : missing #endif
|
||||
ERROR: 48 compilation errors. No code generated.
|
||||
ERROR: 49 compilation errors. No code generated.
|
||||
|
||||
|
||||
Shader version: 300
|
||||
@ -80,19 +82,33 @@ ERROR: node is still EOpNull!
|
||||
0:44 Function Parameters:
|
||||
0:46 Sequence
|
||||
0:46 Branch: Return with expression
|
||||
0:46 add (temp highp float)
|
||||
0:46 add (temp highp float)
|
||||
0:46 direct index (temp highp float)
|
||||
0:46 add (temp highp 4-component vector of float)
|
||||
0:46 add (temp highp 4-component vector of float)
|
||||
0:46 vector swizzle (temp highp 4-component vector of float)
|
||||
0:46 'gl_Position' (gl_Position highp 4-component vector of float Position)
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Sequence
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Constant:
|
||||
0:46 1 (const int)
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Constant:
|
||||
0:46 3 (const int)
|
||||
0:46 Constant:
|
||||
0:46 3.000000
|
||||
0:46 add (temp highp float)
|
||||
0:46 direct index (temp highp float)
|
||||
0:46 add (temp highp 4-component vector of float)
|
||||
0:46 vector swizzle (temp highp 4-component vector of float)
|
||||
0:46 'gl_Position' (gl_Position highp 4-component vector of float Position)
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Sequence
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Constant:
|
||||
0:46 1 (const int)
|
||||
0:46 Constant:
|
||||
0:46 0 (const int)
|
||||
0:46 Constant:
|
||||
0:46 3 (const int)
|
||||
0:46 Constant:
|
||||
0:46 3.000000
|
||||
0:47 Branch: Return with expression
|
||||
|
@ -22,14 +22,14 @@ ERROR: 0:172: '[]' : scalar integer expression required
|
||||
ERROR: 0:175: 'x' : undeclared identifier
|
||||
ERROR: 0:175: '[]' : scalar integer expression required
|
||||
ERROR: 0:175: 'b' : left of '[' is not of type array, matrix, or vector
|
||||
ERROR: 0:175: 'a' : vector field selection out of range
|
||||
ERROR: 0:175: 'a' : vector swizzle selection out of range
|
||||
ERROR: 0:175: 'length' : does not operate on this type: const float
|
||||
ERROR: 0:175: '' : function call, method, or subroutine call expected
|
||||
ERROR: 0:175: '' : no matching overloaded function found
|
||||
ERROR: 0:178: '[]' : scalar integer expression required
|
||||
ERROR: 0:178: 's' : undeclared identifier
|
||||
ERROR: 0:178: 's' : left of '[' is not of type array, matrix, or vector
|
||||
ERROR: 0:178: 'a' : vector field selection out of range
|
||||
ERROR: 0:178: 'a' : vector swizzle selection out of range
|
||||
ERROR: 0:178: 'length' : does not operate on this type: const float
|
||||
ERROR: 0:178: '' : function call, method, or subroutine call expected
|
||||
ERROR: 0:178: '' : no matching overloaded function found
|
||||
|
@ -974,20 +974,20 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
|
||||
// Make a constant vector node or constant scalar node, representing a given
|
||||
// constant vector and constant swizzle into it.
|
||||
//
|
||||
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc)
|
||||
TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& selectors, const TSourceLoc& loc)
|
||||
{
|
||||
const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
|
||||
TConstUnionArray constArray(fields.num);
|
||||
TConstUnionArray constArray(selectors.size());
|
||||
|
||||
for (int i = 0; i < fields.num; i++)
|
||||
constArray[i] = unionArray[fields.offsets[i]];
|
||||
for (int i = 0; i < selectors.size(); i++)
|
||||
constArray[i] = unionArray[selectors[i]];
|
||||
|
||||
TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc);
|
||||
|
||||
if (result == 0)
|
||||
result = node;
|
||||
else
|
||||
result->setType(TType(node->getBasicType(), EvqConst, fields.num));
|
||||
result->setType(TType(node->getBasicType(), EvqConst, selectors.size()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1392,38 +1392,35 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
|
||||
return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
|
||||
}
|
||||
|
||||
TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc& loc)
|
||||
// Put vector swizzle selectors onto the given sequence
|
||||
void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc)
|
||||
{
|
||||
TIntermAggregate* node = new TIntermAggregate(EOpSequence);
|
||||
|
||||
node->setLoc(loc);
|
||||
TIntermConstantUnion* constIntNode;
|
||||
TIntermSequence &sequenceVector = node->getSequence();
|
||||
|
||||
for (int i = 0; i < fields.num; i++) {
|
||||
constIntNode = addConstantUnion(fields.offsets[i], loc);
|
||||
sequenceVector.push_back(constIntNode);
|
||||
}
|
||||
|
||||
return node;
|
||||
TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc);
|
||||
sequence.push_back(constIntNode);
|
||||
}
|
||||
|
||||
// A matrix swizzle is a sequence of nodes, 2N long, where N is the
|
||||
// number of components in the swizzle, alternating col,row, col,row, ...
|
||||
TIntermTyped* TIntermediate::addSwizzle(TMatrixComponents& comps, const TSourceLoc& loc)
|
||||
// Put matrix swizzle selectors onto the given sequence
|
||||
void TIntermediate::pushSelector(TIntermSequence& sequence, const TMatrixSelector& selector, const TSourceLoc& loc)
|
||||
{
|
||||
TIntermConstantUnion* constIntNode = addConstantUnion(selector.coord1, loc);
|
||||
sequence.push_back(constIntNode);
|
||||
constIntNode = addConstantUnion(selector.coord2, loc);
|
||||
sequence.push_back(constIntNode);
|
||||
}
|
||||
|
||||
// Make an aggregate node that has a sequence of all selectors.
|
||||
template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc);
|
||||
template TIntermTyped* TIntermediate::addSwizzle<TMatrixSelector>(TSwizzleSelectors<TMatrixSelector>& selector, const TSourceLoc& loc);
|
||||
template<typename selectorType>
|
||||
TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors<selectorType>& selector, const TSourceLoc& loc)
|
||||
{
|
||||
TIntermAggregate* node = new TIntermAggregate(EOpSequence);
|
||||
|
||||
node->setLoc(loc);
|
||||
TIntermConstantUnion* constIntNode;
|
||||
TIntermSequence &sequenceVector = node->getSequence();
|
||||
|
||||
for (int i = 0; i < comps.size(); i++) {
|
||||
constIntNode = addConstantUnion(comps.get(i).coord1, loc);
|
||||
sequenceVector.push_back(constIntNode);
|
||||
constIntNode = addConstantUnion(comps.get(i).coord2, loc);
|
||||
sequenceVector.push_back(constIntNode);
|
||||
}
|
||||
for (int i = 0; i < selector.size(); i++)
|
||||
pushSelector(sequenceVector, selector[i], loc);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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())
|
||||
|
@ -170,6 +170,9 @@ protected:
|
||||
std::function<bool(const TType&, const TType&, const TType&)>,
|
||||
/* output */ bool& tie);
|
||||
|
||||
virtual void parseSwizzleSelector(const TSourceLoc&, const TString&, int size,
|
||||
TSwizzleSelectors<TVectorSelector>&);
|
||||
|
||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table
|
||||
int firstNewMember; // the index of the first member not yet inserted into the symbol table
|
||||
@ -284,7 +287,6 @@ public:
|
||||
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
||||
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
||||
|
||||
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||
|
@ -47,45 +47,39 @@ class TInfoSink;
|
||||
|
||||
namespace glslang {
|
||||
|
||||
struct TVectorFields {
|
||||
TVectorFields() { }
|
||||
|
||||
TVectorFields(int c0, int c1, int c2, int c3) : num(4)
|
||||
{
|
||||
offsets[0] = c0;
|
||||
offsets[1] = c1;
|
||||
offsets[2] = c2;
|
||||
offsets[3] = c3;
|
||||
}
|
||||
|
||||
int offsets[4];
|
||||
int num;
|
||||
struct TMatrixSelector {
|
||||
int coord1; // stay agnostic about column/row; this is parse order
|
||||
int coord2;
|
||||
};
|
||||
|
||||
class TMatrixComponents {
|
||||
public:
|
||||
static const int maxMatrixComponents = 4;
|
||||
struct tMatrixComponent {
|
||||
int coord1; // stay agnostic about column/row; this is parse order
|
||||
int coord2;
|
||||
};
|
||||
typedef int TVectorSelector;
|
||||
|
||||
TMatrixComponents() : size_(0) { }
|
||||
void push_back(tMatrixComponent comp)
|
||||
template<typename selectorType>
|
||||
class TSwizzleSelectors {
|
||||
public:
|
||||
static const int maxSelectors = 4;
|
||||
TSwizzleSelectors() : size_(0) { }
|
||||
|
||||
void push_back(selectorType comp)
|
||||
{
|
||||
if (size_ < maxMatrixComponents)
|
||||
if (size_ < maxSelectors)
|
||||
components[size_++] = comp;
|
||||
}
|
||||
int size() const { return size_; }
|
||||
tMatrixComponent get(int i) const
|
||||
void resize(int s)
|
||||
{
|
||||
assert(i < maxMatrixComponents);
|
||||
assert(s <= size_);
|
||||
size_ = s;
|
||||
}
|
||||
int size() const { return size_; }
|
||||
selectorType operator[](int i) const
|
||||
{
|
||||
assert(i < maxSelectors);
|
||||
return components[i];
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
int size_;
|
||||
tMatrixComponent components[4];
|
||||
selectorType components[maxSelectors];
|
||||
};
|
||||
|
||||
//
|
||||
@ -274,8 +268,7 @@ public:
|
||||
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
||||
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
||||
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
||||
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
|
||||
TIntermTyped* addSwizzle(TMatrixComponents&, const TSourceLoc&);
|
||||
template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
|
||||
|
||||
// Low level functions to add nodes (no conversions or other higher level transformations)
|
||||
// If a type is provided, the node's type will be set to it.
|
||||
@ -291,7 +284,7 @@ public:
|
||||
TIntermTyped* fold(TIntermAggregate* aggrNode);
|
||||
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
|
||||
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&);
|
||||
TIntermTyped* foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc&);
|
||||
TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors<TVectorSelector>& fields, const TSourceLoc&);
|
||||
|
||||
// Tree ops
|
||||
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
|
||||
@ -444,6 +437,8 @@ protected:
|
||||
bool promoteBinary(TIntermBinary&);
|
||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
|
||||
bool promoteAggregate(TIntermAggregate&);
|
||||
void pushSelector(TIntermSequence&, const TVectorSelector&, const TSourceLoc&);
|
||||
void pushSelector(TIntermSequence&, const TMatrixSelector&, const TSourceLoc&);
|
||||
|
||||
const EShLanguage language; // stage, known at construction time
|
||||
EShSource source; // source language, known a bit later
|
||||
|
@ -502,101 +502,7 @@ void HlslParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString
|
||||
}
|
||||
|
||||
//
|
||||
// Look at a '.' field selector string and change it into offsets
|
||||
// for a vector or scalar
|
||||
//
|
||||
// Returns true if there is no error.
|
||||
//
|
||||
bool HlslParseContext::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;
|
||||
}
|
||||
|
||||
//
|
||||
// Look at a '.' field selector string and change it into components
|
||||
// Look at a '.' matrix selector string and change it into components
|
||||
// for a matrix. There are two types:
|
||||
//
|
||||
// _21 second row, first column (one based)
|
||||
@ -604,10 +510,10 @@ bool HlslParseContext::parseVectorFields(const TSourceLoc& loc, const TString& c
|
||||
//
|
||||
// Returns true if there is no error.
|
||||
//
|
||||
bool HlslParseContext::parseMatrixComponents(const TSourceLoc& loc, const TString& fields, int cols, int rows,
|
||||
TMatrixComponents& components)
|
||||
bool HlslParseContext::parseMatrixSwizzleSelector(const TSourceLoc& loc, const TString& fields, int cols, int rows,
|
||||
TSwizzleSelectors<TMatrixSelector>& components)
|
||||
{
|
||||
int startPos[TMatrixComponents::maxMatrixComponents];
|
||||
int startPos[TSwizzleSelectors<TVectorSelector>::maxSelectors];
|
||||
int numComps = 0;
|
||||
TString compString = fields;
|
||||
|
||||
@ -615,7 +521,7 @@ bool HlslParseContext::parseMatrixComponents(const TSourceLoc& loc, const TStrin
|
||||
// recording the first character position after the '_'.
|
||||
for (size_t c = 0; c < compString.size(); ++c) {
|
||||
if (compString[c] == '_') {
|
||||
if (numComps >= TMatrixComponents::maxMatrixComponents) {
|
||||
if (numComps >= TSwizzleSelectors<TVectorSelector>::maxSelectors) {
|
||||
error(loc, "matrix component swizzle has too many components", compString.c_str(), "");
|
||||
return false;
|
||||
}
|
||||
@ -636,7 +542,7 @@ bool HlslParseContext::parseMatrixComponents(const TSourceLoc& loc, const TStrin
|
||||
bias = 0;
|
||||
++pos;
|
||||
}
|
||||
TMatrixComponents::tMatrixComponent comp;
|
||||
TMatrixSelector comp;
|
||||
comp.coord1 = compString[pos+0] - '0' + bias;
|
||||
comp.coord2 = compString[pos+1] - '0' + bias;
|
||||
if (comp.coord1 < 0 || comp.coord1 >= cols) {
|
||||
@ -658,21 +564,21 @@ bool HlslParseContext::parseMatrixComponents(const TSourceLoc& loc, const TStrin
|
||||
//
|
||||
// Otherwise, return -1.
|
||||
//
|
||||
int HlslParseContext::getMatrixComponentsColumn(int rows, const TMatrixComponents& comps)
|
||||
int HlslParseContext::getMatrixComponentsColumn(int rows, const TSwizzleSelectors<TMatrixSelector>& selector)
|
||||
{
|
||||
int col = -1;
|
||||
|
||||
// right number of comps?
|
||||
if (comps.size() != rows)
|
||||
if (selector.size() != rows)
|
||||
return -1;
|
||||
|
||||
// all comps in the same column?
|
||||
// rows in order?
|
||||
col = comps.get(0).coord1;
|
||||
col = selector[0].coord1;
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
if (col != comps.get(i).coord1)
|
||||
if (col != selector[i].coord1)
|
||||
return -1;
|
||||
if (i != comps.get(i).coord2)
|
||||
if (i != selector[i].coord2)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -934,63 +840,60 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
|
||||
|
||||
TIntermTyped* result = base;
|
||||
if (base->isVector() || base->isScalar()) {
|
||||
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());
|
||||
return addConstructor(loc, base, type);
|
||||
}
|
||||
}
|
||||
if (base->getVectorSize() == 1) {
|
||||
TType scalarType(base->getBasicType(), EvqTemporary, 1);
|
||||
if (fields.num == 1)
|
||||
if (selectors.size() == 1)
|
||||
return addConstructor(loc, base, scalarType);
|
||||
else {
|
||||
TType vectorType(base->getBasicType(), EvqTemporary, fields.num);
|
||||
TType vectorType(base->getBasicType(), EvqTemporary, selectors.size());
|
||||
return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
} else {
|
||||
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, fields.num));
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
|
||||
}
|
||||
}
|
||||
} else if (base->isMatrix()) {
|
||||
TMatrixComponents comps;
|
||||
if (! parseMatrixComponents(loc, field, base->getMatrixCols(), base->getMatrixRows(), comps))
|
||||
TSwizzleSelectors<TMatrixSelector> selectors;
|
||||
if (! parseMatrixSwizzleSelector(loc, field, base->getMatrixCols(), base->getMatrixRows(), selectors))
|
||||
return result;
|
||||
|
||||
if (comps.size() == 1) {
|
||||
if (selectors.size() == 1) {
|
||||
// Representable by m[c][r]
|
||||
if (base->getType().getQualifier().isFrontEndConstant()) {
|
||||
result = intermediate.foldDereference(base, comps.get(0).coord1, loc);
|
||||
result = intermediate.foldDereference(result, comps.get(1).coord2, loc);
|
||||
result = intermediate.foldDereference(base, selectors[0].coord1, loc);
|
||||
result = intermediate.foldDereference(result, selectors[0].coord2, loc);
|
||||
} else {
|
||||
result = intermediate.addIndex(EOpIndexDirect, base, intermediate.addConstantUnion(comps.get(0).coord1, loc), loc);
|
||||
result = intermediate.addIndex(EOpIndexDirect, base, intermediate.addConstantUnion(selectors[0].coord1, loc), loc);
|
||||
TType dereferencedCol(base->getType(), 0);
|
||||
result->setType(dereferencedCol);
|
||||
result = intermediate.addIndex(EOpIndexDirect, result, intermediate.addConstantUnion(comps.get(0).coord2, loc), loc);
|
||||
result = intermediate.addIndex(EOpIndexDirect, result, intermediate.addConstantUnion(selectors[0].coord2, loc), loc);
|
||||
TType dereferenced(dereferencedCol, 0);
|
||||
result->setType(dereferenced);
|
||||
}
|
||||
} else {
|
||||
int column = getMatrixComponentsColumn(base->getMatrixRows(), comps);
|
||||
int column = getMatrixComponentsColumn(base->getMatrixRows(), selectors);
|
||||
if (column >= 0) {
|
||||
// Representable by m[c]
|
||||
if (base->getType().getQualifier().isFrontEndConstant())
|
||||
@ -1002,9 +905,9 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
|
||||
}
|
||||
} else {
|
||||
// general case, not a column, not a single component
|
||||
TIntermTyped* index = intermediate.addSwizzle(comps, loc);
|
||||
TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
|
||||
result = intermediate.addIndex(EOpMatrixSwizzle, base, index, loc);
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, comps.size()));
|
||||
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision, selectors.size()));
|
||||
}
|
||||
}
|
||||
} else if (base->getBasicType() == EbtStruct || base->getBasicType() == EbtBlock) {
|
||||
@ -2535,14 +2438,16 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
coordSwizzle = argCoord;
|
||||
} else {
|
||||
// Extract coordinate
|
||||
TVectorFields coordFields(0,1,2,3);
|
||||
coordFields.num = argCoord->getType().getVectorSize() - (isMS ? 0 : 1);
|
||||
int swizzleSize = argCoord->getType().getVectorSize() - (isMS ? 0 : 1);
|
||||
TSwizzleSelectors<TVectorSelector> coordFields;
|
||||
for (int i = 0; i < swizzleSize; ++i)
|
||||
coordFields.push_back(i);
|
||||
TIntermTyped* coordIdx = intermediate.addSwizzle(coordFields, loc);
|
||||
coordSwizzle = intermediate.addIndex(EOpVectorSwizzle, argCoord, coordIdx, loc);
|
||||
coordSwizzle->setType(TType(coordBaseType, EvqTemporary, coordFields.num));
|
||||
coordSwizzle->setType(TType(coordBaseType, EvqTemporary, coordFields.size()));
|
||||
|
||||
// Extract LOD
|
||||
TIntermTyped* lodIdx = intermediate.addConstantUnion(coordFields.num, loc, true);
|
||||
TIntermTyped* lodIdx = intermediate.addConstantUnion(coordFields.size(), loc, true);
|
||||
lodComponent = intermediate.addIndex(EOpIndexDirect, argCoord, lodIdx, loc);
|
||||
lodComponent->setType(TType(coordBaseType, EvqTemporary, 1));
|
||||
}
|
||||
@ -3248,8 +3153,12 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
|
||||
{
|
||||
// ivec4 ( x.zyxw * 255.001953 );
|
||||
TIntermTyped* arg0 = node->getAsUnaryNode()->getOperand();
|
||||
TVectorFields fields(2,1,0,3);
|
||||
TIntermTyped* swizzleIdx = intermediate.addSwizzle(fields, loc);
|
||||
TSwizzleSelectors<TVectorSelector> selectors;
|
||||
selectors.push_back(2);
|
||||
selectors.push_back(1);
|
||||
selectors.push_back(0);
|
||||
selectors.push_back(3);
|
||||
TIntermTyped* swizzleIdx = intermediate.addSwizzle(selectors, loc);
|
||||
TIntermTyped* swizzled = intermediate.addIndex(EOpVectorSwizzle, arg0, swizzleIdx, loc);
|
||||
swizzled->setType(arg0->getType());
|
||||
swizzled->getWritableType().getQualifier().makeTemporary();
|
||||
|
@ -97,9 +97,8 @@ public:
|
||||
|
||||
TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler);
|
||||
|
||||
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&);
|
||||
bool parseMatrixComponents(const TSourceLoc&, const TString&, int cols, int rows, TMatrixComponents&);
|
||||
int getMatrixComponentsColumn(int rows, const TMatrixComponents&);
|
||||
bool parseMatrixSwizzleSelector(const TSourceLoc&, const TString&, int cols, int rows, TSwizzleSelectors<TMatrixSelector>&);
|
||||
int getMatrixComponentsColumn(int rows, const TSwizzleSelectors<TMatrixSelector>&);
|
||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||
|
Loading…
x
Reference in New Issue
Block a user