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
This commit is contained in:
steve-lunarg 2016-10-12 12:38:12 -06:00
parent 07830e805b
commit b3da8a9cb3
6 changed files with 170 additions and 156 deletions

View File

@ -14,22 +14,21 @@ gl_FragCoord origin is upper left
0:39 Compare Equal (temp bool)
0:39 's3' (temp structure{temp 3-component vector of bool b3})
0:39 's3' (temp structure{temp 3-component vector of bool b3})
0:40 i: direct index for structure (temp 4-component vector of float)
0:40 s2: direct index for structure (layout(offset=48 ) uniform structure{temp 4-component vector of float i})
0:40 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(offset=48 ) uniform structure{temp 4-component vector of float i} s2, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:40 move second child to first child (temp 4-component vector of float)
0:40 i: direct index for structure (temp 4-component vector of float)
0:40 's2' (global structure{temp 4-component vector of float i})
0:40 Constant:
0:40 1 (const uint)
0:40 Constant:
0:40 0 (const int)
0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
0:40 0 (const int)
0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
0:42 Sequence
0:42 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:42 'input' (layout(location=0 ) in 4-component vector of float)
0:42 Branch: Return
0:? Linker Objects
0:? 's2' (global structure{temp 4-component vector of float i})
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'anon@0' (uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(offset=48 ) uniform structure{temp 4-component vector of float i} s2, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:? 'anon@0' (uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:? 'input' (layout(location=0 ) in 4-component vector of float)
0:? 'a' (layout(location=1 ) smooth in 4-component vector of float)
0:? 'b' (layout(location=2 ) flat in bool)
@ -55,22 +54,21 @@ gl_FragCoord origin is upper left
0:39 Compare Equal (temp bool)
0:39 's3' (temp structure{temp 3-component vector of bool b3})
0:39 's3' (temp structure{temp 3-component vector of bool b3})
0:40 i: direct index for structure (temp 4-component vector of float)
0:40 s2: direct index for structure (layout(offset=48 ) uniform structure{temp 4-component vector of float i})
0:40 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(offset=48 ) uniform structure{temp 4-component vector of float i} s2, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:40 move second child to first child (temp 4-component vector of float)
0:40 i: direct index for structure (temp 4-component vector of float)
0:40 's2' (global structure{temp 4-component vector of float i})
0:40 Constant:
0:40 1 (const uint)
0:40 Constant:
0:40 0 (const int)
0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
0:40 0 (const int)
0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
0:42 Sequence
0:42 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:42 'input' (layout(location=0 ) in 4-component vector of float)
0:42 Branch: Return
0:? Linker Objects
0:? 's2' (global structure{temp 4-component vector of float i})
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'anon@0' (uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(offset=48 ) uniform structure{temp 4-component vector of float i} s2, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:? 'anon@0' (uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
0:? 'input' (layout(location=0 ) in 4-component vector of float)
0:? 'a' (layout(location=1 ) smooth in 4-component vector of float)
0:? 'b' (layout(location=2 ) flat in bool)
@ -83,103 +81,95 @@ gl_FragCoord origin is upper left
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 46
// Id's are bound by 49
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 29 31 32 35 37 39 42 43 44 45
EntryPoint Fragment 4 "PixelShaderFunction" 25 30 31 38 40 42 45 46 47 48
ExecutionMode 4 OriginUpperLeft
Name 4 "PixelShaderFunction"
Name 8 "FS"
MemberName 8(FS) 0 "b3"
Name 10 "s3"
Name 20 "myS"
MemberName 20(myS) 0 "b"
MemberName 20(myS) 1 "c"
MemberName 20(myS) 2 "a"
MemberName 20(myS) 3 "d"
Name 21 ""
MemberName 21 0 "i"
Name 22 "$Global"
MemberName 22($Global) 0 "s1"
MemberName 22($Global) 1 "s2"
MemberName 22($Global) 2 "ff5"
MemberName 22($Global) 3 "ff6"
Name 24 ""
Name 29 "ff4"
Name 31 "@entryPointOutput"
Name 32 "input"
Name 35 "a"
Name 37 "b"
Name 39 "c"
Name 42 "d"
Name 43 "ff1"
Name 44 "ff2"
Name 45 "ff3"
MemberDecorate 20(myS) 0 Offset 0
MemberDecorate 20(myS) 1 Offset 4
MemberDecorate 20(myS) 2 Offset 16
MemberDecorate 20(myS) 3 Offset 32
MemberDecorate 21 0 Offset 0
MemberDecorate 22($Global) 0 Offset 0
MemberDecorate 22($Global) 1 Offset 48
MemberDecorate 22($Global) 2 Offset 1620
MemberDecorate 22($Global) 3 Offset 1636
Decorate 22($Global) Block
Decorate 24 DescriptorSet 0
Decorate 29(ff4) Offset 4
Decorate 29(ff4) Location 7
Decorate 29(ff4) Binding 0
Decorate 31(@entryPointOutput) Location 0
Decorate 32(input) Location 0
Decorate 35(a) Location 1
Decorate 37(b) Flat
Decorate 37(b) Location 2
Decorate 39(c) NoPerspective
Decorate 39(c) Centroid
Decorate 39(c) Location 3
Decorate 42(d) Centroid
Decorate 42(d) Location 4
Decorate 43(ff1) BuiltIn FrontFacing
Decorate 44(ff2) Offset 4
Decorate 44(ff2) Location 5
Decorate 45(ff3) Offset 4
Decorate 45(ff3) Location 6
Decorate 45(ff3) Binding 0
Name 19 ""
MemberName 19 0 "i"
Name 21 "s2"
Name 25 "ff4"
Name 30 "@entryPointOutput"
Name 31 "input"
Name 34 "myS"
MemberName 34(myS) 0 "b"
MemberName 34(myS) 1 "c"
MemberName 34(myS) 2 "a"
MemberName 34(myS) 3 "d"
Name 35 "$Global"
MemberName 35($Global) 0 "s1"
MemberName 35($Global) 1 "ff5"
MemberName 35($Global) 2 "ff6"
Name 37 ""
Name 38 "a"
Name 40 "b"
Name 42 "c"
Name 45 "d"
Name 46 "ff1"
Name 47 "ff2"
Name 48 "ff3"
Decorate 25(ff4) Offset 4
Decorate 25(ff4) Location 7
Decorate 25(ff4) Binding 0
Decorate 30(@entryPointOutput) Location 0
Decorate 31(input) Location 0
Decorate 35($Global) Block
Decorate 37 DescriptorSet 0
Decorate 38(a) Location 1
Decorate 40(b) Flat
Decorate 40(b) Location 2
Decorate 42(c) NoPerspective
Decorate 42(c) Centroid
Decorate 42(c) Location 3
Decorate 45(d) Centroid
Decorate 45(d) Location 4
Decorate 46(ff1) BuiltIn FrontFacing
Decorate 47(ff2) Offset 4
Decorate 47(ff2) Location 5
Decorate 48(ff3) Offset 4
Decorate 48(ff3) Location 6
Decorate 48(ff3) Binding 0
2: TypeVoid
3: TypeFunction 2
6: TypeBool
7: TypeVector 6(bool) 3
8(FS): TypeStruct 7(bvec3)
9: TypePointer Function 8(FS)
17: TypeInt 32 0
18: TypeFloat 32
19: TypeVector 18(float) 4
20(myS): TypeStruct 17(int) 17(int) 19(fvec4) 19(fvec4)
21: TypeStruct 19(fvec4)
22($Global): TypeStruct 20(myS) 21(struct) 18(float) 18(float)
23: TypePointer Uniform 22($Global)
24: 23(ptr) Variable Uniform
25: TypeInt 32 1
26: 25(int) Constant 1
27: 25(int) Constant 0
28: TypePointer Input 19(fvec4)
29(ff4): 28(ptr) Variable Input
30: TypePointer Output 19(fvec4)
31(@entryPointOutput): 30(ptr) Variable Output
32(input): 28(ptr) Variable Input
35(a): 28(ptr) Variable Input
36: TypePointer Input 6(bool)
37(b): 36(ptr) Variable Input
38: TypePointer Input 18(float)
39(c): 38(ptr) Variable Input
40: TypeVector 18(float) 2
41: TypePointer Input 40(fvec2)
42(d): 41(ptr) Variable Input
43(ff1): 36(ptr) Variable Input
44(ff2): 36(ptr) Variable Input
45(ff3): 36(ptr) Variable Input
17: TypeFloat 32
18: TypeVector 17(float) 4
19: TypeStruct 18(fvec4)
20: TypePointer Private 19(struct)
21(s2): 20(ptr) Variable Private
22: TypeInt 32 1
23: 22(int) Constant 0
24: TypePointer Input 18(fvec4)
25(ff4): 24(ptr) Variable Input
27: TypePointer Private 18(fvec4)
29: TypePointer Output 18(fvec4)
30(@entryPointOutput): 29(ptr) Variable Output
31(input): 24(ptr) Variable Input
34(myS): TypeStruct 6(bool) 6(bool) 18(fvec4) 18(fvec4)
35($Global): TypeStruct 34(myS) 17(float) 17(float)
36: TypePointer Uniform 35($Global)
37: 36(ptr) Variable Uniform
38(a): 24(ptr) Variable Input
39: TypePointer Input 6(bool)
40(b): 39(ptr) Variable Input
41: TypePointer Input 17(float)
42(c): 41(ptr) Variable Input
43: TypeVector 17(float) 2
44: TypePointer Input 43(fvec2)
45(d): 44(ptr) Variable Input
46(ff1): 39(ptr) Variable Input
47(ff2): 39(ptr) Variable Input
48(ff3): 39(ptr) Variable Input
4(PixelShaderFunction): 2 Function None 3
5: Label
10(s3): 9(ptr) Variable Function
@ -189,7 +179,10 @@ gl_FragCoord origin is upper left
14: 7(bvec3) CompositeExtract 12 0
15: 7(bvec3) LogicalEqual 13 14
16: 6(bool) All 15
33: 19(fvec4) Load 32(input)
Store 31(@entryPointOutput) 33
26: 18(fvec4) Load 25(ff4)
28: 27(ptr) AccessChain 21(s2) 23
Store 28 26
32: 18(fvec4) Load 31(input)
Store 30(@entryPointOutput) 32
Return
FunctionEnd

View File

@ -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;
}

View File

@ -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;
@ -172,6 +166,56 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
return node;
}
//
// 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.
//
@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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
}