When setting a specific component of an array using gl_InvocationID, I get undefined results from patch varyings set in my tessellation control shaders with vectors while arrays work fine. I don’t see why vectors should give an undefined result.
Here’s some code illustrating the problem (using triangular patches):
// tessellation control shader
#version 410
layout(location = 0) patch out vec3 oData1;
layout(location = 1) patch out float oData2[3];
[...]
void main()
{
oData1[gl_InvocationID] = someScalarValue(gl_InvocationID); // undefined in my tessellation evaluation shader
oData2[gl_InvocationID] = someScalarValue(gl_InvocationID); // works fine in my tessellation evaluation shader
}
Either I missed something in the specs, either it’s a driver bug, I’m on Catalyst 11.9.
Tessellation shader invocations were designed to be run in parallel. AMD hardware is vector-based, so I’d guess that what is actually happening in each invocation is:
load vec3 data
insert scalar->vec3
store vec3 data
Because of the fact that the entire vector is being stored, parallel invocations are stomping on the same data location, producing unpredictable results. The float[3] array is very likely being stored in separate 128b-padded addresses, so no data-stomping occurs.
This is in theory, anyway – I don’t exactly know what’s going on behind the scenes.