diff --git a/Test/baseResults/hlsl.hull.1.tesc.out b/Test/baseResults/hlsl.hull.1.tesc.out new file mode 100644 index 0000000000000000000000000000000000000000..18034c8bed252b8033cda416a2630e0a1db7a39c --- /dev/null +++ b/Test/baseResults/hlsl.hull.1.tesc.out @@ -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 diff --git a/Test/baseResults/hlsl.hull.2.tesc.out b/Test/baseResults/hlsl.hull.2.tesc.out new file mode 100644 index 0000000000000000000000000000000000000000..d3c9cb841ae46139938c39c8fa55d2791f4a157f --- /dev/null +++ b/Test/baseResults/hlsl.hull.2.tesc.out @@ -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 diff --git a/Test/baseResults/hlsl.hull.void.tesc.out b/Test/baseResults/hlsl.hull.void.tesc.out new file mode 100644 index 0000000000000000000000000000000000000000..7576fdcea8418b3d4e3149658ea94b508c1b33ee --- /dev/null +++ b/Test/baseResults/hlsl.hull.void.tesc.out @@ -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 diff --git a/Test/hlsl.hull.1.tesc b/Test/hlsl.hull.1.tesc new file mode 100644 index 0000000000000000000000000000000000000000..4959b45331470f56414a6150ac4bdd0974e7dcb3 --- /dev/null +++ b/Test/hlsl.hull.1.tesc @@ -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; +} diff --git a/Test/hlsl.hull.2.tesc b/Test/hlsl.hull.2.tesc new file mode 100644 index 0000000000000000000000000000000000000000..3c0afcc5d669f0472909891d18090ee6fc8a958e --- /dev/null +++ b/Test/hlsl.hull.2.tesc @@ -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; +} diff --git a/Test/hlsl.hull.void.tesc b/Test/hlsl.hull.void.tesc new file mode 100644 index 0000000000000000000000000000000000000000..971d613bf78ecec2d0e531fd59697a0238f2cb57 --- /dev/null +++ b/Test/hlsl.hull.void.tesc @@ -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() +{ +} diff --git a/glslang/Include/ConstantUnion.h b/glslang/Include/ConstantUnion.h index b95bc25a0a16e31a23410e273304971b6636b9b9..f66a7ff5192d351ae59942c1de46a4c636266c63 100644 --- a/glslang/Include/ConstantUnion.h +++ b/glslang/Include/ConstantUnion.h @@ -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; diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 2854235588ddbb09f3a923da42f5e46b71eec7f7..2ebd741eebbec0162f1a752cf3a6dabf1c9f7a83 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -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) { diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index e506e614047138519d4fd0051656d1641c049054..29ee40e15fef51ae2dc39be34fbcb1b3a415a49d 100644 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -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; diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 75bd679e3395203504724148e1f5b422fbca7a56..14193f56adcf3a091026833b4c3e386fb585a2e3 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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&); diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 701863ac012915af44b64541b602181764bc0d3d..ed1cb008e3ee423142aa2576dcda257210d9ebfd 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -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"}, diff --git a/hlsl/hlslAttributes.h b/hlsl/hlslAttributes.h index 820909b19becad036bb30fb408b042ce4fe3b369..5a7c033d45300a4fdc9b6f66788a068201f85741 100644 --- a/hlsl/hlslAttributes.h +++ b/hlsl/hlslAttributes.h @@ -60,6 +60,7 @@ namespace glslang { EatOutputTopology, EatPartitioning, EatPatchConstantFunc, + EatPatchSize, EatUnroll, }; } diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index a454c444d0aa3b5b0ad1867824f836fd7420c784..ea2ae5559a0bd388e5805a5cafd74b3fa4160875 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -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: diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 0629eaae6f27f61ff4b61ca8ec155ee625f89ba5..f98d650cb5e69560260cfcac0cc945e7d47005ce 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -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&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 1a4ae06b1da779cb0474387a909cfc2e27bf2be4..272632ba8246ffc9962c6a726604560fd2fcab77 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -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(); diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 6aec72b16124bc0f1e8cb9eb574e2585c24a4684..fa1cbf470559900c2b3c02e3ea14e1c65cdd1156 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -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 diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index 69c1e37f8690d22dce73ac9a4cb422af6513a05f..7fe8ca262a8d642c924148bd5b115bee5a795184 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -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: diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index ae267705e251af393347d4efb41031588664b20a..95b3826ed9f2522c9142cef0415a0a8bdded81fd 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -78,6 +78,10 @@ enum EHlslTokenClass { EHTokLineStream, EHTokTriangleStream, + // Tessellation patches + EHTokInputPatch, + EHTokOutputPatch, + // template types EHTokBuffer, EHTokVector,