Merge pull request #722 from steve-lunarg/tessellation

Add basic HS/DS implementation.
This commit is contained in:
John Kessenich 2017-02-10 18:10:46 -07:00 committed by GitHub
commit e4e8f7b7a3
18 changed files with 1562 additions and 11 deletions

View File

@ -0,0 +1,359 @@
hlsl.hull.1.tesc
Shader version: 450
vertices = 4
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[4];u1; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 'm_cpid' (in uint)
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp uint)
0:? 'm_cpid' (temp uint)
0:? 'm_cpid' (in uint InvocationID)
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'm_cpid' (temp uint)
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'm_cpid' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Sequence
0:? move second child to first child (temp structure{temp 2-element array of float edges})
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Function Call: PCF(u1; (temp structure{temp 2-element array of float edges})
0:? 'pid' (in uint PrimitiveID)
0:? Sequence
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 0 (const int)
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 1 (const int)
0:33 Function Definition: PCF(u1; (temp structure{temp 2-element array of float edges})
0:33 Function Parameters:
0:33 'pid' (in uint)
0:? Sequence
0:36 move second child to first child (temp float)
0:36 direct index (temp float)
0:36 edges: direct index for structure (temp 2-element array of float)
0:36 'output' (temp structure{temp 2-element array of float edges})
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 2.000000
0:37 move second child to first child (temp float)
0:37 direct index (temp float)
0:37 edges: direct index for structure (temp 2-element array of float)
0:37 'output' (temp structure{temp 2-element array of float edges})
0:37 Constant:
0:37 0 (const int)
0:37 Constant:
0:37 1 (const int)
0:37 Constant:
0:37 8.000000
0:38 Branch: Return with expression
0:38 'output' (temp structure{temp 2-element array of float edges})
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'm_cpid' (in uint InvocationID)
0:? 'pid' (in uint PrimitiveID)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
Linked tessellation control stage:
Shader version: 450
vertices = 4
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[4];u1; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 'm_cpid' (in uint)
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp uint)
0:? 'm_cpid' (temp uint)
0:? 'm_cpid' (in uint InvocationID)
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[4];u1; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'm_cpid' (temp uint)
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'm_cpid' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Sequence
0:? move second child to first child (temp structure{temp 2-element array of float edges})
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Function Call: PCF(u1; (temp structure{temp 2-element array of float edges})
0:? 'pid' (in uint PrimitiveID)
0:? Sequence
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 0 (const int)
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 1 (const int)
0:33 Function Definition: PCF(u1; (temp structure{temp 2-element array of float edges})
0:33 Function Parameters:
0:33 'pid' (in uint)
0:? Sequence
0:36 move second child to first child (temp float)
0:36 direct index (temp float)
0:36 edges: direct index for structure (temp 2-element array of float)
0:36 'output' (temp structure{temp 2-element array of float edges})
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 2.000000
0:37 move second child to first child (temp float)
0:37 direct index (temp float)
0:37 edges: direct index for structure (temp 2-element array of float)
0:37 'output' (temp structure{temp 2-element array of float edges})
0:37 Constant:
0:37 0 (const int)
0:37 Constant:
0:37 1 (const int)
0:37 Constant:
0:37 8.000000
0:38 Branch: Return with expression
0:38 'output' (temp structure{temp 2-element array of float edges})
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'm_cpid' (in uint InvocationID)
0:? 'pid' (in uint PrimitiveID)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 85
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint TessellationControl 4 "main" 40 44 47 62 67
ExecutionMode 4 OutputVertices 4
Name 4 "main"
Name 8 "VS_OUT"
MemberName 8(VS_OUT) 0 "cpoint"
Name 14 "HS_OUT"
MemberName 14(HS_OUT) 0 "cpoint"
Name 18 "@main(struct-VS_OUT-vf31[4];u1;"
Name 16 "ip"
Name 17 "m_cpid"
Name 22 "HS_CONSTANT_OUT"
MemberName 22(HS_CONSTANT_OUT) 0 "edges"
Name 25 "PCF(u1;"
Name 24 "pid"
Name 28 "output"
Name 38 "ip"
Name 40 "ip"
Name 42 "m_cpid"
Name 44 "m_cpid"
Name 47 "@entryPointOutput"
Name 48 "param"
Name 50 "param"
Name 61 "@patchConstantResult"
Name 62 "pid"
Name 63 "param"
Name 67 "@patchConstantOutput_edges"
Name 77 "output"
Decorate 40(ip) Location 0
Decorate 44(m_cpid) BuiltIn InvocationId
Decorate 47(@entryPointOutput) Location 0
Decorate 62(pid) BuiltIn PrimitiveId
Decorate 67(@patchConstantOutput_edges) BuiltIn TessLevelOuter
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8(VS_OUT): TypeStruct 7(fvec3)
9: TypeInt 32 0
10: 9(int) Constant 4
11: TypeArray 8(VS_OUT) 10
12: TypePointer Function 11
13: TypePointer Function 9(int)
14(HS_OUT): TypeStruct 7(fvec3)
15: TypeFunction 14(HS_OUT) 12(ptr) 13(ptr)
20: 9(int) Constant 2
21: TypeArray 6(float) 20
22(HS_CONSTANT_OUT): TypeStruct 21
23: TypeFunction 22(HS_CONSTANT_OUT) 13(ptr)
27: TypePointer Function 14(HS_OUT)
29: TypeInt 32 1
30: 29(int) Constant 0
31: TypePointer Function 7(fvec3)
39: TypePointer Input 11
40(ip): 39(ptr) Variable Input
43: TypePointer Input 9(int)
44(m_cpid): 43(ptr) Variable Input
46: TypePointer Output 14(HS_OUT)
47(@entryPointOutput): 46(ptr) Variable Output
53: 9(int) Constant 1
54: 9(int) Constant 0
56: TypeBool
60: TypePointer Function 22(HS_CONSTANT_OUT)
62(pid): 43(ptr) Variable Input
66: TypePointer Output 21
67(@patchConstantOutput_edges): 66(ptr) Variable Output
68: TypePointer Function 6(float)
71: TypePointer Output 6(float)
73: 29(int) Constant 1
78: 6(float) Constant 1073741824
80: 6(float) Constant 1090519040
4(main): 2 Function None 3
5: Label
38(ip): 12(ptr) Variable Function
42(m_cpid): 13(ptr) Variable Function
48(param): 12(ptr) Variable Function
50(param): 13(ptr) Variable Function
61(@patchConstantResult): 60(ptr) Variable Function
63(param): 13(ptr) Variable Function
41: 11 Load 40(ip)
Store 38(ip) 41
45: 9(int) Load 44(m_cpid)
Store 42(m_cpid) 45
49: 11 Load 38(ip)
Store 48(param) 49
51: 9(int) Load 42(m_cpid)
Store 50(param) 51
52: 14(HS_OUT) FunctionCall 18(@main(struct-VS_OUT-vf31[4];u1;) 48(param) 50(param)
Store 47(@entryPointOutput) 52
ControlBarrier 20 53 54
55: 9(int) Load 44(m_cpid)
57: 56(bool) IEqual 55 30
SelectionMerge 59 None
BranchConditional 57 58 59
58: Label
64: 9(int) Load 62(pid)
Store 63(param) 64
65:22(HS_CONSTANT_OUT) FunctionCall 25(PCF(u1;) 63(param)
Store 61(@patchConstantResult) 65
69: 68(ptr) AccessChain 61(@patchConstantResult) 30 30
70: 6(float) Load 69
72: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 30
Store 72 70
74: 68(ptr) AccessChain 61(@patchConstantResult) 30 73
75: 6(float) Load 74
76: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 73
Store 76 75
Branch 59
59: Label
Return
FunctionEnd
18(@main(struct-VS_OUT-vf31[4];u1;): 14(HS_OUT) Function None 15
16(ip): 12(ptr) FunctionParameter
17(m_cpid): 13(ptr) FunctionParameter
19: Label
28(output): 27(ptr) Variable Function
32: 31(ptr) AccessChain 16(ip) 30 30
33: 7(fvec3) Load 32
34: 31(ptr) AccessChain 28(output) 30
Store 34 33
35: 14(HS_OUT) Load 28(output)
ReturnValue 35
FunctionEnd
25(PCF(u1;):22(HS_CONSTANT_OUT) Function None 23
24(pid): 13(ptr) FunctionParameter
26: Label
77(output): 60(ptr) Variable Function
79: 68(ptr) AccessChain 77(output) 30 30
Store 79 78
81: 68(ptr) AccessChain 77(output) 30 73
Store 81 80
82:22(HS_CONSTANT_OUT) Load 77(output)
ReturnValue 82
FunctionEnd

View File

@ -0,0 +1,357 @@
hlsl.hull.2.tesc
Shader version: 450
vertices = 4
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[4]; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'InvocationId' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Sequence
0:? move second child to first child (temp structure{temp 2-element array of float edges})
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Function Call: PCF(u1;vf4; (temp structure{temp 2-element array of float edges})
0:? 'pid' (in uint PrimitiveID)
0:? 'pos' (in 4-component vector of float Position)
0:? Sequence
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 0 (const int)
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 1 (const int)
0:33 Function Definition: PCF(u1;vf4; (temp structure{temp 2-element array of float edges})
0:33 Function Parameters:
0:33 'pid' (in uint)
0:33 'pos' (in 4-component vector of float)
0:? Sequence
0:36 move second child to first child (temp float)
0:36 direct index (temp float)
0:36 edges: direct index for structure (temp 2-element array of float)
0:36 'output' (temp structure{temp 2-element array of float edges})
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 2.000000
0:37 move second child to first child (temp float)
0:37 direct index (temp float)
0:37 edges: direct index for structure (temp 2-element array of float)
0:37 'output' (temp structure{temp 2-element array of float edges})
0:37 Constant:
0:37 0 (const int)
0:37 Constant:
0:37 1 (const int)
0:37 Constant:
0:37 8.000000
0:38 Branch: Return with expression
0:38 'output' (temp structure{temp 2-element array of float edges})
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'pid' (in uint PrimitiveID)
0:? 'pos' (in 4-component vector of float Position)
0:? 'InvocationId' (in uint InvocationID)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
Linked tessellation control stage:
Shader version: 450
vertices = 4
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[4]; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 4-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[4]; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 4-element array of structure{temp 3-component vector of float cpoint})
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'InvocationId' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Sequence
0:? move second child to first child (temp structure{temp 2-element array of float edges})
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Function Call: PCF(u1;vf4; (temp structure{temp 2-element array of float edges})
0:? 'pid' (in uint PrimitiveID)
0:? 'pos' (in 4-component vector of float Position)
0:? Sequence
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 0 (const int)
0:? move second child to first child (temp float)
0:? direct index (out float TessLevelOuter)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index (temp float)
0:? edges: direct index for structure (temp 2-element array of float)
0:? '@patchConstantResult' (temp structure{temp 2-element array of float edges})
0:? Constant:
0:? 0 (const int)
0:? Constant:
0:? 1 (const int)
0:33 Function Definition: PCF(u1;vf4; (temp structure{temp 2-element array of float edges})
0:33 Function Parameters:
0:33 'pid' (in uint)
0:33 'pos' (in 4-component vector of float)
0:? Sequence
0:36 move second child to first child (temp float)
0:36 direct index (temp float)
0:36 edges: direct index for structure (temp 2-element array of float)
0:36 'output' (temp structure{temp 2-element array of float edges})
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 0 (const int)
0:36 Constant:
0:36 2.000000
0:37 move second child to first child (temp float)
0:37 direct index (temp float)
0:37 edges: direct index for structure (temp 2-element array of float)
0:37 'output' (temp structure{temp 2-element array of float edges})
0:37 Constant:
0:37 0 (const int)
0:37 Constant:
0:37 1 (const int)
0:37 Constant:
0:37 8.000000
0:38 Branch: Return with expression
0:38 'output' (temp structure{temp 2-element array of float edges})
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 4-element array of structure{temp 3-component vector of float cpoint})
0:? 'pid' (in uint PrimitiveID)
0:? 'pos' (in 4-component vector of float Position)
0:? 'InvocationId' (in uint InvocationID)
0:? '@patchConstantOutput_edges' (out 2-element array of float TessLevelOuter)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 87
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint TessellationControl 4 "main" 42 45 52 60 62 69
ExecutionMode 4 OutputVertices 4
Name 4 "main"
Name 8 "VS_OUT"
MemberName 8(VS_OUT) 0 "cpoint"
Name 13 "HS_OUT"
MemberName 13(HS_OUT) 0 "cpoint"
Name 16 "@main(struct-VS_OUT-vf31[4];"
Name 15 "ip"
Name 23 "HS_CONSTANT_OUT"
MemberName 23(HS_CONSTANT_OUT) 0 "edges"
Name 27 "PCF(u1;vf4;"
Name 25 "pid"
Name 26 "pos"
Name 30 "output"
Name 40 "ip"
Name 42 "ip"
Name 45 "@entryPointOutput"
Name 46 "param"
Name 52 "InvocationId"
Name 59 "@patchConstantResult"
Name 60 "pid"
Name 62 "pos"
Name 63 "param"
Name 65 "param"
Name 69 "@patchConstantOutput_edges"
Name 79 "output"
Decorate 42(ip) Location 0
Decorate 45(@entryPointOutput) Location 0
Decorate 52(InvocationId) BuiltIn InvocationId
Decorate 60(pid) BuiltIn PrimitiveId
Decorate 62(pos) BuiltIn Position
Decorate 69(@patchConstantOutput_edges) BuiltIn TessLevelOuter
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8(VS_OUT): TypeStruct 7(fvec3)
9: TypeInt 32 0
10: 9(int) Constant 4
11: TypeArray 8(VS_OUT) 10
12: TypePointer Function 11
13(HS_OUT): TypeStruct 7(fvec3)
14: TypeFunction 13(HS_OUT) 12(ptr)
18: TypePointer Function 9(int)
19: TypeVector 6(float) 4
20: TypePointer Function 19(fvec4)
21: 9(int) Constant 2
22: TypeArray 6(float) 21
23(HS_CONSTANT_OUT): TypeStruct 22
24: TypeFunction 23(HS_CONSTANT_OUT) 18(ptr) 20(ptr)
29: TypePointer Function 13(HS_OUT)
31: TypeInt 32 1
32: 31(int) Constant 0
33: TypePointer Function 7(fvec3)
41: TypePointer Input 11
42(ip): 41(ptr) Variable Input
44: TypePointer Output 13(HS_OUT)
45(@entryPointOutput): 44(ptr) Variable Output
49: 9(int) Constant 1
50: 9(int) Constant 0
51: TypePointer Input 9(int)
52(InvocationId): 51(ptr) Variable Input
54: TypeBool
58: TypePointer Function 23(HS_CONSTANT_OUT)
60(pid): 51(ptr) Variable Input
61: TypePointer Input 19(fvec4)
62(pos): 61(ptr) Variable Input
68: TypePointer Output 22
69(@patchConstantOutput_edges): 68(ptr) Variable Output
70: TypePointer Function 6(float)
73: TypePointer Output 6(float)
75: 31(int) Constant 1
80: 6(float) Constant 1073741824
82: 6(float) Constant 1090519040
4(main): 2 Function None 3
5: Label
40(ip): 12(ptr) Variable Function
46(param): 12(ptr) Variable Function
59(@patchConstantResult): 58(ptr) Variable Function
63(param): 18(ptr) Variable Function
65(param): 20(ptr) Variable Function
43: 11 Load 42(ip)
Store 40(ip) 43
47: 11 Load 40(ip)
Store 46(param) 47
48: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[4];) 46(param)
Store 45(@entryPointOutput) 48
ControlBarrier 21 49 50
53: 9(int) Load 52(InvocationId)
55: 54(bool) IEqual 53 32
SelectionMerge 57 None
BranchConditional 55 56 57
56: Label
64: 9(int) Load 60(pid)
Store 63(param) 64
66: 19(fvec4) Load 62(pos)
Store 65(param) 66
67:23(HS_CONSTANT_OUT) FunctionCall 27(PCF(u1;vf4;) 63(param) 65(param)
Store 59(@patchConstantResult) 67
71: 70(ptr) AccessChain 59(@patchConstantResult) 32 32
72: 6(float) Load 71
74: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 32
Store 74 72
76: 70(ptr) AccessChain 59(@patchConstantResult) 32 75
77: 6(float) Load 76
78: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 75
Store 78 77
Branch 57
57: Label
Return
FunctionEnd
16(@main(struct-VS_OUT-vf31[4];): 13(HS_OUT) Function None 14
15(ip): 12(ptr) FunctionParameter
17: Label
30(output): 29(ptr) Variable Function
34: 33(ptr) AccessChain 15(ip) 32 32
35: 7(fvec3) Load 34
36: 33(ptr) AccessChain 30(output) 32
Store 36 35
37: 13(HS_OUT) Load 30(output)
ReturnValue 37
FunctionEnd
27(PCF(u1;vf4;):23(HS_CONSTANT_OUT) Function None 24
25(pid): 18(ptr) FunctionParameter
26(pos): 20(ptr) FunctionParameter
28: Label
79(output): 58(ptr) Variable Function
81: 70(ptr) AccessChain 79(output) 32 32
Store 81 80
83: 70(ptr) AccessChain 79(output) 32 75
Store 83 82
84:23(HS_CONSTANT_OUT) Load 79(output)
ReturnValue 84
FunctionEnd

View File

@ -0,0 +1,186 @@
hlsl.hull.void.tesc
Shader version: 450
vertices = 3
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 3-element array of structure{temp 3-component vector of float cpoint})
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 3-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 3-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'InvocationId' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Function Call: PCF( (temp void)
0:33 Function Definition: PCF( (temp void)
0:33 Function Parameters:
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'InvocationId' (in uint InvocationID)
Linked tessellation control stage:
Shader version: 450
vertices = 3
0:? Sequence
0:26 Function Definition: @main(struct-VS_OUT-vf31[3]; (temp structure{temp 3-component vector of float cpoint})
0:26 Function Parameters:
0:26 'ip' (in 3-element array of structure{temp 3-component vector of float cpoint})
0:? Sequence
0:28 move second child to first child (temp 3-component vector of float)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 'output' (temp structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 cpoint: direct index for structure (temp 3-component vector of float)
0:28 direct index (temp structure{temp 3-component vector of float cpoint})
0:28 'ip' (in 3-element array of structure{temp 3-component vector of float cpoint})
0:28 Constant:
0:28 0 (const int)
0:28 Constant:
0:28 0 (const int)
0:29 Branch: Return with expression
0:29 'output' (temp structure{temp 3-component vector of float cpoint})
0:26 Function Definition: main( (temp void)
0:26 Function Parameters:
0:? Sequence
0:26 move second child to first child (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 3-element array of structure{temp 3-component vector of float cpoint})
0:26 move second child to first child (temp structure{temp 3-component vector of float cpoint})
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:26 Function Call: @main(struct-VS_OUT-vf31[3]; (temp structure{temp 3-component vector of float cpoint})
0:? 'ip' (temp 3-element array of structure{temp 3-component vector of float cpoint})
0:? Barrier (temp void)
0:? Test condition and select (temp void)
0:? Condition
0:? Compare Equal (temp bool)
0:? 'InvocationId' (in uint InvocationID)
0:? Constant:
0:? 0 (const int)
0:? true case
0:? Function Call: PCF( (temp void)
0:33 Function Definition: PCF( (temp void)
0:33 Function Parameters:
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out structure{temp 3-component vector of float cpoint})
0:? 'ip' (layout(location=0 ) in 3-element array of structure{temp 3-component vector of float cpoint})
0:? 'InvocationId' (in uint InvocationID)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 51
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint TessellationControl 4 "main" 33 36 44
ExecutionMode 4 OutputVertices 3
Name 4 "main"
Name 8 "VS_OUT"
MemberName 8(VS_OUT) 0 "cpoint"
Name 13 "HS_OUT"
MemberName 13(HS_OUT) 0 "cpoint"
Name 16 "@main(struct-VS_OUT-vf31[3];"
Name 15 "ip"
Name 18 "PCF("
Name 21 "output"
Name 31 "ip"
Name 33 "ip"
Name 36 "@entryPointOutput"
Name 37 "param"
Name 44 "InvocationId"
Decorate 33(ip) Location 0
Decorate 36(@entryPointOutput) Location 0
Decorate 44(InvocationId) BuiltIn InvocationId
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 3
8(VS_OUT): TypeStruct 7(fvec3)
9: TypeInt 32 0
10: 9(int) Constant 3
11: TypeArray 8(VS_OUT) 10
12: TypePointer Function 11
13(HS_OUT): TypeStruct 7(fvec3)
14: TypeFunction 13(HS_OUT) 12(ptr)
20: TypePointer Function 13(HS_OUT)
22: TypeInt 32 1
23: 22(int) Constant 0
24: TypePointer Function 7(fvec3)
32: TypePointer Input 11
33(ip): 32(ptr) Variable Input
35: TypePointer Output 13(HS_OUT)
36(@entryPointOutput): 35(ptr) Variable Output
40: 9(int) Constant 2
41: 9(int) Constant 1
42: 9(int) Constant 0
43: TypePointer Input 9(int)
44(InvocationId): 43(ptr) Variable Input
46: TypeBool
4(main): 2 Function None 3
5: Label
31(ip): 12(ptr) Variable Function
37(param): 12(ptr) Variable Function
34: 11 Load 33(ip)
Store 31(ip) 34
38: 11 Load 31(ip)
Store 37(param) 38
39: 13(HS_OUT) FunctionCall 16(@main(struct-VS_OUT-vf31[3];) 37(param)
Store 36(@entryPointOutput) 39
ControlBarrier 40 41 42
45: 9(int) Load 44(InvocationId)
47: 46(bool) IEqual 45 23
SelectionMerge 49 None
BranchConditional 47 48 49
48: Label
50: 2 FunctionCall 18(PCF()
Branch 49
49: Label
Return
FunctionEnd
16(@main(struct-VS_OUT-vf31[3];): 13(HS_OUT) Function None 14
15(ip): 12(ptr) FunctionParameter
17: Label
21(output): 20(ptr) Variable Function
25: 24(ptr) AccessChain 15(ip) 23 23
26: 7(fvec3) Load 25
27: 24(ptr) AccessChain 21(output) 23
Store 27 26
28: 13(HS_OUT) Load 21(output)
ReturnValue 28
FunctionEnd
18(PCF(): 2 Function None 3
19: Label
Return
FunctionEnd

39
Test/hlsl.hull.1.tesc Normal file
View File

@ -0,0 +1,39 @@
// ***
// invocation ID coming from input to entry point
// ***
struct VS_OUT
{
float3 cpoint : CPOINT;
};
struct HS_CONSTANT_OUT
{
float edges[2] : SV_TessFactor;
};
struct HS_OUT
{
float3 cpoint : CPOINT;
};
[domain("isoline")]
[partitioning("integer")]
[outputtopology("line")]
[outputcontrolpoints(4)]
[patchconstantfunc("PCF")]
HS_OUT main(InputPatch<VS_OUT, 4> ip, uint m_cpid : SV_OutputControlPointID)
{
HS_OUT output;
output.cpoint = ip[0].cpoint;
return output;
}
HS_CONSTANT_OUT PCF(uint pid : SV_PrimitiveId)
{
HS_CONSTANT_OUT output;
output.edges[0] = 2.0f;
output.edges[1] = 8.0f;
return output;
}

39
Test/hlsl.hull.2.tesc Normal file
View File

@ -0,0 +1,39 @@
// ***
// invocation ID coming from synthesized variable
// ***
struct VS_OUT
{
float3 cpoint : CPOINT;
};
struct HS_CONSTANT_OUT
{
float edges[2] : SV_TessFactor;
};
struct HS_OUT
{
float3 cpoint : CPOINT;
};
[domain("isoline")]
[partitioning("integer")]
[outputtopology("line")]
[outputcontrolpoints(4)]
[patchconstantfunc("PCF")]
HS_OUT main(InputPatch<VS_OUT, 4> ip)
{
HS_OUT output;
output.cpoint = ip[0].cpoint;
return output;
}
HS_CONSTANT_OUT PCF(uint pid : SV_PrimitiveId, float4 pos : SV_Position)
{
HS_CONSTANT_OUT output;
output.edges[0] = 2.0f;
output.edges[1] = 8.0f;
return output;
}

34
Test/hlsl.hull.void.tesc Normal file
View File

@ -0,0 +1,34 @@
// ***
// void patchconstantfunction input and return
// ***
struct VS_OUT
{
float3 cpoint : CPOINT;
};
struct HS_CONSTANT_OUT
{
float edges[2] : SV_TessFactor;
};
struct HS_OUT
{
float3 cpoint : CPOINT;
};
[domain("tri")]
[partitioning("fractional_even")]
[outputtopology("line")]
[outputcontrolpoints(3)]
[patchconstantfunc("PCF")]
HS_OUT main(InputPatch<VS_OUT, 3> ip)
{
HS_OUT output;
output.cpoint = ip[0].cpoint;
return output;
}
void PCF()
{
}

View File

@ -81,12 +81,19 @@ public:
type = EbtBool;
}
void setSConst(const TString* s)
{
sConst = s;
type = EbtString;
}
int getIConst() const { return iConst; }
unsigned int getUConst() const { return uConst; }
long long getI64Const() const { return i64Const; }
unsigned long long getU64Const() const { return u64Const; }
double getDConst() const { return dConst; }
bool getBConst() const { return bConst; }
const TString* getSConst() const { return sConst; }
bool operator==(const int i) const
{
@ -532,6 +539,7 @@ private:
unsigned long long u64Const; // used for u64vec, scalar uint64s
bool bConst; // used for bvec, scalar bools
double dConst; // used for vec, dvec, mat, dmat, scalar floats and doubles
const TString* sConst; // string constant
};
TBasicType type;

View File

@ -1403,6 +1403,14 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT
return addConstantUnion(unionArray, TType(baseType, EvqConst), loc, literal);
}
TIntermConstantUnion* TIntermediate::addConstantUnion(const TString* s, const TSourceLoc& loc, bool literal) const
{
TConstUnionArray unionArray(1);
unionArray[0].setSConst(s);
return addConstantUnion(unionArray, TType(EbtString, EvqConst), loc, literal);
}
// Put vector swizzle selectors onto the given sequence
void TIntermediate::pushSelector(TIntermSequence& sequence, const TVectorSelector& selector, const TSourceLoc& loc)
{

View File

@ -198,6 +198,7 @@ struct TParameter {
TString *name;
TType* type;
TIntermTyped* defaultValue;
TBuiltInVariable declaredBuiltIn;
void copyParam(const TParameter& param)
{
if (param.name)
@ -206,6 +207,7 @@ struct TParameter {
name = 0;
type = param.type->clone();
defaultValue = param.defaultValue;
declaredBuiltIn = param.declaredBuiltIn;
}
};
@ -222,7 +224,11 @@ public:
TSymbol(name),
mangledName(*name + '('),
op(tOp),
defined(false), prototyped(false), defaultParamCount(0) { returnType.shallowCopy(retType); }
defined(false), prototyped(false), defaultParamCount(0)
{
returnType.shallowCopy(retType);
declaredBuiltIn = retType.getQualifier().builtIn;
}
virtual TFunction* clone() const;
virtual ~TFunction();
@ -232,6 +238,7 @@ public:
virtual void addParameter(TParameter& p)
{
assert(writable);
p.declaredBuiltIn = p.type->getQualifier().builtIn;
parameters.push_back(p);
p.type->appendMangledName(mangledName);
@ -246,6 +253,7 @@ public:
virtual const TString& getMangledName() const { return mangledName; }
virtual const TType& getType() const { return returnType; }
virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
virtual TType& getWritableType() { return returnType; }
virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
virtual TOperator getBuiltInOp() const { return op; }
@ -273,6 +281,8 @@ protected:
typedef TVector<TParameter> TParamList;
TParamList parameters;
TType returnType;
TBuiltInVariable declaredBuiltIn;
TString mangledName;
TOperator op;
bool defined;

View File

@ -263,6 +263,7 @@ public:
TIntermConstantUnion* addConstantUnion(unsigned long long, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(bool, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(double, TBasicType, const TSourceLoc&, bool literal = false) const;
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);

View File

@ -119,6 +119,9 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.getdimensions.rw.dx10.frag", "main"},
{"hlsl.getdimensions.dx10.vert", "main"},
{"hlsl.getsampleposition.dx10.frag", "main"},
{"hlsl.hull.1.tesc", "main"},
{"hlsl.hull.2.tesc", "main"},
{"hlsl.hull.void.tesc", "main"},
{"hlsl.identifier.sample.frag", "main"},
{"hlsl.if.frag", "PixelShaderFunction"},
{"hlsl.inoutquals.frag", "main"},

View File

@ -60,6 +60,7 @@ namespace glslang {
EatOutputTopology,
EatPartitioning,
EatPatchConstantFunc,
EatPatchSize,
EatUnroll,
};
}

View File

@ -869,6 +869,67 @@ bool HlslGrammar::acceptOutputPrimitiveGeometry(TLayoutGeometry& geometry)
return true;
}
// tessellation_decl_type
// : INPUTPATCH
// | OUTPUTPATCH
//
bool HlslGrammar::acceptTessellationDeclType()
{
// read geometry type
const EHlslTokenClass tessType = peek();
switch (tessType) {
case EHTokInputPatch: break;
case EHTokOutputPatch: break;
default:
return false; // not a tessellation decl
}
advanceToken(); // consume the keyword
return true;
}
// tessellation_patch_template_type
// : tessellation_decl_type LEFT_ANGLE type comma integer_literal RIGHT_ANGLE
//
bool HlslGrammar::acceptTessellationPatchTemplateType(TType& type)
{
if (! acceptTessellationDeclType())
return false;
if (! acceptTokenClass(EHTokLeftAngle))
return false;
if (! acceptType(type)) {
expected("tessellation patch type");
return false;
}
if (! acceptTokenClass(EHTokComma))
return false;
// integer size
if (! peekTokenClass(EHTokIntConstant)) {
expected("literal integer");
return false;
}
TIntermTyped* size;
if (! acceptLiteral(size))
return false;
TArraySizes* arraySizes = new TArraySizes;
arraySizes->addInnerSize(size->getAsConstantUnion()->getConstArray()[0].getIConst());
type.newArraySizes(*arraySizes);
if (! acceptTokenClass(EHTokRightAngle)) {
expected("right angle bracket");
return false;
}
return true;
}
// stream_out_template_type
// : output_primitive_geometry_type LEFT_ANGLE type RIGHT_ANGLE
//
@ -1147,6 +1208,15 @@ bool HlslGrammar::acceptType(TType& type)
return true;
}
case EHTokInputPatch: // fall through
case EHTokOutputPatch: // ...
{
if (! acceptTessellationPatchTemplateType(type))
return false;
return true;
}
case EHTokSampler: // fall through
case EHTokSampler1d: // ...
case EHTokSampler2d: // ...
@ -2522,7 +2592,7 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
node = intermediate.addConstantUnion(token.b, token.loc, true);
break;
case EHTokStringConstant:
node = nullptr;
node = intermediate.addConstantUnion(token.string, token.loc, true);
break;
default:

View File

@ -76,6 +76,8 @@ namespace glslang {
bool acceptTemplateVecMatBasicType(TBasicType&);
bool acceptVectorTemplateType(TType&);
bool acceptMatrixTemplateType(TType&);
bool acceptTessellationDeclType();
bool acceptTessellationPatchTemplateType(TType&);
bool acceptStreamOutTemplateType(TType&, TLayoutGeometry&);
bool acceptOutputPrimitiveGeometry(TLayoutGeometry&);
bool acceptAnnotations(TQualifier&);

View File

@ -48,6 +48,7 @@
#include <functional>
#include <cctype>
#include <array>
#include <set>
namespace glslang {
@ -63,7 +64,9 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int
builtInIoIndex(nullptr),
builtInIoBase(nullptr),
nextInLocation(0), nextOutLocation(0),
sourceEntryPointName(sourceEntryPointName)
sourceEntryPointName(sourceEntryPointName),
entryPointFunction(nullptr),
entryPointFunctionBody(nullptr)
{
globalUniformDefaults.clear();
globalUniformDefaults.layoutMatrix = ElmRowMajor;
@ -1343,6 +1346,17 @@ TIntermTyped* HlslParseContext::splitAccessStruct(const TSourceLoc& loc, TInterm
}
}
// Pass through to base class after remembering builtin mappings.
void HlslParseContext::trackLinkage(TSymbol& symbol)
{
TBuiltInVariable biType = symbol.getType().getQualifier().builtIn;
if (biType != EbvNone)
builtInLinkageSymbols[biType] = symbol.clone();
TParseContextBase::trackLinkage(symbol);
}
// Variables that correspond to the user-interface in and out of a stage
// (not the built-in interface) are assigned locations and
// registered as a linkage node (part of the stage's external interface).
@ -1362,6 +1376,7 @@ void HlslParseContext::assignLocations(TVariable& variable)
nextOutLocation += intermediate.computeTypeLocationSize(variable.getType());
}
}
trackLinkage(variable);
}
};
@ -1512,9 +1527,6 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
if (! symbolTable.insert(*variable))
error(loc, "redefinition", variable->getName().c_str(), "");
else {
// Transfer ownership of name pointer to symbol table.
param.name = nullptr;
// Add the parameter to the AST
paramNodes = intermediate.growAggregate(paramNodes,
intermediate.addSymbol(*variable, loc),
@ -1570,6 +1582,8 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
return nullptr;
}
entryPointFunction = &userFunction; // needed in finish()
// entry point logic...
// Handle entry-point function attributes
@ -1580,9 +1594,128 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
for (int lid = 0; lid < int(sequence.size()); ++lid)
intermediate.setLocalSize(lid, sequence[lid]->getAsConstantUnion()->getConstArray()[0].getIConst());
}
// MaxVertexCount
const TIntermAggregate* maxVertexCount = attributes[EatMaxVertexCount];
if (maxVertexCount != nullptr)
intermediate.setVertices(maxVertexCount->getSequence()[0]->getAsConstantUnion()->getConstArray()[0].getIConst());
if (maxVertexCount != nullptr) {
if (! intermediate.setVertices(maxVertexCount->getSequence()[0]->getAsConstantUnion()->getConstArray()[0].getIConst())) {
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
}
}
// Handle [patchconstantfunction("...")]
const TIntermAggregate* pcfAttr = attributes[EatPatchConstantFunc];
if (pcfAttr != nullptr) {
const TConstUnion& pcfName = pcfAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (pcfName.getType() != EbtString) {
error(loc, "invalid patch constant function", "", "");
} else {
patchConstantFunctionName = *pcfName.getSConst();
}
}
// Handle [domain("...")]
const TIntermAggregate* domainAttr = attributes[EatDomain];
if (domainAttr != nullptr) {
const TConstUnion& domainType = domainAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (domainType.getType() != EbtString) {
error(loc, "invalid domain", "", "");
} else {
TString domainStr = *domainType.getSConst();
std::transform(domainStr.begin(), domainStr.end(), domainStr.begin(), ::tolower);
TLayoutGeometry domain = ElgNone;
if (domainStr == "tri") {
domain = ElgTriangles;
} else if (domainStr == "quad") {
domain = ElgQuads;
} else if (domainStr == "isoline") {
domain = ElgIsolines;
} else {
error(loc, "unsupported domain type", domainStr.c_str(), "");
}
if (! intermediate.setInputPrimitive(domain)) {
error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), "");
}
}
}
// Handle [outputtoplogy("...")]
const TIntermAggregate* topologyAttr = attributes[EatOutputTopology];
if (topologyAttr != nullptr) {
const TConstUnion& topoType = topologyAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (topoType.getType() != EbtString) {
error(loc, "invalid outputtoplogy", "", "");
} else {
TString topologyStr = *topoType.getSConst();
std::transform(topologyStr.begin(), topologyStr.end(), topologyStr.begin(), ::tolower);
TVertexOrder topology = EvoNone;
if (topologyStr == "point") {
topology = EvoNone;
} else if (topologyStr == "line") {
topology = EvoNone;
} else if (topologyStr == "triangle_cw") {
topology = EvoCw;
} else if (topologyStr == "triangle_ccw") {
topology = EvoCcw;
} else {
error(loc, "unsupported outputtoplogy type", topologyStr.c_str(), "");
}
if (topology != EvoNone) {
if (! intermediate.setVertexOrder(topology)) {
error(loc, "cannot change previously set outputtopology", TQualifier::getVertexOrderString(topology), "");
}
}
}
}
// Handle [partitioning("...")]
const TIntermAggregate* partitionAttr = attributes[EatPartitioning];
if (partitionAttr != nullptr) {
const TConstUnion& partType = partitionAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (partType.getType() != EbtString) {
error(loc, "invalid partitioning", "", "");
} else {
TString partitionStr = *partType.getSConst();
std::transform(partitionStr.begin(), partitionStr.end(), partitionStr.begin(), ::tolower);
TVertexSpacing partitioning = EvsNone;
if (partitionStr == "integer") {
partitioning = EvsEqual;
} else if (partitionStr == "fractional_even") {
partitioning = EvsFractionalEven;
} else if (partitionStr == "fractional_odd") {
partitioning = EvsFractionalOdd;
//} else if (partition == "pow2") { // TODO: currently nothing to map this to.
} else {
error(loc, "unsupported partitioning type", partitionStr.c_str(), "");
}
if (! intermediate.setVertexSpacing(partitioning))
error(loc, "cannot change previously set partitioning", TQualifier::getVertexSpacingString(partitioning), "");
}
}
// Handle [outputcontrolpoints("...")]
const TIntermAggregate* outputControlPoints = attributes[EatOutputControlPoints];
if (outputControlPoints != nullptr) {
const TConstUnion& ctrlPointConst = outputControlPoints->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
if (ctrlPointConst.getType() != EbtInt) {
error(loc, "invalid outputcontrolpoints", "", "");
} else {
const int ctrlPoints = ctrlPointConst.getIConst();
if (! intermediate.setVertices(ctrlPoints)) {
error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
}
}
}
// Move parameters and return value to shader in/out
TVariable* entryPointOutput; // gets created in remapEntryPointIO
@ -1675,6 +1808,8 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
TIntermNode* synthFunctionDef = synthParams;
handleFunctionBody(loc, synthEntryPoint, synthBody, synthFunctionDef);
entryPointFunctionBody = synthBody;
return synthFunctionDef;
}
@ -1920,6 +2055,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
// array case
for (int element=0; element < left->getType().getOuterArraySize(); ++element) {
arrayElement.push_back(element);
// Add a new AST symbol node if we have a temp variable holding a complex RHS.
TIntermTyped* subLeft = getMember(true, left, element, left, element);
TIntermTyped* subRight = getMember(false, right, element, right, element);
@ -1927,8 +2064,6 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element) : subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element) : subRight;
arrayElement.push_back(element);
if (isFinalFlattening(dereferencedType))
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc);
else
@ -6787,9 +6922,282 @@ void HlslParseContext::clearUniformInputOutput(TQualifier& qualifier)
correctUniform(qualifier);
}
// Add patch constant function invocation
void HlslParseContext::addPatchConstantInvocation()
{
TSourceLoc loc;
loc.init();
// If there's no patch constant function, or we're not a HS, do nothing.
if (patchConstantFunctionName.empty() || language != EShLangTessControl)
return;
if (symbolTable.isFunctionNameVariable(patchConstantFunctionName)) {
error(loc, "can't use variable in patch constant function", patchConstantFunctionName.c_str(), "");
return;
}
const TString mangledName = patchConstantFunctionName + "(";
// create list of PCF candidates
TVector<const TFunction*> candidateList;
bool builtIn;
symbolTable.findFunctionNameList(mangledName, candidateList, builtIn);
// We have to have one and only one, or we don't know which to pick: the patchconstantfunc does not
// allow any disambiguation of overloads.
if (candidateList.empty()) {
error(loc, "patch constant function not found", patchConstantFunctionName.c_str(), "");
return;
}
// Based on directed experiments, it appears that if there are overloaded patchconstantfunctions,
// HLSL picks the last one in shader source order. Since that isn't yet implemented here, error
// out if there is more than one candidate.
if (candidateList.size() > 1) {
error(loc, "ambiguous patch constant function", patchConstantFunctionName.c_str(), "");
return;
}
// Look for builtin variables in a function's parameter list.
const auto findBuiltIns = [&](const TFunction& function, std::set<tInterstageIoData>& builtIns) {
for (int p=0; p<function.getParamCount(); ++p) {
const TStorageQualifier storage = function[p].type->getQualifier().storage;
if (function[p].declaredBuiltIn != EbvNone)
builtIns.insert(tInterstageIoData(function[p].declaredBuiltIn, storage));
else
builtIns.insert(tInterstageIoData(function[p].type->getQualifier().builtIn, storage));
}
};
// If we synthesize a builtin interface variable, we must add it to the linkage.
const auto addToLinkage = [&](const TType& type, const TString* name, TIntermSymbol** symbolNode) {
if (name == nullptr) {
error(loc, "unable to locate patch function parameter name", "", "");
return;
} else {
TVariable& variable = *new TVariable(name, type);
if (! symbolTable.insert(variable)) {
error(loc, "unable to declare patch constant function interface variable", name->c_str(), "");
return;
}
globalQualifierFix(loc, variable.getWritableType().getQualifier());
if (symbolNode != nullptr)
*symbolNode = intermediate.addSymbol(variable);
trackLinkage(variable);
}
};
// Return a symbol for the linkage variable of the given TBuiltInVariable type
const auto findLinkageSymbol = [this](TBuiltInVariable biType) -> TIntermSymbol* {
const auto it = builtInLinkageSymbols.find(biType);
if (it == builtInLinkageSymbols.end()) // if it wasn't declared by the user, return nullptr
return nullptr;
return intermediate.addSymbol(*it->second->getAsVariable());
};
// We will perform these steps. Each is in a scoped block for separation: they could
// become separate functions to make addPatchConstantInvocation shorter.
//
// 1. Union the interfaces, and create builtins for anything present in the PCF and
// declared as a builtin variable that isn't present in the entry point's signature.
//
// 2. Synthesizes a call to the patchconstfunction using builtin variables from either main,
// or the ones we created. Matching is based on builtin type. We may use synthesized
// variables from (1) above.
//
// 3. Create a return sequence: copy the return value (if any) from the PCF to a
// (non-sanitized) output variable. In case this may involve multiple copies, such as for
// an arrayed variable, a temporary copy of the PCF output is created to avoid multiple
// indirections into a complex R-value coming from the call to the PCF.
//
// 4. Add a barrier to the end of the entry point body
//
// 5. Call the PCF inside an if test for (invocation id == 0).
TFunction& patchConstantFunction = const_cast<TFunction&>(*candidateList[0]);
const int pcfParamCount = patchConstantFunction.getParamCount();
TIntermSymbol* invocationIdSym = findLinkageSymbol(EbvInvocationId);
TIntermSequence& epBodySeq = entryPointFunctionBody->getAsAggregate()->getSequence();
// ================ Step 1A: Union Interfaces ================
// Our patch constant function.
{
std::set<tInterstageIoData> pcfBuiltIns; // patch constant function builtins
std::set<tInterstageIoData> epfBuiltIns; // entry point function builtins
assert(entryPointFunction);
assert(entryPointFunctionBody);
findBuiltIns(patchConstantFunction, pcfBuiltIns);
findBuiltIns(*entryPointFunction, epfBuiltIns);
// Patchconstantfunction can contain only builtin qualified variables. (Technically, only HS inputs,
// but this test is less assertive than that).
for (auto bi = pcfBuiltIns.begin(); bi != pcfBuiltIns.end(); ++bi) {
if (bi->builtIn == EbvNone) {
error(loc, "patch constant function invalid parameter", "", "");
return;
}
}
// Find the set of builtins in the PCF that are not present in the entry point.
std::set<tInterstageIoData> notInEntryPoint;
notInEntryPoint = pcfBuiltIns;
for (auto bi : epfBuiltIns) // std::set_difference not usable on unordered containers
notInEntryPoint.erase(bi);
// Now we'll add those to the entry and to the linkage.
for (int p=0; p<pcfParamCount; ++p) {
TType* paramType = patchConstantFunction[p].type->clone();
const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn;
const TStorageQualifier storage = patchConstantFunction[p].type->getQualifier().storage;
// Use the original declaration type for the linkage
paramType->getQualifier().builtIn = biType;
if (notInEntryPoint.count(tInterstageIoData(biType, storage)) == 1)
addToLinkage(*paramType, patchConstantFunction[p].name, nullptr);
}
// If we didn't find it because the shader made one, add our own.
if (invocationIdSym == nullptr) {
TType invocationIdType(EbtUint, EvqIn, 1);
TString* invocationIdName = NewPoolTString("InvocationId");
invocationIdType.getQualifier().builtIn = EbvInvocationId;
addToLinkage(invocationIdType, invocationIdName, &invocationIdSym);
}
assert(invocationIdSym);
}
TIntermTyped* pcfArguments = nullptr;
// ================ Step 1B: Argument synthesis ================
// Create pcfArguments for synthesis of patchconstantfunction invocation
// TODO: handle struct or array inputs
{
for (int p=0; p<pcfParamCount; ++p) {
if (patchConstantFunction[p].type->isArray() ||
patchConstantFunction[p].type->isStruct()) {
error(loc, "unimplemented array or variable in patch constant function signature", "", "");
return;
}
// find which builtin it is
const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn;
TIntermSymbol* builtIn = findLinkageSymbol(biType);
if (builtIn == nullptr) {
error(loc, "unable to find patch constant function builtin variable", "", "");
return;
}
if (pcfParamCount == 1)
pcfArguments = builtIn;
else
pcfArguments = intermediate.growAggregate(pcfArguments, builtIn);
}
}
// ================ Step 2: Synthesize call to PCF ================
TIntermTyped* pcfCall = nullptr;
{
// Create a function call to the patchconstantfunction
if (pcfArguments)
addInputArgumentConversions(patchConstantFunction, pcfArguments);
// Synthetic call.
pcfCall = intermediate.setAggregateOperator(pcfArguments, EOpFunctionCall, patchConstantFunction.getType(), loc);
pcfCall->getAsAggregate()->setUserDefined();
pcfCall->getAsAggregate()->setName(patchConstantFunction.getMangledName());
intermediate.addToCallGraph(infoSink, entryPointFunction->getMangledName(), patchConstantFunction.getMangledName());
if (pcfCall->getAsAggregate()) {
TQualifierList& qualifierList = pcfCall->getAsAggregate()->getQualifierList();
for (int i = 0; i < patchConstantFunction.getParamCount(); ++i) {
TStorageQualifier qual = patchConstantFunction[i].type->getQualifier().storage;
qualifierList.push_back(qual);
}
pcfCall = addOutputArgumentConversions(patchConstantFunction, *pcfCall->getAsOperator());
}
}
// ================ Step 3: Create return Sequence ================
// Return sequence: copy PCF result to a temporary, then to shader output variable.
if (pcfCall->getBasicType() != EbtVoid) {
const TType* retType = &patchConstantFunction.getType(); // return type from the PCF
TType outType; // output type that goes with the return type.
outType.shallowCopy(*retType);
// substitute the output type
const auto newLists = ioTypeMap.find(retType->getStruct());
if (newLists != ioTypeMap.end())
outType.setStruct(newLists->second.output);
// Substitute the top level type's builtin type
if (patchConstantFunction.getDeclaredBuiltInType() != EbvNone)
outType.getQualifier().builtIn = patchConstantFunction.getDeclaredBuiltInType();
TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType);
pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut;
if (pcfOutput->getType().containsBuiltInInterstageIO(language))
split(*pcfOutput);
TIntermSymbol* pcfOutputSym = intermediate.addSymbol(*pcfOutput, loc);
// The call to the PCF is a complex R-value: we want to store it in a temp to avoid
// repeated calls to the PCF:
TVariable* pcfCallResult = makeInternalVariable("@patchConstantResult", *retType);
pcfCallResult->getWritableType().getQualifier().makeTemporary();
TIntermSymbol* pcfResultVar = intermediate.addSymbol(*pcfCallResult, loc);
// sanitizeType(&pcfCall->getWritableType());
TIntermNode* pcfResultAssign = intermediate.addAssign(EOpAssign, pcfResultVar, pcfCall, loc);
TIntermNode* pcfResultToOut = handleAssign(loc, EOpAssign, pcfOutputSym, intermediate.addSymbol(*pcfCallResult, loc));
TIntermTyped* pcfAggregate = nullptr;
pcfAggregate = intermediate.growAggregate(pcfAggregate, pcfResultAssign);
pcfAggregate = intermediate.growAggregate(pcfAggregate, pcfResultToOut);
pcfAggregate = intermediate.setAggregateOperator(pcfAggregate, EOpSequence, *retType, loc);
pcfCall = pcfAggregate;
}
// ================ Step 4: Barrier ================
TIntermTyped* barrier = new TIntermAggregate(EOpBarrier);
barrier->setLoc(loc);
barrier->setType(TType(EbtVoid));
epBodySeq.insert(epBodySeq.end(), barrier);
// ================ Step 5: Test on invocation ID ================
TIntermTyped* zero = intermediate.addConstantUnion(0, loc, true);
TIntermTyped* cmp = intermediate.addBinaryNode(EOpEqual, invocationIdSym, zero, loc, TType(EbtBool));
// Create if statement
TIntermTyped* invocationIdTest = new TIntermSelection(cmp, pcfCall, nullptr);
invocationIdTest->setLoc(loc);
// add our test sequence before the return.
epBodySeq.insert(epBodySeq.end(), invocationIdTest);
}
// post-processing
void HlslParseContext::finish()
{
addPatchConstantInvocation();
addInterstageIoToLinkage();
TParseContextBase::finish();

View File

@ -225,6 +225,7 @@ protected:
TVariable* getSplitIoVar(const TVariable* var) const;
TVariable* getSplitIoVar(int id) const;
void addInterstageIoToLinkage();
void addPatchConstantInvocation();
void flatten(const TSourceLoc& loc, const TVariable& variable);
int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
@ -242,6 +243,10 @@ protected:
void correctUniform(TQualifier& qualifier);
void clearUniformInputOutput(TQualifier& qualifier);
// Pass through to base class after remembering builtin mappings.
using TParseContextBase::trackLinkage;
void trackLinkage(TSymbol& variable) override;
void finish() override; // post-processing
// Current state of parsing
@ -324,6 +329,9 @@ protected:
// can build the linkage correctly if position appears on both sides. Otherwise, multiple positions
// are considered identical.
struct tInterstageIoData {
tInterstageIoData(TBuiltInVariable bi, TStorageQualifier q) :
builtIn(bi), storage(q) { }
tInterstageIoData(const TType& memberType, const TType& storageType) :
builtIn(memberType.getQualifier().builtIn),
storage(storageType.getQualifier().storage) { }
@ -349,6 +357,12 @@ protected:
unsigned int nextOutLocation;
TString sourceEntryPointName;
TFunction* entryPointFunction;
TIntermNode* entryPointFunctionBody;
TString patchConstantFunctionName; // hull shader patch constant function name, from function level attribute.
TMap<TBuiltInVariable, TSymbol*> builtInLinkageSymbols; // used for tessellation, finding declared builtins
};
} // end namespace glslang

View File

@ -129,6 +129,9 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["LineStream"] = EHTokLineStream;
(*KeywordMap)["TriangleStream"] = EHTokTriangleStream;
(*KeywordMap)["InputPatch"] = EHTokInputPatch;
(*KeywordMap)["OutputPatch"] = EHTokOutputPatch;
(*KeywordMap)["Buffer"] = EHTokBuffer;
(*KeywordMap)["vector"] = EHTokVector;
(*KeywordMap)["matrix"] = EHTokMatrix;
@ -540,6 +543,11 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
case EHTokTriangleStream:
return keyword;
// Tessellation patches
case EHTokInputPatch:
case EHTokOutputPatch:
return keyword;
case EHTokBuffer:
case EHTokVector:
case EHTokMatrix:

View File

@ -78,6 +78,10 @@ enum EHlslTokenClass {
EHTokLineStream,
EHTokTriangleStream,
// Tessellation patches
EHTokInputPatch,
EHTokOutputPatch,
// template types
EHTokBuffer,
EHTokVector,