HLSL: Add EOpMatrixSwizzle, selectively decomposed to other ops, for issue #670.

Since EOpMatrixSwizzle is a new op, existing back-ends only work when the
front end first decomposes it to other operations. So far, this is only
being done for simple assignment into matrix swizzles.
This commit is contained in:
John Kessenich 2017-01-13 12:27:52 -07:00
parent 001dfa1c5c
commit fdf6347f0a
12 changed files with 907 additions and 116 deletions

View file

@ -1408,6 +1408,26 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, const TSourceLoc&
return node;
}
// 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)
{
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);
}
return node;
}
//
// Follow the left branches down to the root of an l-value
// expression (just "." and []).
@ -1425,10 +1445,10 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
if (binary == nullptr)
return node;
TOperator op = binary->getOp();
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle)
if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle)
return nullptr;
if (! swizzleOkay) {
if (op == EOpVectorSwizzle)
if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle)
return nullptr;
if ((op == EOpIndexDirect || op == EOpIndexIndirect) &&
(binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) &&

View file

@ -129,6 +129,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
case EOpIndexIndirect: // fall through
case EOpIndexDirectStruct: // fall through
case EOpVectorSwizzle:
case EOpMatrixSwizzle:
return lValueErrorCheck(loc, op, binaryNode->getLeft());
default:
break;
@ -208,6 +209,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
case EOpIndexIndirect:
case EOpIndexDirectStruct:
case EOpVectorSwizzle:
case EOpMatrixSwizzle:
rValueErrorCheck(loc, op, binaryNode->getLeft());
default:
break;

View file

@ -146,6 +146,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
out.debug << ": direct index for structure"; break;
case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
case EOpAdd: out.debug << "add"; break;
case EOpSub: out.debug << "subtract"; break;

View file

@ -275,6 +275,7 @@ public:
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, const TSourceLoc&);
TIntermTyped* addSwizzle(TMatrixComponents&, 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.

View file

@ -90,6 +90,7 @@ bool isDereferenceOperation(glslang::TOperator op)
case glslang::EOpIndexDirectStruct:
case glslang::EOpIndexIndirect:
case glslang::EOpVectorSwizzle:
case glslang::EOpMatrixSwizzle:
return true;
default:
return false;