From 280c75ca511416f3539957fa7219b3ee2de7e0eb Mon Sep 17 00:00:00 2001
From: LoopDawg <sk_opengl@khasekhemwy.net>
Date: Fri, 8 Dec 2017 12:01:16 -0700
Subject: [PATCH] HLSL: Allow primitive id on hull shader inputs

Fixes #979
---
 Test/baseResults/hlsl.color.hull.tesc.out | 573 ++++++++++++++++++++++
 Test/hlsl.color.hull.tesc                 |  74 +++
 gtests/Hlsl.FromFile.cpp                  |   1 +
 hlsl/hlslParseHelper.cpp                  |   2 +-
 4 files changed, 649 insertions(+), 1 deletion(-)
 create mode 100644 Test/baseResults/hlsl.color.hull.tesc.out
 create mode 100644 Test/hlsl.color.hull.tesc

diff --git a/Test/baseResults/hlsl.color.hull.tesc.out b/Test/baseResults/hlsl.color.hull.tesc.out
new file mode 100644
index 000000000..92ca0c357
--- /dev/null
+++ b/Test/baseResults/hlsl.color.hull.tesc.out
@@ -0,0 +1,573 @@
+hlsl.color.hull.tesc
+Shader version: 500
+vertices = 3
+vertex spacing = equal_spacing
+triangle order = cw
+0:? Sequence
+0:37  Function Definition: ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1; ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:37    Function Parameters: 
+0:37      'inputPatch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:37      'patchId' ( in uint)
+0:?     Sequence
+0:42      move second child to first child ( temp float)
+0:42        direct index ( temp float)
+0:42          edges: direct index for structure ( temp 3-element array of float)
+0:42            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:42            Constant:
+0:42              0 (const int)
+0:42          Constant:
+0:42            0 (const int)
+0:42        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:42          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:42          Constant:
+0:42            0 (const uint)
+0:43      move second child to first child ( temp float)
+0:43        direct index ( temp float)
+0:43          edges: direct index for structure ( temp 3-element array of float)
+0:43            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:43            Constant:
+0:43              0 (const int)
+0:43          Constant:
+0:43            1 (const int)
+0:43        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:43          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:43          Constant:
+0:43            0 (const uint)
+0:44      move second child to first child ( temp float)
+0:44        direct index ( temp float)
+0:44          edges: direct index for structure ( temp 3-element array of float)
+0:44            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:44            Constant:
+0:44              0 (const int)
+0:44          Constant:
+0:44            2 (const int)
+0:44        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:44          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:44          Constant:
+0:44            0 (const uint)
+0:47      move second child to first child ( temp float)
+0:47        inside: direct index for structure ( temp float)
+0:47          'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:47          Constant:
+0:47            1 (const int)
+0:47        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:47          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:47          Constant:
+0:47            0 (const uint)
+0:49      Branch: Return with expression
+0:49        'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:63  Function Definition: @main(struct-HullInputType-vf3-vf41[3];u1;u1; ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63    Function Parameters: 
+0:63      'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63      'pointId' ( in uint)
+0:63      'patchId' ( in uint)
+0:?     Sequence
+0:67      move second child to first child ( temp 3-component vector of float)
+0:67        position: direct index for structure ( temp 3-component vector of float)
+0:67          'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67          Constant:
+0:67            0 (const int)
+0:67        position: direct index for structure ( temp 3-component vector of float)
+0:67          indirect index ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67            'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67            'pointId' ( in uint)
+0:67          Constant:
+0:67            0 (const int)
+0:70      move second child to first child ( temp 4-component vector of float)
+0:70        color: direct index for structure ( temp 4-component vector of float)
+0:70          'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70          Constant:
+0:70            1 (const int)
+0:70        color: direct index for structure ( temp 4-component vector of float)
+0:70          indirect index ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70            'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70            'pointId' ( in uint)
+0:70          Constant:
+0:70            1 (const int)
+0:72      Branch: Return with expression
+0:72        'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63  Function Definition: main( ( temp void)
+0:63    Function Parameters: 
+0:?     Sequence
+0:63      move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?         'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?         'patch' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63      move second child to first child ( temp uint)
+0:?         'pointId' ( temp uint)
+0:?         'pointId' ( in uint InvocationID)
+0:63      move second child to first child ( temp uint)
+0:?         'patchId' ( temp uint)
+0:?         'patchId' ( in uint PrimitiveID)
+0:63      move second child to first child ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63        indirect index (layout( location=0) out structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'pointId' ( in uint InvocationID)
+0:63        Function Call: @main(struct-HullInputType-vf3-vf41[3];u1;u1; ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'pointId' ( temp uint)
+0:?           'patchId' ( temp uint)
+0:?       Barrier ( temp void)
+0:?       Test condition and select ( temp void)
+0:?         Condition
+0:?         Compare Equal ( temp bool)
+0:?           'pointId' ( 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-element array of float edges,  temp float inside})
+0:?             '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?             Function Call: ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1; ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?               'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?               'patchId' ( in uint PrimitiveID)
+0:?           Sequence
+0:?             move second child to first child ( temp float)
+0:?               direct index ( patch out float TessLevelOuter)
+0:?                 '@patchConstantOutput.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   0 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   1 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   2 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.inside' ( patch out 2-element array of float TessLevelInner)
+0:?                 Constant:
+0:?                   0 (const int)
+0:?               inside: direct index for structure ( temp float)
+0:?                 '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?                 Constant:
+0:?                   1 (const int)
+0:?   Linker Objects
+0:?     'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:?     '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?     'patch' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?     'pointId' ( in uint InvocationID)
+0:?     'patchId' ( in uint PrimitiveID)
+0:?     '@patchConstantOutput.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?     '@patchConstantOutput.inside' ( patch out 2-element array of float TessLevelInner)
+
+
+Linked tessellation control stage:
+
+
+Shader version: 500
+vertices = 3
+vertex spacing = equal_spacing
+triangle order = cw
+0:? Sequence
+0:37  Function Definition: ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1; ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:37    Function Parameters: 
+0:37      'inputPatch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:37      'patchId' ( in uint)
+0:?     Sequence
+0:42      move second child to first child ( temp float)
+0:42        direct index ( temp float)
+0:42          edges: direct index for structure ( temp 3-element array of float)
+0:42            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:42            Constant:
+0:42              0 (const int)
+0:42          Constant:
+0:42            0 (const int)
+0:42        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:42          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:42          Constant:
+0:42            0 (const uint)
+0:43      move second child to first child ( temp float)
+0:43        direct index ( temp float)
+0:43          edges: direct index for structure ( temp 3-element array of float)
+0:43            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:43            Constant:
+0:43              0 (const int)
+0:43          Constant:
+0:43            1 (const int)
+0:43        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:43          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:43          Constant:
+0:43            0 (const uint)
+0:44      move second child to first child ( temp float)
+0:44        direct index ( temp float)
+0:44          edges: direct index for structure ( temp 3-element array of float)
+0:44            'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:44            Constant:
+0:44              0 (const int)
+0:44          Constant:
+0:44            2 (const int)
+0:44        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:44          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:44          Constant:
+0:44            0 (const uint)
+0:47      move second child to first child ( temp float)
+0:47        inside: direct index for structure ( temp float)
+0:47          'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:47          Constant:
+0:47            1 (const int)
+0:47        tessellationAmount: direct index for structure (layout( row_major std140) uniform float)
+0:47          'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:47          Constant:
+0:47            0 (const uint)
+0:49      Branch: Return with expression
+0:49        'output' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:63  Function Definition: @main(struct-HullInputType-vf3-vf41[3];u1;u1; ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63    Function Parameters: 
+0:63      'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63      'pointId' ( in uint)
+0:63      'patchId' ( in uint)
+0:?     Sequence
+0:67      move second child to first child ( temp 3-component vector of float)
+0:67        position: direct index for structure ( temp 3-component vector of float)
+0:67          'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67          Constant:
+0:67            0 (const int)
+0:67        position: direct index for structure ( temp 3-component vector of float)
+0:67          indirect index ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67            'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:67            'pointId' ( in uint)
+0:67          Constant:
+0:67            0 (const int)
+0:70      move second child to first child ( temp 4-component vector of float)
+0:70        color: direct index for structure ( temp 4-component vector of float)
+0:70          'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70          Constant:
+0:70            1 (const int)
+0:70        color: direct index for structure ( temp 4-component vector of float)
+0:70          indirect index ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70            'patch' ( in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:70            'pointId' ( in uint)
+0:70          Constant:
+0:70            1 (const int)
+0:72      Branch: Return with expression
+0:72        'output' ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63  Function Definition: main( ( temp void)
+0:63    Function Parameters: 
+0:?     Sequence
+0:63      move second child to first child ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?         'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?         'patch' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63      move second child to first child ( temp uint)
+0:?         'pointId' ( temp uint)
+0:?         'pointId' ( in uint InvocationID)
+0:63      move second child to first child ( temp uint)
+0:?         'patchId' ( temp uint)
+0:?         'patchId' ( in uint PrimitiveID)
+0:63      move second child to first child ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:63        indirect index (layout( location=0) out structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'pointId' ( in uint InvocationID)
+0:63        Function Call: @main(struct-HullInputType-vf3-vf41[3];u1;u1; ( temp structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?           'pointId' ( temp uint)
+0:?           'patchId' ( temp uint)
+0:?       Barrier ( temp void)
+0:?       Test condition and select ( temp void)
+0:?         Condition
+0:?         Compare Equal ( temp bool)
+0:?           'pointId' ( 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-element array of float edges,  temp float inside})
+0:?             '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?             Function Call: ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1; ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?               'patch' ( temp 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?               'patchId' ( in uint PrimitiveID)
+0:?           Sequence
+0:?             move second child to first child ( temp float)
+0:?               direct index ( patch out float TessLevelOuter)
+0:?                 '@patchConstantOutput.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   0 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   1 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?                 Constant:
+0:?                   2 (const int)
+0:?               direct index ( temp float)
+0:?                 edges: direct index for structure ( temp 3-element array of float)
+0:?                   '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+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.inside' ( patch out 2-element array of float TessLevelInner)
+0:?                 Constant:
+0:?                   0 (const int)
+0:?               inside: direct index for structure ( temp float)
+0:?                 '@patchConstantResult' ( temp structure{ temp 3-element array of float edges,  temp float inside})
+0:?                 Constant:
+0:?                   1 (const int)
+0:?   Linker Objects
+0:?     'anon@0' (layout( binding=0 row_major std140) uniform block{layout( row_major std140) uniform float tessellationAmount, layout( row_major std140) uniform 3-component vector of float padding})
+0:?     '@entryPointOutput' (layout( location=0) out 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?     'patch' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float position,  temp 4-component vector of float color})
+0:?     'pointId' ( in uint InvocationID)
+0:?     'patchId' ( in uint PrimitiveID)
+0:?     '@patchConstantOutput.edges' ( patch out 4-element array of float TessLevelOuter)
+0:?     '@patchConstantOutput.inside' ( patch out 2-element array of float TessLevelInner)
+
+// Module Version 10000
+// Generated by (magic number): 80002
+// Id's are bound by 128
+
+                              Capability Tessellation
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint TessellationControl 4  "main" 72 76 79 83 111 124
+                              ExecutionMode 4 OutputVertices 3
+                              ExecutionMode 4 Triangles
+                              ExecutionMode 4 SpacingEqual
+                              ExecutionMode 4 VertexOrderCw
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 9  "HullInputType"
+                              MemberName 9(HullInputType) 0  "position"
+                              MemberName 9(HullInputType) 1  "color"
+                              Name 16  "ConstantOutputType"
+                              MemberName 16(ConstantOutputType) 0  "edges"
+                              MemberName 16(ConstantOutputType) 1  "inside"
+                              Name 20  "ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1;"
+                              Name 18  "inputPatch"
+                              Name 19  "patchId"
+                              Name 22  "HullOutputType"
+                              MemberName 22(HullOutputType) 0  "position"
+                              MemberName 22(HullOutputType) 1  "color"
+                              Name 27  "@main(struct-HullInputType-vf3-vf41[3];u1;u1;"
+                              Name 24  "patch"
+                              Name 25  "pointId"
+                              Name 26  "patchId"
+                              Name 30  "output"
+                              Name 33  "TessellationBuffer"
+                              MemberName 33(TessellationBuffer) 0  "tessellationAmount"
+                              MemberName 33(TessellationBuffer) 1  "padding"
+                              Name 35  ""
+                              Name 56  "output"
+                              Name 70  "patch"
+                              Name 72  "patch"
+                              Name 74  "pointId"
+                              Name 76  "pointId"
+                              Name 78  "patchId"
+                              Name 79  "patchId"
+                              Name 83  "@entryPointOutput"
+                              Name 85  "param"
+                              Name 87  "param"
+                              Name 89  "param"
+                              Name 102  "@patchConstantResult"
+                              Name 103  "param"
+                              Name 105  "param"
+                              Name 111  "@patchConstantOutput.edges"
+                              Name 124  "@patchConstantOutput.inside"
+                              MemberDecorate 33(TessellationBuffer) 0 Offset 0
+                              MemberDecorate 33(TessellationBuffer) 1 Offset 4
+                              Decorate 33(TessellationBuffer) Block
+                              Decorate 35 DescriptorSet 0
+                              Decorate 35 Binding 0
+                              Decorate 72(patch) Location 0
+                              Decorate 76(pointId) BuiltIn InvocationId
+                              Decorate 79(patchId) BuiltIn PrimitiveId
+                              Decorate 83(@entryPointOutput) Location 0
+                              Decorate 111(@patchConstantOutput.edges) Patch
+                              Decorate 111(@patchConstantOutput.edges) BuiltIn TessLevelOuter
+                              Decorate 124(@patchConstantOutput.inside) Patch
+                              Decorate 124(@patchConstantOutput.inside) BuiltIn TessLevelInner
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 3
+               8:             TypeVector 6(float) 4
+9(HullInputType):             TypeStruct 7(fvec3) 8(fvec4)
+              10:             TypeInt 32 0
+              11:     10(int) Constant 3
+              12:             TypeArray 9(HullInputType) 11
+              13:             TypePointer Function 12
+              14:             TypePointer Function 10(int)
+              15:             TypeArray 6(float) 11
+16(ConstantOutputType):             TypeStruct 15 6(float)
+              17:             TypeFunction 16(ConstantOutputType) 13(ptr) 14(ptr)
+22(HullOutputType):             TypeStruct 7(fvec3) 8(fvec4)
+              23:             TypeFunction 22(HullOutputType) 13(ptr) 14(ptr) 14(ptr)
+              29:             TypePointer Function 16(ConstantOutputType)
+              31:             TypeInt 32 1
+              32:     31(int) Constant 0
+33(TessellationBuffer):             TypeStruct 6(float) 7(fvec3)
+              34:             TypePointer Uniform 33(TessellationBuffer)
+              35:     34(ptr) Variable Uniform
+              36:             TypePointer Uniform 6(float)
+              39:             TypePointer Function 6(float)
+              41:     31(int) Constant 1
+              45:     31(int) Constant 2
+              55:             TypePointer Function 22(HullOutputType)
+              58:             TypePointer Function 7(fvec3)
+              63:             TypePointer Function 8(fvec4)
+              71:             TypePointer Input 12
+       72(patch):     71(ptr) Variable Input
+              75:             TypePointer Input 10(int)
+     76(pointId):     75(ptr) Variable Input
+     79(patchId):     75(ptr) Variable Input
+              81:             TypeArray 22(HullOutputType) 11
+              82:             TypePointer Output 81
+83(@entryPointOutput):     82(ptr) Variable Output
+              92:             TypePointer Output 22(HullOutputType)
+              94:     10(int) Constant 2
+              95:     10(int) Constant 1
+              96:     10(int) Constant 0
+              98:             TypeBool
+             108:     10(int) Constant 4
+             109:             TypeArray 6(float) 108
+             110:             TypePointer Output 109
+111(@patchConstantOutput.edges):    110(ptr) Variable Output
+             114:             TypePointer Output 6(float)
+             122:             TypeArray 6(float) 94
+             123:             TypePointer Output 122
+124(@patchConstantOutput.inside):    123(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+       70(patch):     13(ptr) Variable Function
+     74(pointId):     14(ptr) Variable Function
+     78(patchId):     14(ptr) Variable Function
+       85(param):     13(ptr) Variable Function
+       87(param):     14(ptr) Variable Function
+       89(param):     14(ptr) Variable Function
+102(@patchConstantResult):     29(ptr) Variable Function
+      103(param):     13(ptr) Variable Function
+      105(param):     14(ptr) Variable Function
+              73:          12 Load 72(patch)
+                              Store 70(patch) 73
+              77:     10(int) Load 76(pointId)
+                              Store 74(pointId) 77
+              80:     10(int) Load 79(patchId)
+                              Store 78(patchId) 80
+              84:     10(int) Load 76(pointId)
+              86:          12 Load 70(patch)
+                              Store 85(param) 86
+              88:     10(int) Load 74(pointId)
+                              Store 87(param) 88
+              90:     10(int) Load 78(patchId)
+                              Store 89(param) 90
+              91:22(HullOutputType) FunctionCall 27(@main(struct-HullInputType-vf3-vf41[3];u1;u1;) 85(param) 87(param) 89(param)
+              93:     92(ptr) AccessChain 83(@entryPointOutput) 84
+                              Store 93 91
+                              ControlBarrier 94 95 96
+              97:     10(int) Load 76(pointId)
+              99:    98(bool) IEqual 97 32
+                              SelectionMerge 101 None
+                              BranchConditional 99 100 101
+             100:               Label
+             104:          12   Load 70(patch)
+                                Store 103(param) 104
+             106:     10(int)   Load 79(patchId)
+                                Store 105(param) 106
+             107:16(ConstantOutputType)   FunctionCall 20(ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1;) 103(param) 105(param)
+                                Store 102(@patchConstantResult) 107
+             112:     39(ptr)   AccessChain 102(@patchConstantResult) 32 32
+             113:    6(float)   Load 112
+             115:    114(ptr)   AccessChain 111(@patchConstantOutput.edges) 32
+                                Store 115 113
+             116:     39(ptr)   AccessChain 102(@patchConstantResult) 32 41
+             117:    6(float)   Load 116
+             118:    114(ptr)   AccessChain 111(@patchConstantOutput.edges) 41
+                                Store 118 117
+             119:     39(ptr)   AccessChain 102(@patchConstantResult) 32 45
+             120:    6(float)   Load 119
+             121:    114(ptr)   AccessChain 111(@patchConstantOutput.edges) 45
+                                Store 121 120
+             125:     39(ptr)   AccessChain 102(@patchConstantResult) 41
+             126:    6(float)   Load 125
+             127:    114(ptr)   AccessChain 124(@patchConstantOutput.inside) 32
+                                Store 127 126
+                                Branch 101
+             101:             Label
+                              Return
+                              FunctionEnd
+20(ColorPatchConstantFunction(struct-HullInputType-vf3-vf41[3];u1;):16(ConstantOutputType) Function None 17
+  18(inputPatch):     13(ptr) FunctionParameter
+     19(patchId):     14(ptr) FunctionParameter
+              21:             Label
+      30(output):     29(ptr) Variable Function
+              37:     36(ptr) AccessChain 35 32
+              38:    6(float) Load 37
+              40:     39(ptr) AccessChain 30(output) 32 32
+                              Store 40 38
+              42:     36(ptr) AccessChain 35 32
+              43:    6(float) Load 42
+              44:     39(ptr) AccessChain 30(output) 32 41
+                              Store 44 43
+              46:     36(ptr) AccessChain 35 32
+              47:    6(float) Load 46
+              48:     39(ptr) AccessChain 30(output) 32 45
+                              Store 48 47
+              49:     36(ptr) AccessChain 35 32
+              50:    6(float) Load 49
+              51:     39(ptr) AccessChain 30(output) 41
+                              Store 51 50
+              52:16(ConstantOutputType) Load 30(output)
+                              ReturnValue 52
+                              FunctionEnd
+27(@main(struct-HullInputType-vf3-vf41[3];u1;u1;):22(HullOutputType) Function None 23
+       24(patch):     13(ptr) FunctionParameter
+     25(pointId):     14(ptr) FunctionParameter
+     26(patchId):     14(ptr) FunctionParameter
+              28:             Label
+      56(output):     55(ptr) Variable Function
+              57:     10(int) Load 25(pointId)
+              59:     58(ptr) AccessChain 24(patch) 57 32
+              60:    7(fvec3) Load 59
+              61:     58(ptr) AccessChain 56(output) 32
+                              Store 61 60
+              62:     10(int) Load 25(pointId)
+              64:     63(ptr) AccessChain 24(patch) 62 41
+              65:    8(fvec4) Load 64
+              66:     63(ptr) AccessChain 56(output) 41
+                              Store 66 65
+              67:22(HullOutputType) Load 56(output)
+                              ReturnValue 67
+                              FunctionEnd
diff --git a/Test/hlsl.color.hull.tesc b/Test/hlsl.color.hull.tesc
new file mode 100644
index 000000000..73d9ad034
--- /dev/null
+++ b/Test/hlsl.color.hull.tesc
@@ -0,0 +1,74 @@
+/////////////
+// GLOBALS //
+/////////////
+cbuffer TessellationBuffer : register(b0)
+{
+    float tessellationAmount;
+    float3 padding;
+};
+
+
+//////////////
+// TYPEDEFS //
+//////////////
+struct HullInputType
+{
+    float3 position : POSITION;
+    float4 color : COLOR;
+};
+
+struct ConstantOutputType
+{
+    float edges[3] : SV_TessFactor;
+    float inside : SV_InsideTessFactor;
+};
+
+struct HullOutputType
+{
+    float3 position : POSITION;
+    float4 color : COLOR;
+};
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Patch Constant Function
+////////////////////////////////////////////////////////////////////////////////
+ConstantOutputType ColorPatchConstantFunction(InputPatch<HullInputType, 3> inputPatch, uint patchId : SV_PrimitiveID)
+{
+    ConstantOutputType output;
+
+
+	// Set the tessellation factors for the three edges of the triangle.
+    output.edges[0] = tessellationAmount;
+    output.edges[1] = tessellationAmount;
+    output.edges[2] = tessellationAmount;
+
+	// Set the tessellation factor for tessallating inside the triangle.
+    output.inside = tessellationAmount;
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Hull Shader
+////////////////////////////////////////////////////////////////////////////////
+[domain("tri")]
+[partitioning("integer")]
+[outputtopology("triangle_cw")]
+[outputcontrolpoints(3)]
+[patchconstantfunc("ColorPatchConstantFunction")]
+
+HullOutputType main(InputPatch<HullInputType, 3> patch, uint pointId : SV_OutputControlPointID, uint patchId : SV_PrimitiveID)
+{
+    HullOutputType output;
+
+    // Set the position for this control point as the output position.
+    output.position = patch[pointId].position;
+
+	// Set the input color as the output color.
+    output.color = patch[pointId].color;
+
+    return output;
+}
+
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 1e936dada..20fc69058 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -133,6 +133,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.clipdistance-8.vert", "main"},
         {"hlsl.clipdistance-9.frag", "main"},
         {"hlsl.clipdistance-9.vert", "main"},
+        {"hlsl.color.hull.tesc", "main"},
         {"hlsl.comparison.vec.frag", "main"},
         {"hlsl.conditional.frag", "PixelShaderFunction"},
         {"hlsl.constantbuffer.frag", "main"},
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 7192747c4..5187c0f2e 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -9000,7 +9000,7 @@ bool HlslParseContext::isInputBuiltIn(const TQualifier& qualifier) const
     case EbvVertexIndex:
         return language == EShLangVertex;
     case EbvPrimitiveId:
-        return language == EShLangGeometry || language == EShLangFragment;
+        return language == EShLangGeometry || language == EShLangFragment || language == EShLangTessControl;
     case EbvTessLevelInner:
     case EbvTessLevelOuter:
         return language == EShLangTessEvaluation;
-- 
GitLab