Commit c142c889 by John Kessenich

Front-ends: Non-functional: Rationalize vector and matrix swizzles.

This reduces code duplication in a few ways, and better encapsulates vector swizzle representation.
parent 0a76a187
...@@ -15,11 +15,9 @@ ERROR: 0:63: 'bitwise-or assign' : not supported for this version or the enabled ...@@ -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: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: ':' : 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: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:82: 'xr' : vector swizzle selectors not from the same set
ERROR: 0:83: 'xyxyx' : illegal vector field selection ERROR: 0:83: 'xyxyx' : vector swizzle too long
ERROR: 0:83: 'scalar swizzle' : not supported for this version or the enabled extensions ERROR: 0:84: 'z' : vector swizzle selection out of range
ERROR: 0:83: 'xy' : vector field selection out of range
ERROR: 0:84: 'z' : vector field selection out of range
ERROR: 0:85: 'assign' : l-value required ERROR: 0:85: 'assign' : l-value required
ERROR: 0:91: 'int' : overloaded functions must have the same return type ERROR: 0:91: 'int' : overloaded functions must have the same return type
ERROR: 0:91: 'main' : function already has a body ERROR: 0:91: 'main' : function already has a body
...@@ -52,7 +50,7 @@ ERROR: 0:191: 'shadow2DProjGradARB' : required extension not requested: GL_ARB_s ...@@ -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: 'shadow2DRectProjGradARB' : no matching overloaded function found
ERROR: 0:209: 'assign' : cannot convert from 'const float' to 'temp 4-component vector of float' ERROR: 0:209: 'assign' : cannot convert from 'const float' to 'temp 4-component vector of float'
ERROR: 0:212: 'sampler2DRect' : Reserved word. ERROR: 0:212: 'sampler2DRect' : Reserved word.
ERROR: 53 compilation errors. No code generated. ERROR: 51 compilation errors. No code generated.
Shader version: 120 Shader version: 120
...@@ -251,10 +249,23 @@ ERROR: node is still EOpNull! ...@@ -251,10 +249,23 @@ ERROR: node is still EOpNull!
0:82 'gl_FragColor' (fragColor 4-component vector of float FragColor) 0:82 'gl_FragColor' (fragColor 4-component vector of float FragColor)
0:82 Constant: 0:82 Constant:
0:82 0 (const int) 0:82 0 (const int)
0:83 direct index (temp float) 0:83 vector swizzle (temp 2-component vector of float)
0:83 'gl_FragColor' (fragColor 4-component vector of float FragColor) 0:83 vector swizzle (temp 4-component vector of float)
0:83 Constant: 0:83 'gl_FragColor' (fragColor 4-component vector of float FragColor)
0:83 0 (const int) 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 direct index (temp float)
0:84 'centTexCoord' (centroid smooth in 2-component vector of float) 0:84 'centTexCoord' (centroid smooth in 2-component vector of float)
0:84 Constant: 0:84 Constant:
......
...@@ -18,9 +18,9 @@ ERROR: 0:40: 'j' : undeclared identifier ...@@ -18,9 +18,9 @@ ERROR: 0:40: 'j' : undeclared identifier
ERROR: 0:40: '=' : cannot convert from 'temp float' to 'temp int' ERROR: 0:40: '=' : cannot convert from 'temp float' to 'temp int'
ERROR: 0:44: 'jj' : undeclared identifier ERROR: 0:44: 'jj' : undeclared identifier
ERROR: 0:44: '=' : cannot convert from 'temp float' to 'temp int' ERROR: 0:44: '=' : cannot convert from 'temp float' to 'temp int'
ERROR: 0:54: 'y' : vector field selection out of range ERROR: 0:54: 'y' : vector swizzle selection out of range
ERROR: 0:62: 'xxxxx' : illegal vector field selection ERROR: 0:62: 'xxxxx' : vector swizzle too long
ERROR: 0:63: 'xxy' : vector field selection out of range 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: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:69: 'location/component/index' : cannot declare a default, use a full declaration
ERROR: 0:70: 'input block' : not supported in this stage: vertex ERROR: 0:70: 'input block' : not supported in this stage: vertex
...@@ -124,8 +124,10 @@ ERROR: node is still EOpNull! ...@@ -124,8 +124,10 @@ ERROR: node is still EOpNull!
0:61 'smeared' (temp 3-component vector of float) 0:61 'smeared' (temp 3-component vector of float)
0:61 Construct vec3 (temp 3-component vector of float) 0:61 Construct vec3 (temp 3-component vector of float)
0:61 'f' (temp float) 0:61 'f' (temp float)
0:62 'f' (temp float) 0:62 Construct vec4 (temp 4-component vector of float)
0:63 'f' (temp 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 Definition: bar23444( (global void)
0:88 Function Parameters: 0:88 Function Parameters:
0:? Sequence 0:? Sequence
......
cppComplexExpr.vert cppComplexExpr.vert
ERROR: 0:46: 'xyxwx' : illegal vector field selection ERROR: 0:46: 'xyxwx' : vector swizzle too long
ERROR: 0:46: 'xyxwx' : illegal vector field selection 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:66: '#define' : Macro redefined; different substitutions: BIG
ERROR: 0:81: 'preprocessor evaluation' : bad expression ERROR: 0:81: 'preprocessor evaluation' : bad expression
ERROR: 0:81: '#if' : unexpected tokens following directive ERROR: 0:81: '#if' : unexpected tokens following directive
...@@ -47,7 +49,7 @@ ERROR: 0:0: 'preprocessor evaluation' : division by 0 ...@@ -47,7 +49,7 @@ ERROR: 0:0: 'preprocessor evaluation' : division by 0
ERROR: 0:3: 'preprocessor evaluation' : bad expression ERROR: 0:3: 'preprocessor evaluation' : bad expression
ERROR: 0:3: 'preprocessor evaluation' : division by 0 ERROR: 0:3: 'preprocessor evaluation' : division by 0
ERROR: 0:10001: '' : missing #endif ERROR: 0:10001: '' : missing #endif
ERROR: 48 compilation errors. No code generated. ERROR: 49 compilation errors. No code generated.
Shader version: 300 Shader version: 300
...@@ -80,19 +82,33 @@ ERROR: node is still EOpNull! ...@@ -80,19 +82,33 @@ ERROR: node is still EOpNull!
0:44 Function Parameters: 0:44 Function Parameters:
0:46 Sequence 0:46 Sequence
0:46 Branch: Return with expression 0:46 Branch: Return with expression
0:46 add (temp highp float) 0:46 add (temp highp 4-component vector of float)
0:46 add (temp highp float) 0:46 add (temp highp 4-component vector of float)
0:46 direct index (temp highp 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 'gl_Position' (gl_Position highp 4-component vector of float Position)
0:46 Constant: 0:46 Sequence
0:46 0 (const int) 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 Constant:
0:46 3.000000 0:46 3.000000
0:46 add (temp highp float) 0:46 add (temp highp 4-component vector of float)
0:46 direct index (temp highp 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 'gl_Position' (gl_Position highp 4-component vector of float Position)
0:46 Constant: 0:46 Sequence
0:46 0 (const int) 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 Constant:
0:46 3.000000 0:46 3.000000
0:47 Branch: Return with expression 0:47 Branch: Return with expression
......
...@@ -22,14 +22,14 @@ ERROR: 0:172: '[]' : scalar integer expression required ...@@ -22,14 +22,14 @@ ERROR: 0:172: '[]' : scalar integer expression required
ERROR: 0:175: 'x' : undeclared identifier ERROR: 0:175: 'x' : undeclared identifier
ERROR: 0:175: '[]' : scalar integer expression required ERROR: 0:175: '[]' : scalar integer expression required
ERROR: 0:175: 'b' : left of '[' is not of type array, matrix, or vector 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: 'length' : does not operate on this type: const float
ERROR: 0:175: '' : function call, method, or subroutine call expected ERROR: 0:175: '' : function call, method, or subroutine call expected
ERROR: 0:175: '' : no matching overloaded function found ERROR: 0:175: '' : no matching overloaded function found
ERROR: 0:178: '[]' : scalar integer expression required ERROR: 0:178: '[]' : scalar integer expression required
ERROR: 0:178: 's' : undeclared identifier ERROR: 0:178: 's' : undeclared identifier
ERROR: 0:178: 's' : left of '[' is not of type array, matrix, or vector 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: 'length' : does not operate on this type: const float
ERROR: 0:178: '' : function call, method, or subroutine call expected ERROR: 0:178: '' : function call, method, or subroutine call expected
ERROR: 0:178: '' : no matching overloaded function found ERROR: 0:178: '' : no matching overloaded function found
......
...@@ -974,20 +974,20 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons ...@@ -974,20 +974,20 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
// Make a constant vector node or constant scalar node, representing a given // Make a constant vector node or constant scalar node, representing a given
// constant vector and constant swizzle into it. // 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(); const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray();
TConstUnionArray constArray(fields.num); TConstUnionArray constArray(selectors.size());
for (int i = 0; i < fields.num; i++) for (int i = 0; i < selectors.size(); i++)
constArray[i] = unionArray[fields.offsets[i]]; constArray[i] = unionArray[selectors[i]];
TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc); TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc);
if (result == 0) if (result == 0)
result = node; result = node;
else else
result->setType(TType(node->getBasicType(), EvqConst, fields.num)); result->setType(TType(node->getBasicType(), EvqConst, selectors.size()));
return result; return result;
} }
......
...@@ -1392,38 +1392,35 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT ...@@ -1392,38 +1392,35 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal); 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); TIntermConstantUnion* constIntNode = addConstantUnion(selector, loc);
sequence.push_back(constIntNode);
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; // 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);
} }
// A matrix swizzle is a sequence of nodes, 2N long, where N is the // Make an aggregate node that has a sequence of all selectors.
// number of components in the swizzle, alternating col,row, col,row, ... template TIntermTyped* TIntermediate::addSwizzle<TVectorSelector>(TSwizzleSelectors<TVectorSelector>& selector, const TSourceLoc& loc);
TIntermTyped* TIntermediate::addSwizzle(TMatrixComponents& comps, 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); TIntermAggregate* node = new TIntermAggregate(EOpSequence);
node->setLoc(loc); node->setLoc(loc);
TIntermConstantUnion* constIntNode;
TIntermSequence &sequenceVector = node->getSequence(); TIntermSequence &sequenceVector = node->getSequence();
for (int i = 0; i < comps.size(); i++) { for (int i = 0; i < selector.size(); i++)
constIntNode = addConstantUnion(comps.get(i).coord1, loc); pushSelector(sequenceVector, selector[i], loc);
sequenceVector.push_back(constIntNode);
constIntNode = addConstantUnion(comps.get(i).coord2, loc);
sequenceVector.push_back(constIntNode);
}
return node; return node;
} }
......
...@@ -434,6 +434,108 @@ const TFunction* TParseContextBase::selectFunction( ...@@ -434,6 +434,108 @@ const TFunction* TParseContextBase::selectFunction(
} }
// //
// 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 // Make the passed-in variable information become a member of the
// global uniform block. If this doesn't exist yet, make it. // global uniform block. If this doesn't exist yet, make it.
// //
......
...@@ -258,106 +258,6 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& ...@@ -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. // Handle seeing a variable identifier in the grammar.
// //
...@@ -781,17 +681,14 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm ...@@ -781,17 +681,14 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature); profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, dotFeature);
} }
TVectorFields fields; TSwizzleSelectors<TVectorSelector> selectors;
if (! parseVectorFields(loc, field, base->getVectorSize(), fields)) { parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
fields.num = 1;
fields.offsets[0] = 0;
}
if (base->isScalar()) { if (base->isScalar()) {
if (fields.num == 1) if (selectors.size() == 1)
return result; return result;
else { else {
TType type(base->getBasicType(), EvqTemporary, fields.num); TType type(base->getBasicType(), EvqTemporary, selectors.size());
// Swizzle operations propagate specialization-constantness // Swizzle operations propagate specialization-constantness
if (base->getQualifier().isSpecConstant()) if (base->getQualifier().isSpecConstant())
type.getQualifier().makeSpecConstant(); type.getQualifier().makeSpecConstant();
...@@ -800,17 +697,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm ...@@ -800,17 +697,16 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
} }
if (base->getType().getQualifier().isFrontEndConstant()) if (base->getType().getQualifier().isFrontEndConstant())
result = intermediate.foldSwizzle(base, fields, loc); result = intermediate.foldSwizzle(base, selectors, loc);
else { else {
if (fields.num == 1) { if (selectors.size() == 1) {
TIntermTyped* index = intermediate.addConstantUnion(fields.offsets[0], loc); TIntermTyped* index = intermediate.addConstantUnion(selectors[0], loc);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc); result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision)); result->setType(TType(base->getBasicType(), EvqTemporary, base->getType().getQualifier().precision));
} else { } else {
TString vectorString = field; TIntermTyped* index = intermediate.addSwizzle(selectors, loc);
TIntermTyped* index = intermediate.addSwizzle(fields, loc);
result = intermediate.addIndex(EOpVectorSwizzle, base, index, 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 // Swizzle operations propagate specialization-constantness
if (base->getType().getQualifier().isSpecConstant()) if (base->getType().getQualifier().isSpecConstant())
......
...@@ -170,6 +170,9 @@ protected: ...@@ -170,6 +170,9 @@ protected:
std::function<bool(const TType&, const TType&, const TType&)>, std::function<bool(const TType&, const TType&, const TType&)>,
/* output */ bool& tie); /* 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) // Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
TVariable* globalUniformBlock; // the actual block, inserted into the symbol table 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 int firstNewMember; // the index of the first member not yet inserted into the symbol table
...@@ -284,7 +287,6 @@ public: ...@@ -284,7 +287,6 @@ public:
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier); void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
void checkPrecisionQualifier(const TSourceLoc&, 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 assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand); void unaryOpError(const TSourceLoc&, const char* op, TString operand);
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
......
...@@ -47,45 +47,39 @@ class TInfoSink; ...@@ -47,45 +47,39 @@ class TInfoSink;
namespace glslang { namespace glslang {
struct TVectorFields { struct TMatrixSelector {
TVectorFields() { } int coord1; // stay agnostic about column/row; this is parse order
int coord2;
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;
}; };
class TMatrixComponents { typedef int TVectorSelector;
template<typename selectorType>
class TSwizzleSelectors {
public: public:
static const int maxMatrixComponents = 4; static const int maxSelectors = 4;
struct tMatrixComponent { TSwizzleSelectors() : size_(0) { }
int coord1; // stay agnostic about column/row; this is parse order
int coord2; void push_back(selectorType comp)
};
TMatrixComponents() : size_(0) { }
void push_back(tMatrixComponent comp)
{ {
if (size_ < maxMatrixComponents) if (size_ < maxSelectors)
components[size_++] = comp; components[size_++] = comp;
} }
void resize(int s)
{
assert(s <= size_);
size_ = s;
}
int size() const { return size_; } int size() const { return size_; }
tMatrixComponent get(int i) const selectorType operator[](int i) const
{ {
assert(i < maxMatrixComponents); assert(i < maxSelectors);
return components[i]; return components[i];
} }
private: private:
int size_; int size_;
tMatrixComponent components[4]; selectorType components[maxSelectors];
}; };
// //
...@@ -274,8 +268,7 @@ public: ...@@ -274,8 +268,7 @@ public:
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&); TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, const TSourceLoc&); TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&); TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&); template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
TIntermTyped* addSwizzle(TMatrixComponents&, const TSourceLoc&);
// Low level functions to add nodes (no conversions or other higher level transformations) // 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. // If a type is provided, the node's type will be set to it.
...@@ -291,7 +284,7 @@ public: ...@@ -291,7 +284,7 @@ public:
TIntermTyped* fold(TIntermAggregate* aggrNode); TIntermTyped* fold(TIntermAggregate* aggrNode);
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode); TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
TIntermTyped* foldDereference(TIntermTyped* node, int index, const TSourceLoc&); 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 // Tree ops
static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay); static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay);
...@@ -444,6 +437,8 @@ protected: ...@@ -444,6 +437,8 @@ protected:
bool promoteBinary(TIntermBinary&); bool promoteBinary(TIntermBinary&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&);
bool promoteAggregate(TIntermAggregate&); 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 const EShLanguage language; // stage, known at construction time
EShSource source; // source language, known a bit later EShSource source; // source language, known a bit later
......
...@@ -97,9 +97,8 @@ public: ...@@ -97,9 +97,8 @@ public:
TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler); TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler);
bool parseVectorFields(const TSourceLoc&, const TString&, int vecSize, TVectorFields&); bool parseMatrixSwizzleSelector(const TSourceLoc&, const TString&, int cols, int rows, TSwizzleSelectors<TMatrixSelector>&);
bool parseMatrixComponents(const TSourceLoc&, const TString&, int cols, int rows, TMatrixComponents&); int getMatrixComponentsColumn(int rows, const TSwizzleSelectors<TMatrixSelector>&);
int getMatrixComponentsColumn(int rows, const TMatrixComponents&);
void assignError(const TSourceLoc&, const char* op, TString left, TString right); void assignError(const TSourceLoc&, const char* op, TString left, TString right);
void unaryOpError(const TSourceLoc&, const char* op, TString operand); void unaryOpError(const TSourceLoc&, const char* op, TString operand);
void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right); void binaryOpError(const TSourceLoc&, const char* op, TString left, TString right);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment