Commit b3da8a9c by steve-lunarg

HLSL: phase 2e: introduce lower level addBinaryNode/UnaryNode fns

- hlsl.struct.frag variable changed to static, assignment replacd. - Created new low level functions addBinaryNode and addUnaryNode. These are used by higher level functions such as addAssignment, and do not do any argument promotion or conversion of any sort. - Two functions above are now used in RWTexture lvalue conversions. Also, other direction creations of unary or binary nodes now use them, e.g, addIndex. This cleans up some existing code. - removed handling of EOpVectorTimesScalar from promote() - removed comment from ParseHelper.cpp
parent 07830e80
......@@ -12,7 +12,7 @@ struct myS {
myS s1;
struct {
static struct {
float4 i;
} s2;
......@@ -37,7 +37,7 @@ float4 PixelShaderFunction(float4 input, IN_S s) : COLOR0
} s3;
s3 == s3;
s2.i; s.ff4; // no assignments to uniforms, but preserve indirections.
s2.i = s.ff4;
return input;
}
......@@ -136,13 +136,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
// Need a new node holding things together. Make
// one and promote it to the right type.
//
TIntermBinary* node = new TIntermBinary(op);
if (loc.line == 0)
loc = right->getLoc();
node->setLoc(loc);
node->setLeft(left);
node->setRight(right);
TIntermBinary* node = addBinaryNode(op, left, right, loc);
if (! node->promote())
return 0;
......@@ -173,6 +167,56 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
}
//
// Low level: add binary node (no promotions or other argument modifications)
//
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc) const
{
// build the node
TIntermBinary* node = new TIntermBinary(op);
if (loc.line == 0)
loc = left->getLoc();
node->setLoc(loc);
node->setLeft(left);
node->setRight(right);
return node;
}
//
// like non-type form, but sets node's type.
//
TIntermBinary* TIntermediate::addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc loc, const TType& type) const
{
TIntermBinary* node = addBinaryNode(op, left, right, loc);
node->setType(type);
return node;
}
//
// Low level: add unary node (no promotions or other argument modifications)
//
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc) const
{
TIntermUnary* node = new TIntermUnary(op);
if (loc.line == 0)
loc = child->getLoc();
node->setLoc(loc);
node->setOperand(child);
return node;
}
//
// like non-type form, but sets node's type.
//
TIntermUnary* TIntermediate::addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc loc, const TType& type) const
{
TIntermUnary* node = addUnaryNode(op, child, loc);
node->setType(type);
return node;
}
//
// Connect two nodes through an assignment.
//
// Returns the added node.
......@@ -200,12 +244,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
right = addShapeConversion(op, left->getType(), right);
// build the node
TIntermBinary* node = new TIntermBinary(op);
if (loc.line == 0)
loc = left->getLoc();
node->setLoc(loc);
node->setLeft(left);
node->setRight(right);
TIntermBinary* node = addBinaryNode(op, left, right, loc);
if (! node->promote())
return nullptr;
......@@ -224,16 +263,8 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
//
TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc loc)
{
TIntermBinary* node = new TIntermBinary(op);
if (loc.line == 0)
loc = index->getLoc();
node->setLoc(loc);
node->setLeft(base);
node->setRight(index);
// caller should set the type
return node;
return addBinaryNode(op, base, index, loc);
}
//
......@@ -316,11 +347,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo
//
// Make a new node for the operator.
//
TIntermUnary* node = new TIntermUnary(op);
if (loc.line == 0)
loc = child->getLoc();
node->setLoc(loc);
node->setOperand(child);
TIntermUnary* node = addUnaryNode(op, child, loc);
if (! node->promote())
return 0;
......@@ -357,12 +384,7 @@ TIntermTyped* TIntermediate::addBuiltInFunctionCall(const TSourceLoc& loc, TOper
return folded;
}
TIntermUnary* node = new TIntermUnary(op);
node->setLoc(child->getLoc());
node->setOperand(child);
node->setType(returnType);
return node;
return addUnaryNode(op, child, child->getLoc(), returnType);
} else {
// setAggregateOperater() calls fold() for constant folding
TIntermTyped* node = setAggregateOperator(childNode, op, returnType, loc);
......@@ -725,9 +747,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
}
TType newType(promoteTo, EvqTemporary, node->getVectorSize(), node->getMatrixCols(), node->getMatrixRows());
newNode = new TIntermUnary(newOp, newType);
newNode->setLoc(node->getLoc());
newNode->setOperand(node);
newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
// TODO: it seems that some unary folding operations should occur here, but are not
......@@ -2045,11 +2065,6 @@ bool TIntermBinary::promote()
}
break;
case EOpVectorTimesScalarAssign:
if (!left->isVector() || !right->isScalar())
return false;
break;
default:
return false;
}
......@@ -2070,7 +2085,6 @@ bool TIntermBinary::promote()
case EOpExclusiveOrAssign:
case EOpLeftShiftAssign:
case EOpRightShiftAssign:
case EOpVectorTimesScalarAssign:
if (getType() != left->getType())
return false;
break;
......
......@@ -1966,7 +1966,6 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
if (TParseContextBase::lValueErrorCheck(loc, op, node))
return true;
// GLSL specific
const char* symbol = nullptr;
TIntermSymbol* symNode = node->getAsSymbolNode();
if (symNode != nullptr)
......
......@@ -236,6 +236,13 @@ public:
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
TIntermTyped* addSwizzle(TVectorFields&, 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.
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc) const;
TIntermBinary* addBinaryNode(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, const TType&) const;
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc) const;
TIntermUnary* addUnaryNode(TOperator op, TIntermTyped* child, TSourceLoc, const TType&) const;
// Constant folding (in Constant.cpp)
TIntermTyped* fold(TIntermAggregate* aggrNode);
TIntermTyped* foldConstructor(TIntermAggregate* aggrNode);
......
......@@ -228,9 +228,9 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
};
// Helper to create an assign.
const auto makeAssign = [&](TOperator assignOp, TIntermTyped* lhs, TIntermTyped* rhs) {
const auto makeBinary = [&](TOperator op, TIntermTyped* lhs, TIntermTyped* rhs) {
sequence = intermediate.growAggregate(sequence,
intermediate.addAssign(assignOp, lhs, rhs, loc),
intermediate.addBinaryNode(op, lhs, rhs, loc, lhs->getType()),
loc);
};
......@@ -246,9 +246,10 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
};
// Helper to add unary op
const auto addUnary = [&](TOperator op, TIntermSymbol* rhsTmp) {
const auto makeUnary = [&](TOperator op, TIntermSymbol* rhsTmp) {
sequence = intermediate.growAggregate(sequence,
intermediate.addUnaryMath(op, intermediate.addSymbol(*rhsTmp), loc),
intermediate.addUnaryNode(op, intermediate.addSymbol(*rhsTmp), loc,
rhsTmp->getType()),
loc);
};
......@@ -322,12 +323,12 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
if (isModifyOp) {
// We have to make a temp var for the coordinate, to avoid evaluating it twice.
coordTmp = addTmpVar("coordTemp", coord->getType());
makeAssign(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp, object, coordTmp, objDerefType); // rhsTmp = OpImageLoad(object, coordTmp)
}
// rhsTmp op= rhs.
makeAssign(assignOp, intermediate.addSymbol(*rhsTmp), rhs);
makeBinary(assignOp, intermediate.addSymbol(*rhsTmp), rhs);
}
makeStore(object, coordTmp, rhsTmp); // add a store
......@@ -357,9 +358,9 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
TIntermSymbol* rhsTmp = addTmpVar("storeTemp", objDerefType);
TIntermTyped* coordTmp = addTmpVar("coordTemp", coord->getType());
makeAssign(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp, object, coordTmp, objDerefType); // rhsTmp = OpImageLoad(object, coordTmp)
addUnary(assignOp, rhsTmp); // op rhsTmp
makeUnary(assignOp, rhsTmp); // op rhsTmp
makeStore(object, coordTmp, rhsTmp); // OpImageStore(object, coordTmp, rhsTmp)
return finishSequence(rhsTmp, objDerefType); // return rhsTmp from sequence
}
......@@ -379,10 +380,10 @@ TIntermTyped* HlslParseContext::handleLvalue(const TSourceLoc& loc, const char*
TIntermSymbol* rhsTmp2 = addTmpVar("storeTempPost", objDerefType);
TIntermTyped* coordTmp = addTmpVar("coordTemp", coord->getType());
makeAssign(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeBinary(EOpAssign, coordTmp, coord); // coordtmp = load[param1]
makeLoad(rhsTmp1, object, coordTmp, objDerefType); // rhsTmp1 = OpImageLoad(object, coordTmp)
makeAssign(EOpAssign, rhsTmp2, rhsTmp1); // rhsTmp2 = rhsTmp1
addUnary(assignOp, rhsTmp2); // rhsTmp op
makeBinary(EOpAssign, rhsTmp2, rhsTmp1); // rhsTmp2 = rhsTmp1
makeUnary(assignOp, rhsTmp2); // rhsTmp op
makeStore(object, coordTmp, rhsTmp2); // OpImageStore(object, coordTmp, rhsTmp2)
return finishSequence(rhsTmp1, objDerefType); // return rhsTmp from sequence
}
......
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