HLSL: Implement ?: grammar productions.

Missing are implicit conversions between int/bool/etc.
This commit is contained in:
John Kessenich 2016-07-27 10:39:57 -06:00
parent b783d712ab
commit 00957f8110
5 changed files with 423 additions and 7 deletions

View File

@ -0,0 +1,357 @@
hlsl.conditional.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:17 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
0:2 Function Parameters:
0:2 'input' (in 4-component vector of float)
0:? Sequence
0:3 Sequence
0:3 move second child to first child (temp int)
0:3 'a' (temp int)
0:3 Constant:
0:3 5 (const int)
0:4 Sequence
0:4 move second child to first child (temp int)
0:4 'b' (temp int)
0:4 Constant:
0:4 6 (const int)
0:5 Sequence
0:5 move second child to first child (temp int)
0:5 'c' (temp int)
0:5 Constant:
0:5 7 (const int)
0:6 Sequence
0:6 move second child to first child (temp int)
0:6 'd' (temp int)
0:6 Constant:
0:6 7 (const int)
0:7 Sequence
0:7 move second child to first child (temp 4-component vector of float)
0:7 'ret' (temp 4-component vector of float)
0:8 add (temp 4-component vector of float)
0:7 add (temp 4-component vector of float)
0:7 vector-scale (temp 4-component vector of float)
0:7 Convert int to float (temp float)
0:7 'a' (temp int)
0:7 'input' (in 4-component vector of float)
0:8 vector-scale (temp 4-component vector of float)
0:8 Convert int to float (temp float)
0:8 'b' (temp int)
0:8 'input' (in 4-component vector of float)
0:9 add (temp 4-component vector of float)
0:9 vector-scale (temp 4-component vector of float)
0:9 Convert int to float (temp float)
0:9 'c' (temp int)
0:9 'input' (in 4-component vector of float)
0:10 vector-scale (temp 4-component vector of float)
0:10 Convert int to float (temp float)
0:10 'd' (temp int)
0:10 'input' (in 4-component vector of float)
0:12 Comma (temp int)
0:12 move second child to first child (temp int)
0:12 'e' (temp int)
0:12 move second child to first child (temp int)
0:12 'a' (temp int)
0:12 Test condition and select (temp int)
0:12 Condition
0:12 'b' (temp int)
0:12 true case
0:12 move second child to first child (temp int)
0:12 'c' (temp int)
0:12 'd' (temp int)
0:12 false case
0:12 Constant:
0:12 10 (const int)
0:12 move second child to first child (temp int)
0:12 'b' (temp int)
0:12 Test condition and select (temp int)
0:12 Condition
0:12 'a' (temp int)
0:12 true case
0:12 move second child to first child (temp int)
0:12 'd' (temp int)
0:12 'c' (temp int)
0:12 false case
0:12 Constant:
0:12 11 (const int)
0:14 move second child to first child (temp 4-component vector of float)
0:14 'f' (temp 4-component vector of float)
0:14 Test condition and select (temp 4-component vector of float)
0:14 Condition
0:14 Compare Less Than (temp bool)
0:14 direct index (temp float)
0:14 'ret' (temp 4-component vector of float)
0:14 Constant:
0:14 0 (const int)
0:14 direct index (temp float)
0:14 'input' (in 4-component vector of float)
0:14 Constant:
0:14 1 (const int)
0:14 true case
0:14 vector-scale (temp 4-component vector of float)
0:14 Convert int to float (temp float)
0:14 'c' (temp int)
0:14 'input' (in 4-component vector of float)
0:14 false case
0:14 vector-scale (temp 4-component vector of float)
0:14 Convert int to float (temp float)
0:14 'd' (temp int)
0:14 'input' (in 4-component vector of float)
0:15 Branch: Return with expression
0:15 add (temp 4-component vector of float)
0:15 vector-scale (temp 4-component vector of float)
0:15 Convert int to float (temp float)
0:15 'e' (temp int)
0:15 'ret' (temp 4-component vector of float)
0:15 'f' (temp 4-component vector of float)
0:? Linker Objects
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:17 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
0:2 Function Parameters:
0:2 'input' (in 4-component vector of float)
0:? Sequence
0:3 Sequence
0:3 move second child to first child (temp int)
0:3 'a' (temp int)
0:3 Constant:
0:3 5 (const int)
0:4 Sequence
0:4 move second child to first child (temp int)
0:4 'b' (temp int)
0:4 Constant:
0:4 6 (const int)
0:5 Sequence
0:5 move second child to first child (temp int)
0:5 'c' (temp int)
0:5 Constant:
0:5 7 (const int)
0:6 Sequence
0:6 move second child to first child (temp int)
0:6 'd' (temp int)
0:6 Constant:
0:6 7 (const int)
0:7 Sequence
0:7 move second child to first child (temp 4-component vector of float)
0:7 'ret' (temp 4-component vector of float)
0:8 add (temp 4-component vector of float)
0:7 add (temp 4-component vector of float)
0:7 vector-scale (temp 4-component vector of float)
0:7 Convert int to float (temp float)
0:7 'a' (temp int)
0:7 'input' (in 4-component vector of float)
0:8 vector-scale (temp 4-component vector of float)
0:8 Convert int to float (temp float)
0:8 'b' (temp int)
0:8 'input' (in 4-component vector of float)
0:9 add (temp 4-component vector of float)
0:9 vector-scale (temp 4-component vector of float)
0:9 Convert int to float (temp float)
0:9 'c' (temp int)
0:9 'input' (in 4-component vector of float)
0:10 vector-scale (temp 4-component vector of float)
0:10 Convert int to float (temp float)
0:10 'd' (temp int)
0:10 'input' (in 4-component vector of float)
0:12 Comma (temp int)
0:12 move second child to first child (temp int)
0:12 'e' (temp int)
0:12 move second child to first child (temp int)
0:12 'a' (temp int)
0:12 Test condition and select (temp int)
0:12 Condition
0:12 'b' (temp int)
0:12 true case
0:12 move second child to first child (temp int)
0:12 'c' (temp int)
0:12 'd' (temp int)
0:12 false case
0:12 Constant:
0:12 10 (const int)
0:12 move second child to first child (temp int)
0:12 'b' (temp int)
0:12 Test condition and select (temp int)
0:12 Condition
0:12 'a' (temp int)
0:12 true case
0:12 move second child to first child (temp int)
0:12 'd' (temp int)
0:12 'c' (temp int)
0:12 false case
0:12 Constant:
0:12 11 (const int)
0:14 move second child to first child (temp 4-component vector of float)
0:14 'f' (temp 4-component vector of float)
0:14 Test condition and select (temp 4-component vector of float)
0:14 Condition
0:14 Compare Less Than (temp bool)
0:14 direct index (temp float)
0:14 'ret' (temp 4-component vector of float)
0:14 Constant:
0:14 0 (const int)
0:14 direct index (temp float)
0:14 'input' (in 4-component vector of float)
0:14 Constant:
0:14 1 (const int)
0:14 true case
0:14 vector-scale (temp 4-component vector of float)
0:14 Convert int to float (temp float)
0:14 'c' (temp int)
0:14 'input' (in 4-component vector of float)
0:14 false case
0:14 vector-scale (temp 4-component vector of float)
0:14 Convert int to float (temp float)
0:14 'd' (temp int)
0:14 'input' (in 4-component vector of float)
0:15 Branch: Return with expression
0:15 add (temp 4-component vector of float)
0:15 vector-scale (temp 4-component vector of float)
0:15 Convert int to float (temp float)
0:15 'e' (temp int)
0:15 'ret' (temp 4-component vector of float)
0:15 'f' (temp 4-component vector of float)
0:? Linker Objects
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 89
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 22
ExecutionMode 4 OriginUpperLeft
Source HLSL 450
Name 4 "PixelShaderFunction"
Name 8 "a"
Name 10 "b"
Name 12 "c"
Name 14 "d"
Name 18 "ret"
Name 22 "input"
Name 40 "e"
Name 57 "f"
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypePointer Function 6(int)
9: 6(int) Constant 5
11: 6(int) Constant 6
13: 6(int) Constant 7
15: TypeFloat 32
16: TypeVector 15(float) 4
17: TypePointer Function 16(fvec4)
21: TypePointer Input 16(fvec4)
22(input): 21(ptr) Variable Input
47: 6(int) Constant 10
55: 6(int) Constant 11
59: TypeInt 32 0
60: 59(int) Constant 0
61: TypePointer Function 15(float)
64: 59(int) Constant 1
65: TypePointer Input 15(float)
68: TypeBool
4(PixelShaderFunction): 2 Function None 3
5: Label
8(a): 7(ptr) Variable Function
10(b): 7(ptr) Variable Function
12(c): 7(ptr) Variable Function
14(d): 7(ptr) Variable Function
18(ret): 17(ptr) Variable Function
40(e): 7(ptr) Variable Function
41: 7(ptr) Variable Function
49: 7(ptr) Variable Function
57(f): 17(ptr) Variable Function
58: 17(ptr) Variable Function
Store 8(a) 9
Store 10(b) 11
Store 12(c) 13
Store 14(d) 13
19: 6(int) Load 8(a)
20: 15(float) ConvertSToF 19
23: 16(fvec4) Load 22(input)
24: 16(fvec4) VectorTimesScalar 23 20
25: 6(int) Load 10(b)
26: 15(float) ConvertSToF 25
27: 16(fvec4) Load 22(input)
28: 16(fvec4) VectorTimesScalar 27 26
29: 16(fvec4) FAdd 24 28
30: 6(int) Load 12(c)
31: 15(float) ConvertSToF 30
32: 16(fvec4) Load 22(input)
33: 16(fvec4) VectorTimesScalar 32 31
34: 6(int) Load 14(d)
35: 15(float) ConvertSToF 34
36: 16(fvec4) Load 22(input)
37: 16(fvec4) VectorTimesScalar 36 35
38: 16(fvec4) FAdd 33 37
39: 16(fvec4) FAdd 29 38
Store 18(ret) 39
42: 6(int) Load 10(b)
SelectionMerge 44 None
BranchConditional 42 43 46
43: Label
45: 6(int) Load 14(d)
Store 12(c) 45
Store 41 45
Branch 44
46: Label
Store 41 47
Branch 44
44: Label
48: 6(int) Load 41
Store 8(a) 48
Store 40(e) 48
50: 6(int) Load 8(a)
SelectionMerge 52 None
BranchConditional 50 51 54
51: Label
53: 6(int) Load 12(c)
Store 14(d) 53
Store 49 53
Branch 52
54: Label
Store 49 55
Branch 52
52: Label
56: 6(int) Load 49
Store 10(b) 56
62: 61(ptr) AccessChain 18(ret) 60
63: 15(float) Load 62
66: 65(ptr) AccessChain 22(input) 64
67: 15(float) Load 66
69: 68(bool) FOrdLessThan 63 67
SelectionMerge 71 None
BranchConditional 69 70 76
70: Label
72: 6(int) Load 12(c)
73: 15(float) ConvertSToF 72
74: 16(fvec4) Load 22(input)
75: 16(fvec4) VectorTimesScalar 74 73
Store 58 75
Branch 71
76: Label
77: 6(int) Load 14(d)
78: 15(float) ConvertSToF 77
79: 16(fvec4) Load 22(input)
80: 16(fvec4) VectorTimesScalar 79 78
Store 58 80
Branch 71
71: Label
81: 16(fvec4) Load 58
Store 57(f) 81
82: 6(int) Load 40(e)
83: 15(float) ConvertSToF 82
84: 16(fvec4) Load 18(ret)
85: 16(fvec4) VectorTimesScalar 84 83
86: 16(fvec4) Load 57(f)
87: 16(fvec4) FAdd 85 86
ReturnValue 87
FunctionEnd

