WIP: HLSL: Support InputPatch variables in patch constant functions
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Sat, 1 Apr 2017 21:34:48 +0000 (15:34 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Tue, 4 Apr 2017 01:39:44 +0000 (19:39 -0600)
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 [new file with mode: 0644]
Test/hlsl.hull.ctrlpt-2.tesc [new file with mode: 0644]
glslang/Include/BaseTypes.h
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp
hlsl/hlslGrammar.h
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

diff --git a/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out b/Test/baseResults/hlsl.hull.ctrlpt-2.tesc.out
new file mode 100644 (file)
index 0000000..886cff8
--- /dev/null
@@ -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 (file)
index 0000000..1f65ce4
--- /dev/null
@@ -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 <hs_in_t, 3> i , uint cpid : SV_OutputControlPointID)
+{
+    i[0].val;
+
+    hs_out_t o;
+    o.val = cpid;
+    return o;
+}
+
+hs_pcf_t PCF( const OutputPatch <hs_out_t, 3> pcf_out,
+              const InputPatch <hs_in_t, 3> 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;
+}
index 45aff02..a805a06 100644 (file)
@@ -220,6 +220,8 @@ enum TBuiltInVariable {
     EbvFragDepthLesser,
     EbvStencilRef,
     EbvGsOutputStream,
+    EbvOutputPatch,
+    EbvInputPatch,
 
     EbvLast
 };
index 2a211bc..ca0f4fb 100644 (file)
@@ -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"},
index b9d9a3a..a1c05cf 100755 (executable)
@@ -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");
index e88d780..6d8ed8f 100755 (executable)
@@ -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&);
index 27c09a2..7f6f7b2 100755 (executable)
@@ -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<tInterstageIoData>& builtIns) {
         for (int p=0; p<function.getParamCount(); ++p) {
-            const TStorageQualifier storage = function[p].type->getQualifier().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; p<pcfParamCount; ++p) {
             const TBuiltInVariable biType   = patchConstantFunction[p].declaredBuiltIn;
-            const TStorageQualifier storage = patchConstantFunction[p].type->getQualifier().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; p<pcfParamCount; ++p) {
-            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;
-            }
-        
             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", "", "");
index 0796b6a..ff597c2 100755 (executable)
@@ -386,6 +386,7 @@ protected:
     };
 
     TMap<tInterstageIoData, TVariable*> 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