Merge pull request #722 from steve-lunarg/tessellation
Add basic HS/DS implementation.
This commit is contained in:
commit
e4e8f7b7a3
359
Test/baseResults/hlsl.hull.1.tesc.out
Normal file
359
Test/baseResults/hlsl.hull.1.tesc.out
Normal 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
|
357
Test/baseResults/hlsl.hull.2.tesc.out
Normal file
357
Test/baseResults/hlsl.hull.2.tesc.out
Normal 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
|
186
Test/baseResults/hlsl.hull.void.tesc.out
Normal file
186
Test/baseResults/hlsl.hull.void.tesc.out
Normal 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
39
Test/hlsl.hull.1.tesc
Normal 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
39
Test/hlsl.hull.2.tesc
Normal 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
34
Test/hlsl.hull.void.tesc
Normal 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()
|
||||
{
|
||||
}
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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&);
|
||||
|
@ -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"},
|
||||
|
@ -60,6 +60,7 @@ namespace glslang {
|
||||
EatOutputTopology,
|
||||
EatPartitioning,
|
||||
EatPatchConstantFunc,
|
||||
EatPatchSize,
|
||||
EatUnroll,
|
||||
};
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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&);
|
||||
|
@ -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();
|
||||
|
@ -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) { }
|
||||
@ -348,7 +356,13 @@ protected:
|
||||
unsigned int nextInLocation;
|
||||
unsigned int nextOutLocation;
|
||||
|
||||
TString sourceEntryPointName;
|
||||
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
|
||||
|
@ -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:
|
||||
|
@ -78,6 +78,10 @@ enum EHlslTokenClass {
|
||||
EHTokLineStream,
|
||||
EHTokTriangleStream,
|
||||
|
||||
// Tessellation patches
|
||||
EHTokInputPatch,
|
||||
EHTokOutputPatch,
|
||||
|
||||
// template types
|
||||
EHTokBuffer,
|
||||
EHTokVector,
|
||||
|
Loading…
x
Reference in New Issue
Block a user