View File

@ -0,0 +1,16 @@
float4 PixelShaderFunction(float4 input) : COLOR0
{
int a = 1 < 2 ? 3 < 4 ? 5 : 6 : 7;
int b = 1 < 2 ? 3 > 4 ? 5 : 6 : 7;
int c = 1 > 2 ? 3 > 4 ? 5 : 6 : 7;
int d = 1 > 2 ? 3 < 4 ? 5 : 6 : 7;
float4 ret = a * input +
b * input +
c * input +
d * input;
int e;
e = a = b ? c = d : 10, b = a ? d = c : 11;
float4 f;
f = ret.x < input.y ? c * input : d * input;
return e * ret + f;
}

View File

@ -77,6 +77,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.attribute.frag", "PixelShaderFunction"},
{"hlsl.buffer.frag", "PixelShaderFunction"},
{"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.conditional.frag", "PixelShaderFunction"},
{"hlsl.discard.frag", "PixelShaderFunction"},
{"hlsl.doLoop.frag", "PixelShaderFunction"},
{"hlsl.float1.frag", "PixelShaderFunction"},

View File

@ -1548,8 +1548,9 @@ bool HlslGrammar::acceptInitializer(TIntermTyped*& node)
// a op (b op (c op d))
//
// assigment_expression
// : binary_expression op binary_expression op binary_expression ...
// | initializer
// : initializer
// | conditional_expression
// | conditional_expression assign_op conditional_expression assign_op conditional_expression ...
//
bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
{
@ -1562,8 +1563,8 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
return false;
}
// binary_expression
if (! acceptBinaryExpression(node, PlLogicalOr))
// conditional_expression
if (! acceptConditionalExpression(node))
return false;
// assignment operation?
@ -1571,12 +1572,12 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
if (assignOp == EOpNull)
return true;
// assignment op
// assign_op
TSourceLoc loc = token.loc;
advanceToken();
// binary_expression
// But, done by recursing this function, which automatically
// conditional_expression assign_op conditional_expression ...
// Done by recursing this function, which automatically
// gets the right-to-left associativity.
TIntermTyped* rightNode = nullptr;
if (! acceptAssignmentExpression(rightNode)) {
@ -1595,6 +1596,46 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
return true;
}
// Accept a conditional expression, which associates right-to-left,
// accomplished by the "true" expression calling down to lower
// precedence levels than this level.
//
// conditional_expression
// : binary_expression
// | binary_expression QUESTION expression COLON assignment_expression
//
bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
{
// binary_expression
if (! acceptBinaryExpression(node, PlLogicalOr))
return false;
if (! acceptTokenClass(EHTokQuestion))
return true;
TIntermTyped* trueNode = nullptr;
if (! acceptExpression(trueNode)) {
expected("expression after ?");
return false;
}
TSourceLoc loc = token.loc;
if (! acceptTokenClass(EHTokColon)) {
expected(":");
return false;
}
TIntermTyped* falseNode = nullptr;
if (! acceptAssignmentExpression(falseNode)) {
expected("expression after :");
return false;
}
node = intermediate.addSelection(node, trueNode, falseNode, loc);
return true;
}
// Accept a binary expression, for binary operations that
// associate left-to-right. This is, it is implicit, for example
//

View File

@ -83,6 +83,7 @@ namespace glslang {
bool acceptExpression(TIntermTyped*&);
bool acceptInitializer(TIntermTyped*&);
bool acceptAssignmentExpression(TIntermTyped*&);
bool acceptConditionalExpression(TIntermTyped*&);
bool acceptBinaryExpression(TIntermTyped*&, PrecedenceLevel);
bool acceptUnaryExpression(TIntermTyped*&);
bool acceptPostfixExpression(TIntermTyped*&);