qxz
qxz

Reputation: 3854

How are GLSL varyings packed, and how many vec2's can I have?

I know that I can glGet with GL_MAX_VARYING_VECTORS to get the number of 4-component vectors I can use as varyings. What about other size vectors, matrices, and arrays of said types? How closely can these be packed; what are the restrictions?

I came across this question with a good answer. However, I am interested in desktop OpenGL, not OpenGL ES. Is there a difference in this case? I briefly searched this spec but found nothing useful.

Besides a general interest in how varyings are packed, I have a shader program whose sole varying is an array of vec2s. I want to programmatically get the largest size that this array can be. How can I derive that from GL_MAX_VARYING_VECTORS?

On my computer, GL_MAX_VARYING_VECTORS is 16, and I can size the array up to 62 before it won't compile.

Additionally, should I even be using varyings? I'm aware that newer versions of GLSL use an in/out syntax; should I switch, and do you know of any resources to get me started?

Upvotes: 1

Views: 951

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473407

For all versions of Desktop OpenGL (where it matters), the limitations on the interface between shader stages are defined by the number of "components", not the number of "vectors". GL_MAX_VERTEX_OUTPUT_COMPONENTS, for example, defines the maximum number of output components the VS can generate.

A "component" is a float, integer, or boolean value. A vec3 takes up 3 components. A vec2[4] takes up 8 components.

So:

I want to programmatically get the largest size that this array can be. How can I derive that from GL_MAX_VARYING_VECTORS?

You don't. You derive it from the actual component count. In modern desktop GL 3.2+, this is defined by a per-stage value. For vertex shaders, this is GL_MAX_VERTEX_OUTPUT_COMPONENTS. For geometry shaders, this is GL_MAX_GEOMETRY_OUTPUT_COMPONENTS.

If the number of components is 64 (the minimum value that GL 4.x implementations will return), then you can have 32 vec2s.

According to the standard, at least. In practice, implementations have a tendency to vary with how these things work. Particularly in the early days, you were pretty much guaranteed that implementations would take each individual element of an array and expand it into a vec4.

Do they do that now? Well, either they do or they don't. If you manually pack your array of vec2s into an array of vec4s, then you're far more likely to work across platforms. So if you're not willing/able to test on numerous implementations, that's what I would do.

And yes, if you're using modern OpenGL implementations, you should be using in/out syntax. But that won't change anything in this regard; it's just syntax.

Upvotes: 2

Related Questions