From 067eb9b48a476c39c7efb62fc023ebf714d3d4e4 Mon Sep 17 00:00:00 2001 From: steve-lunarg Date: Sat, 1 Apr 2017 15:34:48 -0600 Subject: [PATCH] WIP: HLSL: Support InputPatch variables in patch constant functions Previously, patch constant functions only accepted OutputPatch. This adds InputPatch support, via a pseudo-builtin variable type, so that the patch can be tracked clear through from the qualifier. --- Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out | 633 +++++++++++++++++++ Test/hlsl.hull.ctrlpt-2.tesc | 47 ++ glslang/Include/BaseTypes.h | 2 + gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslGrammar.cpp | 11 +- hlsl/hlslGrammar.h | 2 +- hlsl/hlslParseHelper.cpp | 76 ++- hlsl/hlslParseHelper.h | 1 + 8 files changed, 739 insertions(+), 34 deletions(-) create mode 100644 Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out create mode 100644 Test/hlsl.hull.ctrlpt-2.tesc diff --git a/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out new file mode 100644 index 000000000..886cff8ca --- /dev/null +++ b/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out @@ -0,0 +1,633 @@ +hlsl.hull.ctrlpt-2.tesc +Shader version: 450 +vertices = 3 +vertex spacing = fractional_odd_spacing +triangle order = cw +0:? Sequence +0:28 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:28 Function Parameters: +0:28 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:28 'cpid' ( in uint) +0:? Sequence +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 direct index ( temp structure{ temp 3-component vector of float val}) +0:29 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Constant: +0:29 0 (const int) +0:32 move second child to first child ( temp 3-component vector of float) +0:32 val: direct index for structure ( temp 3-component vector of float) +0:32 'o' ( temp structure{ temp 3-component vector of float val}) +0:32 Constant: +0:32 0 (const int) +0:32 Construct vec3 ( temp 3-component vector of float) +0:32 Convert uint to float ( temp float) +0:32 'cpid' ( in uint) +0:33 Branch: Return with expression +0:33 'o' ( temp structure{ temp 3-component vector of float val}) +0:28 Function Definition: main( ( temp void) +0:28 Function Parameters: +0:? Sequence +0:28 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:28 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:28 indirect index ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:28 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];struct-hs_in_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:? 'i' (layout( location=0) in 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 4-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 4-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 4-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:? direct index ( patch out float TessLevelInner) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) +0:? Constant: +0:? 0 (const int) +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:38 Function Definition: PCF(struct-hs_out_t-vf31[3];struct-hs_in_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Function Parameters: +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 'pcf_in' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:41 move second child to first child ( temp float) +0:41 direct index ( temp float) +0:41 tfactor: direct index for structure ( temp 3-element array of float) +0:41 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:41 direct index ( temp float) +0:41 val: direct index for structure ( temp 3-component vector of float) +0:41 direct index ( temp structure{ temp 3-component vector of float val}) +0:41 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:42 move second child to first child ( temp float) +0:42 direct index ( temp float) +0:42 tfactor: direct index for structure ( temp 3-element array of float) +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:42 Constant: +0:42 0 (const int) +0:42 Constant: +0:42 1 (const int) +0:42 direct index ( temp float) +0:42 val: direct index for structure ( temp 3-component vector of float) +0:42 direct index ( temp structure{ temp 3-component vector of float val}) +0:42 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:42 Constant: +0:42 1 (const int) +0:42 Constant: +0:42 0 (const int) +0:42 Constant: +0:42 0 (const int) +0:43 move second child to first child ( temp float) +0:43 direct index ( temp float) +0:43 tfactor: direct index for structure ( temp 3-element array of float) +0:43 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:43 Constant: +0:43 0 (const int) +0:43 Constant: +0:43 2 (const int) +0:43 direct index ( temp float) +0:43 val: direct index for structure ( temp 3-component vector of float) +0:43 direct index ( temp structure{ temp 3-component vector of float val}) +0:43 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:43 Constant: +0:43 2 (const int) +0:43 Constant: +0:43 0 (const int) +0:43 Constant: +0:43 0 (const int) +0:44 move second child to first child ( temp float) +0:44 flInFactor: direct index for structure ( temp float) +0:44 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:44 Constant: +0:44 1 (const int) +0:44 Constant: +0:44 4.000000 +0:46 Branch: Return with expression +0:46 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 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:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) + + +Linked tessellation control stage: + + +Shader version: 450 +vertices = 3 +vertex spacing = fractional_odd_spacing +triangle order = cw +0:? Sequence +0:28 Function Definition: @main(struct-hs_in_t-vf31[3];u1; ( temp structure{ temp 3-component vector of float val}) +0:28 Function Parameters: +0:28 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:28 'cpid' ( in uint) +0:? Sequence +0:29 val: direct index for structure ( temp 3-component vector of float) +0:29 direct index ( temp structure{ temp 3-component vector of float val}) +0:29 'i' ( in 3-element array of structure{ temp 3-component vector of float val}) +0:29 Constant: +0:29 0 (const int) +0:29 Constant: +0:29 0 (const int) +0:32 move second child to first child ( temp 3-component vector of float) +0:32 val: direct index for structure ( temp 3-component vector of float) +0:32 'o' ( temp structure{ temp 3-component vector of float val}) +0:32 Constant: +0:32 0 (const int) +0:32 Construct vec3 ( temp 3-component vector of float) +0:32 Convert uint to float ( temp float) +0:32 'cpid' ( in uint) +0:33 Branch: Return with expression +0:33 'o' ( temp structure{ temp 3-component vector of float val}) +0:28 Function Definition: main( ( temp void) +0:28 Function Parameters: +0:? Sequence +0:28 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:28 move second child to first child ( temp uint) +0:? 'cpid' ( temp uint) +0:? 'cpid' ( in uint InvocationID) +0:28 move second child to first child ( temp structure{ temp 3-component vector of float val}) +0:28 indirect index ( temp structure{ temp 3-component vector of float val}) +0:? '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float val}) +0:? 'cpid' ( in uint InvocationID) +0:28 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];struct-hs_in_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:? 'i' (layout( location=0) in 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 4-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 4-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 4-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:? direct index ( patch out float TessLevelInner) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) +0:? Constant: +0:? 0 (const int) +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:38 Function Definition: PCF(struct-hs_out_t-vf31[3];struct-hs_in_t-vf31[3]; ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:38 Function Parameters: +0:38 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:38 'pcf_in' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:? Sequence +0:41 move second child to first child ( temp float) +0:41 direct index ( temp float) +0:41 tfactor: direct index for structure ( temp 3-element array of float) +0:41 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:41 direct index ( temp float) +0:41 val: direct index for structure ( temp 3-component vector of float) +0:41 direct index ( temp structure{ temp 3-component vector of float val}) +0:41 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:41 Constant: +0:41 0 (const int) +0:42 move second child to first child ( temp float) +0:42 direct index ( temp float) +0:42 tfactor: direct index for structure ( temp 3-element array of float) +0:42 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:42 Constant: +0:42 0 (const int) +0:42 Constant: +0:42 1 (const int) +0:42 direct index ( temp float) +0:42 val: direct index for structure ( temp 3-component vector of float) +0:42 direct index ( temp structure{ temp 3-component vector of float val}) +0:42 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:42 Constant: +0:42 1 (const int) +0:42 Constant: +0:42 0 (const int) +0:42 Constant: +0:42 0 (const int) +0:43 move second child to first child ( temp float) +0:43 direct index ( temp float) +0:43 tfactor: direct index for structure ( temp 3-element array of float) +0:43 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:43 Constant: +0:43 0 (const int) +0:43 Constant: +0:43 2 (const int) +0:43 direct index ( temp float) +0:43 val: direct index for structure ( temp 3-component vector of float) +0:43 direct index ( temp structure{ temp 3-component vector of float val}) +0:43 'pcf_out' ( const (read only) 3-element array of structure{ temp 3-component vector of float val}) +0:43 Constant: +0:43 2 (const int) +0:43 Constant: +0:43 0 (const int) +0:43 Constant: +0:43 0 (const int) +0:44 move second child to first child ( temp float) +0:44 flInFactor: direct index for structure ( temp float) +0:44 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:44 Constant: +0:44 1 (const int) +0:44 Constant: +0:44 4.000000 +0:46 Branch: Return with expression +0:46 'o' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor}) +0:? Linker Objects +0:? '@entryPointOutput' (layout( location=0) out 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:? 'cpid' ( in uint InvocationID) +0:? '@patchConstantOutput' (layout( location=1) patch out structure{}) +0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter) +0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 129 + + Capability Tessellation + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint TessellationControl 4 "main" 42 46 49 96 110 128 + ExecutionMode 4 OutputVertices 3 + ExecutionMode 4 Triangles + ExecutionMode 4 SpacingFractionalOdd + ExecutionMode 4 VertexOrderCw + 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 26 "PCF(struct-hs_out_t-vf31[3];struct-hs_in_t-vf31[3];" + Name 24 "pcf_out" + Name 25 "pcf_in" + Name 31 "o" + Name 40 "i" + Name 42 "i" + Name 44 "cpid" + Name 46 "cpid" + Name 49 "@entryPointOutput" + Name 51 "param" + Name 53 "param" + Name 67 "pcf_out" + Name 68 "i" + Name 69 "param" + Name 71 "param" + Name 75 "i" + Name 76 "param" + Name 78 "param" + Name 82 "i" + Name 83 "param" + Name 85 "param" + Name 89 "@patchConstantResult" + Name 96 "@patchConstantOutput_tfactor" + Name 110 "@patchConstantOutput_flInFactor" + Name 114 "o" + Name 126 "hs_pcf_t" + Name 128 "@patchConstantOutput" + Decorate 42(i) Location 0 + Decorate 46(cpid) BuiltIn InvocationId + Decorate 49(@entryPointOutput) Location 0 + Decorate 96(@patchConstantOutput_tfactor) Patch + Decorate 96(@patchConstantOutput_tfactor) BuiltIn TessLevelOuter + Decorate 110(@patchConstantOutput_flInFactor) Patch + Decorate 110(@patchConstantOutput_flInFactor) BuiltIn TessLevelInner + Decorate 128(@patchConstantOutput) Patch + Decorate 128(@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 11 + 28: TypeInt 32 1 + 29: 28(int) Constant 0 + 30: TypePointer Function 14(hs_out_t) + 35: TypePointer Function 7(fvec3) + 41: TypePointer Input 11 + 42(i): 41(ptr) Variable Input + 45: TypePointer Input 9(int) + 46(cpid): 45(ptr) Variable Input + 48: TypePointer Output 20 +49(@entryPointOutput): 48(ptr) Variable Output + 56: TypePointer Output 14(hs_out_t) + 58: 9(int) Constant 2 + 59: 9(int) Constant 1 + 60: 9(int) Constant 0 + 62: TypeBool + 66: TypePointer Function 20 + 74: 28(int) Constant 1 + 81: 28(int) Constant 2 + 88: TypePointer Function 22(hs_pcf_t) + 93: 9(int) Constant 4 + 94: TypeArray 6(float) 93 + 95: TypePointer Output 94 +96(@patchConstantOutput_tfactor): 95(ptr) Variable Output + 97: TypePointer Function 6(float) + 100: TypePointer Output 6(float) + 108: TypeArray 6(float) 58 + 109: TypePointer Output 108 +110(@patchConstantOutput_flInFactor): 109(ptr) Variable Output + 121: 6(float) Constant 1082130432 + 126(hs_pcf_t): TypeStruct + 127: TypePointer Output 126(hs_pcf_t) +128(@patchConstantOutput): 127(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 40(i): 12(ptr) Variable Function + 44(cpid): 13(ptr) Variable Function + 51(param): 12(ptr) Variable Function + 53(param): 13(ptr) Variable Function + 67(pcf_out): 66(ptr) Variable Function + 68(i): 12(ptr) Variable Function + 69(param): 12(ptr) Variable Function + 71(param): 13(ptr) Variable Function + 75(i): 12(ptr) Variable Function + 76(param): 12(ptr) Variable Function + 78(param): 13(ptr) Variable Function + 82(i): 12(ptr) Variable Function + 83(param): 12(ptr) Variable Function + 85(param): 13(ptr) Variable Function +89(@patchConstantResult): 88(ptr) Variable Function + 43: 11 Load 42(i) + Store 40(i) 43 + 47: 9(int) Load 46(cpid) + Store 44(cpid) 47 + 50: 9(int) Load 46(cpid) + 52: 11 Load 40(i) + Store 51(param) 52 + 54: 9(int) Load 44(cpid) + Store 53(param) 54 + 55:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 51(param) 53(param) + 57: 56(ptr) AccessChain 49(@entryPointOutput) 50 + Store 57 55 + ControlBarrier 58 59 60 + 61: 9(int) Load 46(cpid) + 63: 62(bool) IEqual 61 29 + SelectionMerge 65 None + BranchConditional 63 64 65 + 64: Label + 70: 11 Load 68(i) + Store 69(param) 70 + Store 71(param) 60 + 72:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 69(param) 71(param) + 73: 30(ptr) AccessChain 67(pcf_out) 29 + Store 73 72 + 77: 11 Load 75(i) + Store 76(param) 77 + Store 78(param) 59 + 79:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 76(param) 78(param) + 80: 30(ptr) AccessChain 67(pcf_out) 74 + Store 80 79 + 84: 11 Load 82(i) + Store 83(param) 84 + Store 85(param) 58 + 86:14(hs_out_t) FunctionCall 18(@main(struct-hs_in_t-vf31[3];u1;) 83(param) 85(param) + 87: 30(ptr) AccessChain 67(pcf_out) 81 + Store 87 86 + 90: 20 Load 67(pcf_out) + 91: 11 Load 42(i) + 92:22(hs_pcf_t) FunctionCall 26(PCF(struct-hs_out_t-vf31[3];struct-hs_in_t-vf31[3];) 90 91 + Store 89(@patchConstantResult) 92 + 98: 97(ptr) AccessChain 89(@patchConstantResult) 29 29 + 99: 6(float) Load 98 + 101: 100(ptr) AccessChain 96(@patchConstantOutput_tfactor) 29 + Store 101 99 + 102: 97(ptr) AccessChain 89(@patchConstantResult) 29 74 + 103: 6(float) Load 102 + 104: 100(ptr) AccessChain 96(@patchConstantOutput_tfactor) 74 + Store 104 103 + 105: 97(ptr) AccessChain 89(@patchConstantResult) 29 81 + 106: 6(float) Load 105 + 107: 100(ptr) AccessChain 96(@patchConstantOutput_tfactor) 81 + Store 107 106 + 111: 97(ptr) AccessChain 89(@patchConstantResult) 74 + 112: 6(float) Load 111 + 113: 100(ptr) AccessChain 110(@patchConstantOutput_flInFactor) 29 + Store 113 112 + Branch 65 + 65: 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 + 31(o): 30(ptr) Variable Function + 32: 9(int) Load 17(cpid) + 33: 6(float) ConvertUToF 32 + 34: 7(fvec3) CompositeConstruct 33 33 33 + 36: 35(ptr) AccessChain 31(o) 29 + Store 36 34 + 37:14(hs_out_t) Load 31(o) + ReturnValue 37 + FunctionEnd +26(PCF(struct-hs_out_t-vf31[3];struct-hs_in_t-vf31[3];):22(hs_pcf_t) Function None 23 + 24(pcf_out): 20 FunctionParameter + 25(pcf_in): 11 FunctionParameter + 27: Label + 114(o): 88(ptr) Variable Function + 115: 6(float) CompositeExtract 24(pcf_out) 0 0 0 + 116: 97(ptr) AccessChain 114(o) 29 29 + Store 116 115 + 117: 6(float) CompositeExtract 24(pcf_out) 1 0 0 + 118: 97(ptr) AccessChain 114(o) 29 74 + Store 118 117 + 119: 6(float) CompositeExtract 24(pcf_out) 2 0 0 + 120: 97(ptr) AccessChain 114(o) 29 81 + Store 120 119 + 122: 97(ptr) AccessChain 114(o) 74 + Store 122 121 + 123:22(hs_pcf_t) Load 114(o) + ReturnValue 123 + FunctionEnd diff --git a/Test/hlsl.hull.ctrlpt-2.tesc b/Test/hlsl.hull.ctrlpt-2.tesc new file mode 100644 index 000000000..1f65ce4b1 --- /dev/null +++ b/Test/hlsl.hull.ctrlpt-2.tesc @@ -0,0 +1,47 @@ +// *** +// per-control-point invocation of PCF from entry point return value with +// both OutputPatch and InputPatch given to PCF. +// *** + +struct hs_in_t +{ + float3 val : TEXCOORD0; +}; + +struct hs_pcf_t +{ + float tfactor[3] : SV_TessFactor; // must turn into a size 4 array in SPIR-V + float flInFactor : SV_InsideTessFactor; // must turn into a size 2 array in SPIR-V +}; + +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) +{ + i[0].val; + + hs_out_t o; + o.val = cpid; + return o; +} + +hs_pcf_t PCF( const OutputPatch pcf_out, + const InputPatch pcf_in) +{ + 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/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index 45aff022b..a805a0603 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -220,6 +220,8 @@ enum TBuiltInVariable { EbvFragDepthLesser, EbvStencilRef, EbvGsOutputStream, + EbvOutputPatch, + EbvInputPatch, EbvLast }; diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 2a211bc13..ca0f4fbf6 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -129,6 +129,7 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.hull.2.tesc", "main"}, {"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.ctrlpt-1.tesc", "main"}, + {"hlsl.hull.ctrlpt-2.tesc", "main"}, {"hlsl.identifier.sample.frag", "main"}, {"hlsl.if.frag", "PixelShaderFunction"}, {"hlsl.implicitBool.frag", "main"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index b9d9a3a13..a1c05cf44 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -963,14 +963,14 @@ bool HlslGrammar::acceptOutputPrimitiveGeometry(TLayoutGeometry& geometry) // : INPUTPATCH // | OUTPUTPATCH // -bool HlslGrammar::acceptTessellationDeclType() +bool HlslGrammar::acceptTessellationDeclType(TBuiltInVariable& patchType) { // read geometry type const EHlslTokenClass tessType = peek(); switch (tessType) { - case EHTokInputPatch: break; - case EHTokOutputPatch: break; + case EHTokInputPatch: patchType = EbvInputPatch; break; + case EHTokOutputPatch: patchType = EbvOutputPatch; break; default: return false; // not a tessellation decl } @@ -984,7 +984,9 @@ bool HlslGrammar::acceptTessellationDeclType() // bool HlslGrammar::acceptTessellationPatchTemplateType(TType& type) { - if (! acceptTessellationDeclType()) + TBuiltInVariable patchType; + + if (! acceptTessellationDeclType(patchType)) return false; if (! acceptTokenClass(EHTokLeftAngle)) @@ -1011,6 +1013,7 @@ bool HlslGrammar::acceptTessellationPatchTemplateType(TType& type) TArraySizes* arraySizes = new TArraySizes; arraySizes->addInnerSize(size->getAsConstantUnion()->getConstArray()[0].getIConst()); type.newArraySizes(*arraySizes); + type.getQualifier().builtIn = patchType; if (! acceptTokenClass(EHTokRightAngle)) { expected("right angle bracket"); diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index e88d78057..6d8ed8fd6 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -79,7 +79,7 @@ namespace glslang { bool acceptTemplateVecMatBasicType(TBasicType&); bool acceptVectorTemplateType(TType&); bool acceptMatrixTemplateType(TType&); - bool acceptTessellationDeclType(); + bool acceptTessellationDeclType(TBuiltInVariable&); bool acceptTessellationPatchTemplateType(TType&); bool acceptStreamOutTemplateType(TType&, TLayoutGeometry&); bool acceptOutputPrimitiveGeometry(TLayoutGeometry&); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 27c09a269..7f6f7b213 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -67,7 +67,8 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int sourceEntryPointName(sourceEntryPointName), entryPointFunction(nullptr), entryPointFunctionBody(nullptr), - gsStreamOutput(nullptr) + gsStreamOutput(nullptr), + inputPatch(nullptr) { globalUniformDefaults.clear(); globalUniformDefaults.layoutMatrix = ElmRowMajor; @@ -1377,6 +1378,7 @@ TIntermTyped* HlslParseContext::splitAccessStruct(const TSourceLoc& loc, TInterm void HlslParseContext::trackLinkage(TSymbol& symbol) { TBuiltInVariable biType = symbol.getType().getQualifier().builtIn; + if (biType != EbvNone) builtInLinkageSymbols[biType] = symbol.clone(); @@ -1811,6 +1813,7 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct else if (variable.getType().containsBuiltInInterstageIO(language)) split(variable); } + assignLocations(variable); }; if (entryPointOutput) @@ -1988,6 +1991,7 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return correctOutput(ioVariable->getWritableType().getQualifier()); } ioVariable->getWritableType().getQualifier().storage = storage; + return ioVariable; }; @@ -2022,6 +2026,9 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return if (paramType.getQualifier().isParamInput()) { TVariable* argAsGlobal = makeIoVariable(function[i].name->c_str(), paramType, EvqVaryingIn); inputs.push_back(argAsGlobal); + + if (function[i].declaredBuiltIn == EbvInputPatch) + inputPatch = argAsGlobal; } if (paramType.getQualifier().isParamOutput()) { TVariable* argAsGlobal = makeIoVariable(function[i].name->c_str(), paramType, EvqVaryingOut); @@ -7574,7 +7581,10 @@ void HlslParseContext::addPatchConstantInvocation() // Look for builtin variables in a function's parameter list. const auto findBuiltIns = [&](const TFunction& function, std::set& builtIns) { for (int p=0; pgetQualifier().storage; + TStorageQualifier storage = function[p].type->getQualifier().storage; + + if (storage == EvqConstReadOnly) // treated identically to input + storage = EvqIn; if (function[p].declaredBuiltIn != EbvNone) builtIns.insert(HlslParseContext::tInterstageIoData(function[p].declaredBuiltIn, storage)); @@ -7605,9 +7615,11 @@ void HlslParseContext::addPatchConstantInvocation() } }; - 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(); + const auto isOutputPatch = [this](TFunction& patchConstantFunction, int param) { + const TType& type = *patchConstantFunction[param].type; + const TBuiltInVariable biType = patchConstantFunction[param].declaredBuiltIn; + + return type.isArray() && !type.isRuntimeSizedArray() && biType == EbvOutputPatch; }; // We will perform these steps. Each is in a scoped block for separation: they could @@ -7636,7 +7648,7 @@ void HlslParseContext::addPatchConstantInvocation() TIntermSymbol* invocationIdSym = findLinkageSymbol(EbvInvocationId); TIntermSequence& epBodySeq = entryPointFunctionBody->getAsAggregate()->getSequence(); - int perCtrlPtParam = -1; // -1 means there isn't one. + int outPatchParam = -1; // -1 means there isn't one. // ================ Step 1A: Union Interfaces ================ // Our patch constant function. @@ -7662,25 +7674,37 @@ void HlslParseContext::addPatchConstantInvocation() // Now we'll add those to the entry and to the linkage. for (int p=0; pgetQualifier().storage; + TStorageQualifier storage = patchConstantFunction[p].type->getQualifier().storage; - // 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", "", ""); + // Track whether there is an output patch param + if (isOutputPatch(patchConstantFunction, p)) { + if (outPatchParam >= 0) { + // Presently we only support one per ctrl pt input. + error(loc, "unimplemented: multiple output patches in patch constant function", "", ""); return; } - perCtrlPtParam = p; + outPatchParam = p; } 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 (storage == EvqConstReadOnly) // treated identically to input + storage = EvqIn; + + // Presently, the only non-builtin we support is InputPatch, which is treated as + // a pseudo-builtin. + if (biType == EbvInputPatch) { + builtInLinkageSymbols[biType] = inputPatch; + } else if (biType == EbvOutputPatch) { + // Nothing... + } else { + // 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); + } } } @@ -7703,18 +7727,12 @@ void HlslParseContext::addPatchConstantInvocation() // TODO: handle struct or array inputs { for (int p=0; pisArray() && !isPerCtrlPt(*patchConstantFunction[p].type)) || - (!patchConstantFunction[p].type->isArray() && patchConstantFunction[p].type->isStruct())) { - error(loc, "unimplemented array or variable in patch constant function signature", "", ""); - return; - } - TIntermSymbol* inputArg = nullptr; - if (p == perCtrlPtParam) { + if (p == outPatchParam) { if (perCtrlPtVar == nullptr) { - perCtrlPtVar = makeInternalVariable(*patchConstantFunction[perCtrlPtParam].name, - *patchConstantFunction[perCtrlPtParam].type); + perCtrlPtVar = makeInternalVariable(*patchConstantFunction[outPatchParam].name, + *patchConstantFunction[outPatchParam].type); perCtrlPtVar->getWritableType().getQualifier().makeTemporary(); } @@ -7724,7 +7742,7 @@ void HlslParseContext::addPatchConstantInvocation() const TBuiltInVariable biType = patchConstantFunction[p].declaredBuiltIn; inputArg = findLinkageSymbol(biType); - + if (inputArg == nullptr) { error(loc, "unable to find patch constant function builtin variable", "", ""); return; @@ -7769,9 +7787,9 @@ void HlslParseContext::addPatchConstantInvocation() // 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) { + if (outPatchParam >= 0) { // We must introduce a local temp variable of the type wanted by the PCF input. - const int arraySize = patchConstantFunction[perCtrlPtParam].type->getOuterArraySize(); + const int arraySize = patchConstantFunction[outPatchParam].type->getOuterArraySize(); if (entryPointFunction->getType().getBasicType() == EbtVoid) { error(loc, "entry point must return a value for use with patch constant function", "", ""); diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 0796b6a96..ff597c288 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -386,6 +386,7 @@ protected: }; TMap interstageBuiltInIo; // individual builtin interstage IO vars, indexed by builtin type. + TVariable* inputPatch; // We have to move array references to structs containing builtin interstage IO to the split variables. // This is only handled for one level. This stores the index, because we'll need it in the future, since