1

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?

Community
  • 1
  • 1
qxz
  • 3,814
  • 1
  • 14
  • 29
  • If you are using newer versions of GLSL, you should switch to `in/out` as varyings are deprecated. – SurvivalMachine Aug 17 '16 at 07:03
  • Do you think compatibility with old machines/drivers would be a problem? – qxz Aug 17 '16 at 07:04
  • I think `in/out` was introduced in GLSL version 130 in the year 2008 which is quite old so I don't think compatibility will be a problem. – SurvivalMachine Aug 17 '16 at 07:12
  • It is probably worth mentioning that varyings that do not contribute to an active codepath that produces final output may be stripped and do not contribute to this limit... making counting even more ridiculous ;) If the compiler can determine statically that an array index is not accessed, it may skimp out on storage for it. I have seen this with uniform arrays; causing code that would otherwise exceed a certain limit to compile and link. I have never tried anything like this with varyings to be honest. – Andon M. Coleman Aug 17 '16 at 16:22

1 Answers1

2

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Ok, that makes sense. For me, `GL_MAX_VERTEX_OUTPUT_COMPONENTS` is 128, but I can only use 62 `vec2`s... Is this because `gl_Position` takes up a `vec4`? – qxz Aug 17 '16 at 20:08
  • @qxz: Nothing in the spec suggests that `gl_Position` is exempt from the count. After all, you don't *have* to write to it. – Nicol Bolas Aug 17 '16 at 20:13
  • @qxz: Program introspection can probably shed some light on what's going on. It's not the easiest part of the OpenGL API to work with, but will give you a lot more insight. – Andon M. Coleman Aug 19 '16 at 00:57
  • @AndonM.Coleman: Actually, with [the introspection modern API](https://www.opengl.org/wiki/Program_Introspection#Interface_query), it's quite easy to work with. And I just checked; active built-in variables are part of the interface query. So if you write to `gl_Position`, it should be listed. – Nicol Bolas Aug 19 '16 at 01:05
  • Not using the C language bindings. There's a ton of setup of property lists and such that require temporary variables, it's quite unlike most parts of the OpenGL API. – Andon M. Coleman Aug 19 '16 at 03:29