- use shader blocks, where the order of the elements in the block determines how the GLSL compiler packs it, i.e. analogous to declaring a structure in C.
Forcing a specific order on the user doesn’t make the implementation faster. For any list of strings (ie: names of the in/outs), you can just use the standard less-than ordering to sort them. If two sets of strings are identical (and thus can link together), they will have the same order.
Doing this makes the whole test boil down to a single, long string equality test. You can even encode the type with an 8-bit integer that’s just another character to test equals with.
Look at the implementation. If programs on average have 6 in/out pairs, and each name is 8 characters long on average, and you can fit all of the types in one byte, then each name+type is 9 characters. The total list is 54 characters. Since all you want is an equals/unequal test, you don’t have to go character-by-character; simply compare whole 32 or 64-bit integers at a time. That makes 7 comparisons to test if these are equal; 8 if you count adding the size of the respective strings to the beginning.
The real performance issue and potential killer is part of the reasoning behind bindless graphics: cache thrashing. Accessing both objects, and reading the values is almost certainly going to cause a lot of uncached read operations.
Of course any kind of linkage checking will require that. Just not quite as much as 54+ bytes worth for each shader stage.
Rendezvous by name, but non within a dedicated type, has to me, a dangling feeling, also depending on the how severely the shaders are intermixed naming conventions are not a good thing, for example if you want to insert a geometry shader between a vertex and fragment shader, having just in/out is going to kill you, but having like this:
Rendezvous by name does not prevent one from defining a particular interface “struct”. All it does is give the user the freedom to not have to. EXT_separate_shader_objects is not about compiling programs with a single shader and a single string. You can still use the separate functionality when compiling programs with multiple shaders, or compiling shaders from multiple strings.
It just seems silly to have to change how you write shaders just because you want to use them differently.
- another method the nVidia fellow suggested, ala Cg:
out type someinterpolator:ATTR0;
Right now, you have to set attributes indices to inputs and draw buffer indices to outputs manually, in C++ code. If this were used as a generic solution to that problem, I’d be willing to accept having to enumerate all inputs/outputs manually. And thus rendezvous by resource.
I don’t like it; I would rather that strings were used instead of attribute and draw buffer indices. But I’m willing to go halfway on it.
However, they should specifically be numbers, not strings like “ATTR0”. So it would look like:
in vec3 position : 0;
out vec4 color : 2;
This might pose a problem for compatibility contexts. I’d be willing to accept that such contexts could define specific strings for their fixed-function attributes. Such as:
in vec3 position : vertex
I’m not fond of it, but I don’t use the fixed attributes anymore either, so I don’t have to use it
I tend to think that nVidia really, really likes GL and if you look at the credits for the specification, you can clearly see that nVidia has a big hand in making them.
Of course they like OpenGL. But they often treat it as their own personal playground for high-performance NVIDIA-only stuff. Vertex array range comes to mind, as does bindless graphics. OpenGL’s greatest strength is being cross-platform.