diff --git a/Test/baseResults/hlsl.hull.1.tesc.out b/Test/baseResults/hlsl.hull.1.tesc.out index 89ab4e63..a9f6386c 100644 --- a/Test/baseResults/hlsl.hull.1.tesc.out +++ b/Test/baseResults/hlsl.hull.1.tesc.out @@ -50,8 +50,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -62,8 +62,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -104,7 +104,8 @@ vertices = 4 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) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) Linked tessellation control stage: @@ -161,8 +162,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -173,8 +174,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -215,16 +216,17 @@ vertices = 4 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) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 85 +// Id's are bound by 88 Capability Tessellation 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint TessellationControl 4 "main" 40 44 47 62 67 + EntryPoint TessellationControl 4 "main" 40 44 47 62 67 87 ExecutionMode 4 OutputVertices 4 Name 4 "main" Name 8 "VS_OUT" @@ -251,11 +253,16 @@ vertices = 4 Name 63 "param" Name 67 "@patchConstantOutput_edges" Name 77 "output" + Name 85 "HS_CONSTANT_OUT" + Name 87 "@patchConstantOutput" 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) Patch Decorate 67(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 87(@patchConstantOutput) Patch + Decorate 87(@patchConstantOutput) Location 1 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -294,6 +301,9 @@ vertices = 4 73: 29(int) Constant 1 78: 6(float) Constant 1073741824 80: 6(float) Constant 1090519040 +85(HS_CONSTANT_OUT): TypeStruct + 86: TypePointer Output 85(HS_CONSTANT_OUT) +87(@patchConstantOutput): 86(ptr) Variable Output 4(main): 2 Function None 3 5: Label 38(ip): 12(ptr) Variable Function diff --git a/Test/baseResults/hlsl.hull.2.tesc.out b/Test/baseResults/hlsl.hull.2.tesc.out index 9d848c61..b66ead08 100644 --- a/Test/baseResults/hlsl.hull.2.tesc.out +++ b/Test/baseResults/hlsl.hull.2.tesc.out @@ -46,8 +46,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -58,8 +58,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -102,7 +102,8 @@ vertices = 4 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) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) Linked tessellation control stage: @@ -155,8 +156,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 0 (const int) 0:? direct index ( temp float) @@ -167,8 +168,8 @@ vertices = 4 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:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) 0:? Constant: 0:? 1 (const int) 0:? direct index ( temp float) @@ -211,16 +212,17 @@ vertices = 4 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) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter) // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 87 +// Id's are bound by 90 Capability Tessellation 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint TessellationControl 4 "main" 42 45 52 60 62 69 + EntryPoint TessellationControl 4 "main" 42 45 52 60 62 69 89 ExecutionMode 4 OutputVertices 4 Name 4 "main" Name 8 "VS_OUT" @@ -247,12 +249,17 @@ vertices = 4 Name 65 "param" Name 69 "@patchConstantOutput_edges" Name 79 "output" + Name 87 "HS_CONSTANT_OUT" + Name 89 "@patchConstantOutput" 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) Patch Decorate 69(@patchConstantOutput_edges) BuiltIn TessLevelOuter + Decorate 89(@patchConstantOutput) Patch + Decorate 89(@patchConstantOutput) Location 1 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -295,6 +302,9 @@ vertices = 4 75: 31(int) Constant 1 80: 6(float) Constant 1073741824 82: 6(float) Constant 1090519040 +87(HS_CONSTANT_OUT): TypeStruct + 88: TypePointer Output 87(HS_CONSTANT_OUT) +89(@patchConstantOutput): 88(ptr) Variable Output 4(main): 2 Function None 3 5: Label 40(ip): 12(ptr) Variable Function diff --git a/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out new file mode 100644 index 00000000..a6c202b8 --- /dev/null +++ b/Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out @@ -0,0 +1,587 @@ +hlsl.hull.ctrlpt-1.tesc +Shader version: 450 +vertices = 3 +0:? Sequence +0:27 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:27 Function Parameters: +0:27 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:27 'cpid' ( in uint) +0:? Sequence +0:29 move second child to first child ( temp 3-component vector of float) +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 'o' ( temp structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Construct vec3 ( temp 3-component vector of float) +0:29 Convert uint to float ( temp float) +0:29 'cpid' ( in uint) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 3-component vector of float val}) +0:27 Function Definition: main( ( temp void) +0:27 Function Parameters: +0:? Sequence +0:27 move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:27 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float val}) +0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( temp uint) +0:? Barrier ( temp void) +0:? Test condition and select ( temp void) +0:? Condition +0:? Compare Equal ( temp bool) +0:? '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 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const uint) +0:? move second child to first child ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Function Call: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 0 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 0 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 1 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 1 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 2 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 2 (const int) +0:? move second child to first child ( temp float) +0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner) +0:? flInFactor: direct index for structure ( temp float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 1 (const int) +0:34 Function Definition: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:34 Function Parameters: +0:34 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:37 move second child to first child ( temp float) +0:37 direct index ( temp float) +0:37 tfactor: direct index for structure ( temp 3-element array of float) +0:37 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 direct index ( temp float) +0:37 val: direct index for structure ( temp 3-component vector of float) +0:37 direct index ( temp structure{ temp 3-component vector of float val}) +0:37 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:38 move second child to first child ( temp float) +0:38 direct index ( temp float) +0:38 tfactor: direct index for structure ( temp 3-element array of float) +0:38 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 direct index ( temp float) +0:38 val: direct index for structure ( temp 3-component vector of float) +0:38 direct index ( temp structure{ temp 3-component vector of float val}) +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 0 (const int) +0:39 move second child to first child ( temp float) +0:39 direct index ( temp float) +0:39 tfactor: direct index for structure ( temp 3-element array of float) +0:39 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 direct index ( temp float) +0:39 val: direct index for structure ( temp 3-component vector of float) +0:39 direct index ( temp structure{ temp 3-component vector of float val}) +0:39 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 move second child to first child ( temp float) +0:40 flInFactor: direct index for structure ( temp float) +0:40 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 4.000000 +0:42 Branch: Return with expression +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner) + + +Linked tessellation control stage: + + +Shader version: 450 +vertices = 3 +0:? Sequence +0:27 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:27 Function Parameters: +0:27 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:27 'cpid' ( in uint) +0:? Sequence +0:29 move second child to first child ( temp 3-component vector of float) +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 'o' ( temp structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Construct vec3 ( temp 3-component vector of float) +0:29 Convert uint to float ( temp float) +0:29 'cpid' ( in uint) +0:30 Branch: Return with expression +0:30 'o' ( temp structure{ temp 3-component vector of float val}) +0:27 Function Definition: main( ( temp void) +0:27 Function Parameters: +0:? Sequence +0:27 move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:27 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:27 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float val}) +0:27 Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( temp uint) +0:? Barrier ( temp void) +0:? Test condition and select ( temp void) +0:? Condition +0:? Compare Equal ( temp bool) +0:? '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 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 0 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 1 (const uint) +0:? move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:? direct index ( temp structure{ temp 3-component vector of float val}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const int) +0:? Function Call: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:? 'i' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Constant: +0:? 2 (const uint) +0:? move second child to first child ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Function Call: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? 'pcf_out' ( temp 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 0 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 0 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 1 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 1 (const int) +0:? move second child to first child ( temp float) +0:? direct index ( patch out float TessLevelOuter) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? Constant: +0:? 2 (const int) +0:? direct index ( temp float) +0:? tfactor: direct index for structure ( temp 3-element array of float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 0 (const int) +0:? Constant: +0:? 2 (const int) +0:? move second child to first child ( temp float) +0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner) +0:? flInFactor: direct index for structure ( temp float) +0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Constant: +0:? 1 (const int) +0:34 Function Definition: PCF(struct-hs_out_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:34 Function Parameters: +0:34 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:37 move second child to first child ( temp float) +0:37 direct index ( temp float) +0:37 tfactor: direct index for structure ( temp 3-element array of float) +0:37 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 direct index ( temp float) +0:37 val: direct index for structure ( temp 3-component vector of float) +0:37 direct index ( temp structure{ temp 3-component vector of float val}) +0:37 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:37 Constant: +0:37 0 (const int) +0:38 move second child to first child ( temp float) +0:38 direct index ( temp float) +0:38 tfactor: direct index for structure ( temp 3-element array of float) +0:38 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 1 (const int) +0:38 direct index ( temp float) +0:38 val: direct index for structure ( temp 3-component vector of float) +0:38 direct index ( temp structure{ temp 3-component vector of float val}) +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 Constant: +0:38 1 (const int) +0:38 Constant: +0:38 0 (const int) +0:38 Constant: +0:38 0 (const int) +0:39 move second child to first child ( temp float) +0:39 direct index ( temp float) +0:39 tfactor: direct index for structure ( temp 3-element array of float) +0:39 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 2 (const int) +0:39 direct index ( temp float) +0:39 val: direct index for structure ( temp 3-component vector of float) +0:39 direct index ( temp structure{ temp 3-component vector of float val}) +0:39 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:39 Constant: +0:39 2 (const int) +0:39 Constant: +0:39 0 (const int) +0:39 Constant: +0:39 0 (const int) +0:40 move second child to first child ( temp float) +0:40 flInFactor: direct index for structure ( temp float) +0:40 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:40 Constant: +0:40 1 (const int) +0:40 Constant: +0:40 4.000000 +0:42 Branch: Return with expression +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out structure{ temp 3-component vector of float val}) +0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 119 + + Capability Tessellation + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint TessellationControl 4 "main" 41 45 48 89 101 118 + ExecutionMode 4 OutputVertices 3 + Name 4 "main" + Name 8 "hs_in_t" + MemberName 8(hs_in_t) 0 "val" + Name 14 "hs_out_t" + MemberName 14(hs_out_t) 0 "val" + Name 18 "@main(struct-hs_in_t-vf31[3];u1;" + Name 16 "i" + Name 17 "cpid" + Name 22 "hs_pcf_t" + MemberName 22(hs_pcf_t) 0 "tfactor" + MemberName 22(hs_pcf_t) 1 "flInFactor" + Name 25 "PCF(struct-hs_out_t-vf31[3];" + Name 24 "pcf_out" + Name 28 "o" + Name 39 "i" + Name 41 "i" + Name 43 "cpid" + Name 45 "cpid" + Name 48 "@entryPointOutput" + Name 49 "param" + Name 51 "param" + Name 63 "pcf_out" + Name 64 "i" + Name 65 "param" + Name 67 "param" + Name 71 "i" + Name 72 "param" + Name 74 "param" + Name 78 "i" + Name 79 "param" + Name 81 "param" + Name 85 "@patchConstantResult" + Name 89 "@patchConstantOutput_tfactor" + Name 101 "@patchConstantOutput_flInFactor" + Name 104 "o" + Name 116 "hs_pcf_t" + Name 118 "@patchConstantOutput" + Decorate 41(i) Location 0 + Decorate 45(cpid) BuiltIn InvocationId + Decorate 48(@entryPointOutput) Location 0 + Decorate 89(@patchConstantOutput_tfactor) Patch + Decorate 89(@patchConstantOutput_tfactor) BuiltIn TessLevelOuter + Decorate 101(@patchConstantOutput_flInFactor) Patch + Decorate 101(@patchConstantOutput_flInFactor) BuiltIn TessLevelInner + Decorate 118(@patchConstantOutput) Patch + Decorate 118(@patchConstantOutput) Location 1 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 3 + 8(hs_in_t): TypeStruct 7(fvec3) + 9: TypeInt 32 0 + 10: 9(int) Constant 3 + 11: TypeArray 8(hs_in_t) 10 + 12: TypePointer Function 11 + 13: TypePointer Function 9(int) + 14(hs_out_t): TypeStruct 7(fvec3) + 15: TypeFunction 14(hs_out_t) 12(ptr) 13(ptr) + 20: TypeArray 14(hs_out_t) 10 + 21: TypeArray 6(float) 10 + 22(hs_pcf_t): TypeStruct 21 6(float) + 23: TypeFunction 22(hs_pcf_t) 20 + 27: TypePointer Function 14(hs_out_t) + 29: TypeInt 32 1 + 30: 29(int) Constant 0 + 34: TypePointer Function 7(fvec3) + 40: TypePointer Input 11 + 41(i): 40(ptr) Variable Input + 44: TypePointer Input 9(int) + 45(cpid): 44(ptr) Variable Input + 47: TypePointer Output 14(hs_out_t) +48(@entryPointOutput): 47(ptr) Variable Output + 54: 9(int) Constant 2 + 55: 9(int) Constant 1 + 56: 9(int) Constant 0 + 58: TypeBool + 62: TypePointer Function 20 + 70: 29(int) Constant 1 + 77: 29(int) Constant 2 + 84: TypePointer Function 22(hs_pcf_t) + 88: TypePointer Output 21 +89(@patchConstantOutput_tfactor): 88(ptr) Variable Output + 90: TypePointer Function 6(float) + 93: TypePointer Output 6(float) +101(@patchConstantOutput_flInFactor): 93(ptr) Variable Output + 111: 6(float) Constant 1082130432 + 116(hs_pcf_t): TypeStruct + 117: TypePointer Output 116(hs_pcf_t) +118(@patchConstantOutput): 117(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 39(i): 12(ptr) Variable Function + 43(cpid): 13(ptr) Variable Function + 49(param): 12(ptr) Variable Function + 51(param): 13(ptr) Variable Function + 63(pcf_out): 62(ptr) Variable Function + 64(i): 12(ptr) Variable Function + 65(param): 12(ptr) Variable Function + 67(param): 13(ptr) Variable Function + 71(i): 12(ptr) Variable Function + 72(param): 12(ptr) Variable Function + 74(param): 13(ptr) Variable Function + 78(i): 12(ptr) Variable Function + 79(param): 12(ptr) Variable Function + 81(param): 13(ptr) Variable Function +85(@patchConstantResult): 84(ptr) Variable Function + 42: 11 Load 41(i) + Store 39(i) 42 + 46: 9(int) Load 45(cpid) + Store 43(cpid) 46 + 50: 11 Load 39(i) + Store 49(param) 50 + 52: 9(int) Load 43(cpid) + Store 51(param) 52 + 53:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 49(param) 51(param) + Store 48(@entryPointOutput) 53 + ControlBarrier 54 55 56 + 57: 9(int) Load 45(cpid) + 59: 58(bool) IEqual 57 30 + SelectionMerge 61 None + BranchConditional 59 60 61 + 60: Label + 66: 11 Load 64(i) + Store 65(param) 66 + Store 67(param) 56 + 68:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 65(param) 67(param) + 69: 27(ptr) AccessChain 63(pcf_out) 30 + Store 69 68 + 73: 11 Load 71(i) + Store 72(param) 73 + Store 74(param) 55 + 75:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 72(param) 74(param) + 76: 27(ptr) AccessChain 63(pcf_out) 70 + Store 76 75 + 80: 11 Load 78(i) + Store 79(param) 80 + Store 81(param) 54 + 82:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 79(param) 81(param) + 83: 27(ptr) AccessChain 63(pcf_out) 77 + Store 83 82 + 86: 20 Load 63(pcf_out) + 87:22(hs_pcf_t) FunctionCall 25(PCF(struct-hs_out_t-vf31[3];) 86 + Store 85(@patchConstantResult) 87 + 91: 90(ptr) AccessChain 85(@patchConstantResult) 30 30 + 92: 6(float) Load 91 + 94: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 30 + Store 94 92 + 95: 90(ptr) AccessChain 85(@patchConstantResult) 30 70 + 96: 6(float) Load 95 + 97: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 70 + Store 97 96 + 98: 90(ptr) AccessChain 85(@patchConstantResult) 30 77 + 99: 6(float) Load 98 + 100: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 77 + Store 100 99 + 102: 90(ptr) AccessChain 85(@patchConstantResult) 70 + 103: 6(float) Load 102 + Store 101(@patchConstantOutput_flInFactor) 103 + Branch 61 + 61: Label + Return + FunctionEnd +18(@main(struct-hs_in_t-vf31[3];u1;):14(hs_out_t) Function None 15 + 16(i): 12(ptr) FunctionParameter + 17(cpid): 13(ptr) FunctionParameter + 19: Label + 28(o): 27(ptr) Variable Function + 31: 9(int) Load 17(cpid) + 32: 6(float) ConvertUToF 31 + 33: 7(fvec3) CompositeConstruct 32 32 32 + 35: 34(ptr) AccessChain 28(o) 30 + Store 35 33 + 36:14(hs_out_t) Load 28(o) + ReturnValue 36 + FunctionEnd +25(PCF(struct-hs_out_t-vf31[3];):22(hs_pcf_t) Function None 23 + 24(pcf_out): 20 FunctionParameter + 26: Label + 104(o): 84(ptr) Variable Function + 105: 6(float) CompositeExtract 24(pcf_out) 0 0 0 + 106: 90(ptr) AccessChain 104(o) 30 30 + Store 106 105 + 107: 6(float) CompositeExtract 24(pcf_out) 1 0 0 + 108: 90(ptr) AccessChain 104(o) 30 70 + Store 108 107 + 109: 6(float) CompositeExtract 24(pcf_out) 2 0 0 + 110: 90(ptr) AccessChain 104(o) 30 77 + Store 110 109 + 112: 90(ptr) AccessChain 104(o) 70 + Store 112 111 + 113:22(hs_pcf_t) Load 104(o) + ReturnValue 113 + FunctionEnd diff --git a/Test/baseResults/hlsl.hull.void.tesc.out b/Test/baseResults/hlsl.hull.void.tesc.out index a2d0a1c7..a429d5f0 100644 --- a/Test/baseResults/hlsl.hull.void.tesc.out +++ b/Test/baseResults/hlsl.hull.void.tesc.out @@ -38,7 +38,8 @@ vertices = 3 0:? Constant: 0:? 0 (const int) 0:? true case -0:? Function Call: PCF( ( temp void) +0:? Sequence +0:? Function Call: PCF( ( temp void) 0:33 Function Definition: PCF( ( temp void) 0:33 Function Parameters: 0:? Linker Objects @@ -89,7 +90,8 @@ vertices = 3 0:? Constant: 0:? 0 (const int) 0:? true case -0:? Function Call: PCF( ( temp void) +0:? Sequence +0:? Function Call: PCF( ( temp void) 0:33 Function Definition: PCF( ( temp void) 0:33 Function Parameters: 0:? Linker Objects diff --git a/Test/hlsl.hull.ctrlpt-1.tesc b/Test/hlsl.hull.ctrlpt-1.tesc new file mode 100644 index 00000000..389c7cb9 --- /dev/null +++ b/Test/hlsl.hull.ctrlpt-1.tesc @@ -0,0 +1,43 @@ +// *** +// per-control-point invocation of PCF from entry point return value +// *** + +struct hs_in_t +{ + float3 val : TEXCOORD0; +}; + +struct hs_pcf_t +{ + float tfactor[3] : SV_TessFactor; + float flInFactor : SV_InsideTessFactor; +}; + +struct hs_out_t +{ + float3 val : TEXCOORD0; +}; + +[ domain ("tri") ] +[ partitioning ("fractional_odd") ] +[ outputtopology ("triangle_cw") ] +[ outputcontrolpoints (3) ] +[ patchconstantfunc ( "PCF" ) ] +hs_out_t main (InputPatch i , uint cpid : SV_OutputControlPointID) +{ + hs_out_t o; + o.val = cpid; + return o; +} + +hs_pcf_t PCF( const OutputPatch pcf_out) +{ + hs_pcf_t o; + + o.tfactor[0] = pcf_out[0].val.x; + o.tfactor[1] = pcf_out[1].val.x; + o.tfactor[2] = pcf_out[2].val.x; + o.flInFactor = 4; + + return o; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 185435a9..756f4df6 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -125,6 +125,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.hull.1.tesc", "main"}, {"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.void.tesc", "main"}, + {"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.identifier.sample.frag", "main"}, {"hlsl.if.frag", "PixelShaderFunction"}, {"hlsl.inoutquals.frag", "main"}, diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index da2f1ae3..7ce6544e 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -7431,6 +7431,11 @@ void HlslParseContext::addPatchConstantInvocation() return intermediate.addSymbol(*it->second->getAsVariable()); }; + + const auto isPerCtrlPt = [this](const TType& type) { + // TODO: this is not sufficient to reject all such cases in malformed shaders. + return type.isArray() && !type.isRuntimeSizedArray(); + }; // We will perform these steps. Each is in a scoped block for separation: they could // become separate functions to make addPatchConstantInvocation shorter. @@ -7441,21 +7446,25 @@ void HlslParseContext::addPatchConstantInvocation() // 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. + // + // 2B: Synthesize per control point invocations of wrapped entry point if the PCF requires them. // // 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). + // + // 4. Create a barrier. + // + // 5/5B. Call the PCF inside an if test for (invocation id == 0). TFunction& patchConstantFunction = const_cast(*candidateList[0]); const int pcfParamCount = patchConstantFunction.getParamCount(); TIntermSymbol* invocationIdSym = findLinkageSymbol(EbvInvocationId); TIntermSequence& epBodySeq = entryPointFunctionBody->getAsAggregate()->getSequence(); + int perCtrlPtParam = -1; // -1 means there isn't one. + // ================ Step 1A: Union Interfaces ================ // Our patch constant function. { @@ -7468,16 +7477,6 @@ void HlslParseContext::addPatchConstantInvocation() 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 notInEntryPoint; @@ -7489,15 +7488,27 @@ void HlslParseContext::addPatchConstantInvocation() // Now we'll add those to the entry and to the linkage. for (int p=0; pclone(); 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; + // Track whether there is any per control point input + if (isPerCtrlPt(*patchConstantFunction[p].type)) { + if (perCtrlPtParam >= 0) { + // Presently we only support one per ctrl pt input. TODO: does HLSL even allow multiple? + error(loc, "unimplemented: multiple per control point inputs to patch constant function", "", ""); + return; + } + perCtrlPtParam = p; + } - if (notInEntryPoint.count(tInterstageIoData(biType, storage)) == 1) - addToLinkage(*paramType, patchConstantFunction[p].name, nullptr); + if (biType != EbvNone) { + TType* paramType = patchConstantFunction[p].type->clone(); + // 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. @@ -7512,36 +7523,50 @@ void HlslParseContext::addPatchConstantInvocation() } TIntermTyped* pcfArguments = nullptr; + TVariable* perCtrlPtVar = nullptr; // ================ Step 1B: Argument synthesis ================ // Create pcfArguments for synthesis of patchconstantfunction invocation // TODO: handle struct or array inputs { for (int p=0; pisArray() || - patchConstantFunction[p].type->isStruct()) { + if ((patchConstantFunction[p].type->isArray() && !isPerCtrlPt(*patchConstantFunction[p].type)) || + (!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* inputArg = nullptr; - TIntermSymbol* builtIn = findLinkageSymbol(biType); + if (p == perCtrlPtParam) { + if (perCtrlPtVar == nullptr) { + perCtrlPtVar = makeInternalVariable(*patchConstantFunction[perCtrlPtParam].name, + *patchConstantFunction[perCtrlPtParam].type); + + perCtrlPtVar->getWritableType().getQualifier().makeTemporary(); + } + inputArg = intermediate.addSymbol(*perCtrlPtVar, loc); + } else { + // find which builtin it is + const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn; + + inputArg = findLinkageSymbol(biType); - if (builtIn == nullptr) { - error(loc, "unable to find patch constant function builtin variable", "", ""); - return; + if (inputArg == nullptr) { + error(loc, "unable to find patch constant function builtin variable", "", ""); + return; + } } if (pcfParamCount == 1) - pcfArguments = builtIn; + pcfArguments = inputArg; else - pcfArguments = intermediate.growAggregate(pcfArguments, builtIn); + pcfArguments = intermediate.growAggregate(pcfArguments, inputArg); } } // ================ Step 2: Synthesize call to PCF ================ + TIntermAggregate* pcfCallSequence = nullptr; TIntermTyped* pcfCall = nullptr; { @@ -7553,7 +7578,8 @@ void HlslParseContext::addPatchConstantInvocation() pcfCall = intermediate.setAggregateOperator(pcfArguments, EOpFunctionCall, patchConstantFunction.getType(), loc); pcfCall->getAsAggregate()->setUserDefined(); pcfCall->getAsAggregate()->setName(patchConstantFunction.getMangledName()); - intermediate.addToCallGraph(infoSink, entryPointFunction->getMangledName(), patchConstantFunction.getMangledName()); + intermediate.addToCallGraph(infoSink, intermediate.getEntryPointMangledName().c_str(), + patchConstantFunction.getMangledName()); if (pcfCall->getAsAggregate()) { TQualifierList& qualifierList = pcfCall->getAsAggregate()->getQualifierList(); @@ -7565,6 +7591,71 @@ void HlslParseContext::addPatchConstantInvocation() } } + // ================ Step 2B: Per Control Point synthesis ================ + // If there is per control point data, we must either emulate that with multiple + // invocations of the entry point to build up an array, or (TODO:) use a yet + // unavailable extension to look across the SIMD lanes. This is the former + // as a placeholder for the latter. + if (perCtrlPtParam >= 0) { + // We must introduce a local temp variable of the type wanted by the PCF input. + const int arraySize = patchConstantFunction[perCtrlPtParam].type->getOuterArraySize(); + + if (entryPointFunction->getType().getBasicType() == EbtVoid) { + error(loc, "entry point must return a value for use with patch constant function", "", ""); + return; + } + + // Create calls to wrapped main to fill in the array. We will substitute fixed values + // of invocation ID when calling the wrapped main. + + // This is the type of the each member of the per ctrl point array. + const TType derefType(perCtrlPtVar->getType(), 0); + + for (int cpt = 0; cpt < arraySize; ++cpt) { + // TODO: improve. substr(1) here is to avoid the '@' that was grafted on but isn't in the symtab + // for this function. + const TString origName = entryPointFunction->getName().substr(1); + TFunction callee(&origName, TType(EbtVoid)); + TIntermTyped* callingArgs = nullptr; + + for (int i = 0; i < entryPointFunction->getParamCount(); i++) { + TParameter& param = (*entryPointFunction)[i]; + TType& paramType = *param.type; + + if (paramType.getQualifier().isParamOutput()) { + error(loc, "unimplemented: entry point outputs in patch constant function invocation", "", ""); + return; + } + + if (paramType.getQualifier().isParamInput()) { + TIntermTyped* arg = nullptr; + if ((*entryPointFunction)[i].declaredBuiltIn == EbvInvocationId) { + // substitute invocation ID with the array element ID + arg = intermediate.addConstantUnion(cpt, loc); + } else { + TVariable* argVar = makeInternalVariable(*param.name, *param.type); + argVar->getWritableType().getQualifier().makeTemporary(); + arg = intermediate.addSymbol(*argVar); + } + + handleFunctionArgument(&callee, callingArgs, arg); + } + } + + // Call and assign to per ctrl point variable + currentCaller = intermediate.getEntryPointMangledName().c_str(); + TIntermTyped* callReturn = handleFunctionCall(loc, &callee, callingArgs); + TIntermTyped* index = intermediate.addConstantUnion(cpt, loc); + TIntermSymbol* perCtrlPtSym = intermediate.addSymbol(*perCtrlPtVar, loc); + TIntermTyped* element = intermediate.addIndex(EOpIndexDirect, perCtrlPtSym, index, loc); + element->setType(derefType); + element->setLoc(loc); + + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, + handleAssign(loc, EOpAssign, element, callReturn)); + } + } + // ================ Step 3: Create return Sequence ================ // Return sequence: copy PCF result to a temporary, then to shader output variable. if (pcfCall->getBasicType() != EbtVoid) { @@ -7581,30 +7672,31 @@ void HlslParseContext::addPatchConstantInvocation() if (patchConstantFunction.getDeclaredBuiltInType() != EbvNone) outType.getQualifier().builtIn = patchConstantFunction.getDeclaredBuiltInType(); + outType.getQualifier().patch = true; // make it a per-patch variable + TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType); pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut; if (pcfOutput->getType().containsBuiltInInterstageIO(language)) split(*pcfOutput); + assignLocations(*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); + TIntermSymbol* pcfResultVar = intermediate.addSymbol(*pcfCallResult, loc); + TIntermNode* pcfResultAssign = handleAssign(loc, EOpAssign, pcfResultVar, pcfCall); 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; + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfResultAssign); + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfResultToOut); + } else { + pcfCallSequence = intermediate.growAggregate(pcfCallSequence, pcfCall); } // ================ Step 4: Barrier ================ @@ -7613,12 +7705,14 @@ void HlslParseContext::addPatchConstantInvocation() barrier->setType(TType(EbtVoid)); epBodySeq.insert(epBodySeq.end(), barrier); - // ================ Step 5: Test on invocation ID ================ + // ================ 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); + + // ================ Step 5B: Create if statement on Invocation ID == 0 ================ + intermediate.setAggregateOperator(pcfCallSequence, EOpSequence, TType(EbtVoid), loc); + TIntermTyped* invocationIdTest = new TIntermSelection(cmp, pcfCallSequence, nullptr); invocationIdTest->setLoc(loc); // add our test sequence before the return.