Take a look at the main() function of the TCS shown below from this tutorial. I included the entire shader just for completeness.
#version 410 core
// define the number of CPs in the output patch
layout (vertices = 3) out;
uniform vec3 gEyeWorldPos;
// attributes of the input CPs
in vec3 WorldPos_CS_in[];
in vec2 TexCoord_CS_in[];
in vec3 Normal_CS_in[];
// attributes of the output CPs
out vec3 WorldPos_ES_in[];
out vec2 TexCoord_ES_in[];
out vec3 Normal_ES_in[];
void main()
{
// Set the control points of the output patch
TexCoord_ES_in[gl_InvocationID] = TexCoord_CS_in[gl_InvocationID];
Normal_ES_in[gl_InvocationID] = Normal_CS_in[gl_InvocationID];
WorldPos_ES_in[gl_InvocationID] = WorldPos_CS_in[gl_InvocationID];
// Calculate the distance from the camera to the three control points
float EyeToVertexDistance0 = distance(gEyeWorldPos, WorldPos_ES_in[0]);
float EyeToVertexDistance1 = distance(gEyeWorldPos, WorldPos_ES_in[1]);
float EyeToVertexDistance2 = distance(gEyeWorldPos, WorldPos_ES_in[2]);
// Calculate the tessellation levels
gl_TessLevelOuter[0] = GetTessLevel(EyeToVertexDistance1, EyeToVertexDistance2);
gl_TessLevelOuter[1] = GetTessLevel(EyeToVertexDistance2, EyeToVertexDistance0);
gl_TessLevelOuter[2] = GetTessLevel(EyeToVertexDistance0, EyeToVertexDistance1);
gl_TessLevelInner[0] = gl_TessLevelOuter[2];
}
Note I removed the intermediate commentary from the code blocks in the tutorial so its possible that some intermediate portions were left out.
My source of confusion is the first 3 lines of code make sense for a 'per-control-point' operation (it uses the gl_InvocationID), but the remaining code seems to be a 'per-patch' operation (it uses all three indices: 0,1,2). The tessellation levels (to my knowledge) correspond to the entire patch. So what I think is happening here, is that the tessellation levels will be improperly calculated twice, and then on the 3rd invocation, (after all the WorldPos_ES_in values are initialized) the correct result will be obtained.
I don't see anything technically incorrect with any of this, but this mixing of per-patch, and per-control-point operations, blurs my understanding of the Tesselation Control Shader as a 'per-control-point' action.