Official feedback on OpenGL 4.3 thread

You can jump to a different model/frame/LOD with a single BindVertexBuffer call, rather than having to specify individual VAOs for each model/frame/LOD, or respecify the full set of VertexAttribPointer calls for each model/frame/LOD (worth noting that stride is not really a big deal here and is unlikely to change in real-world programs; offset is the important one).

Welcome to my entire point: if the stride isn’t going to change in any real-world system, why is the stride not part of the vertex format?

There’s a reason I gave it the “one little mistake” award: the only thing wrong with the functionality is that the stride is in the wrong place for no real reason. Or at least, the only reason is because “Direct3D does it that way.” It doesn’t actually make sense; that’s just how they do it.

the only seeming bad part being (and I haven’t fully reviewed the spec so I may have missed something) that BufferData/BufferSubData/MapBuffer/MapBufferRange haven’t been updated to take advantage of the new binding points.

There aren’t new binding points. glBindVertexBuffer does not bind the buffer to a binding target the way that glBindBufferRange does. That’s why it doesn’t take a “target” enum. It only binds it to an indexed vertex buffer binding point; it doesn’t bind the buffer to a modifiable target.

This was almost certainly done to allow glVertexAttribPointer to be defined entirely in terms of the new API. glVertexAttribPointer doesn’t change GL_ARRAY_BUFFER’s binding, nor does it change any other previously-visible buffer binding state. Therefore, glBindVertexBuffer doesn’t either.

Personally, I don’t have a problem with the minor API inconsistency.

On the other hand, what harm does it do? I personally can’t see any reason to change stride either, but the functionality is now there and maybe someone will find a use for it? I don’t see it as being a “wrong thing”, more of an odd but ultimately inconsequential decision. Doing what D3D does can make sense in many cases - makes it easier to port from D3D to GL, after all. That’s gotta be a good thing. But in this case the D3D behaviour is also odd but ultimately inconsequential. It could be worse - just be thankful that it didn’t take an array of each of buffers/strides/offsets like D3D does - that’s painful to use.

There aren’t new binding points.

Just using the terminology from http://us.download.nvidia.com/opengl/specs/GL_ARB_vertex_attrib_binding.txt

I don’t see it as being a “wrong thing”, more of an odd but ultimately inconsequential decision.

But it’s not inconsequential. It’s taking something that is by all rights part of the format and putting it elsewhere. It’s not broken as specified, but it’s not what it should be.

It’s like not being able to specify attribute indices in shaders and many other API issues with OpenGL, past and present. Yes, you can live without it, but it would clearly be better to have it done right.

Hypothetical reason why you may wish to change the stride - skipping over vertexes for an LOD scheme.

To be honest I think you’re wasting too much negative energy on this. Not having attribute indices in shaders was a colossal pain in the rear-end; this is nowhere even near the same magnitude. If it’s a genuine API issue that is going to cause torment to those using it, then by all means yell about it from the rooftops (I’ll be right there beside you). This isn’t.

I don’t understand what’s the use case here. How stride helps you “skipping over vertices for a LOD scheme”? Also, skipping over vertices should be done by giving a different base index to DrawElements calls as you probably use indices anyways and if you use LOD I barely believe that you want to use the same set of indices. Why would you? That would mean that all of your LOD levels render the same amount of vertices which defeats the purpose.
Also, if you don’t want to use indices, you probably better off sending a different first vertex parameter to your DrawArrays calls instead of always changing the offset and/or stride of your vertex buffers.

from spec 2.5.10

Vertex array objects are container objects including references to buffer objects, and are not shared

Even with vertex formats removing buffer object references, I still need to carry vertex format info from my loading thread to main thread in order to finalize my OpenGL objects.

so this just makes me sad…

[QUOTE=Alfonse Reinheart;1241156]But it’s not inconsequential. It’s taking something that is by all rights part of the format and putting it elsewhere. It’s not broken as specified, but it’s not what it should be.

It’s like not being able to specify attribute indices in shaders and many other API issues with OpenGL, past and present. Yes, you can live without it, but it would clearly be better to have it done right.[/QUOTE]
Agree, not to mention that the per-attribute relativeoffset parameter is still specified for the vertex attributes themselves and, in practice, these relative offsets don’t make any sense unless you are also aware of the stride, thus again, it defeats the purpose.

I think the use pattern intended was that format of the attribute data was unchanged but weather or not and how it was interleaved with other attribute data varied… the current interface does effectively have an offset in both glBindVertexBuffer and glVertexAttrib*Format … so the issue is which use case comes up more often:
[ul]
[li]Keeping the format the same, but varying buffer sources and interleaving[/li][/ul]
OR
[ul]
[li]Using the same buffer, but varying interleave and format[/li][/ul]

What is in the spec makes the first case possible with only setting the buffer sources where as what some are wanting is to do the 2nd more often.

It look to me like that the interface is made for when a GL implementation works likes this:

[ul]
[li]Attribute puller has only two things: location from which to grab data and stride on what to grab[/li][li]Attribute interpreter converts raw bytes from the puller for the vertex shader to consume[/li][/ul]

If a GL implementation worked like that, then I can see how a GL implementer would strongly prefer how the interface came out. Though an offset within the formatting setter kind of invalidates the above idea without more hackery…

In recent (but not sure latest hardware), there are no such things as ‘Vertex Puller’, feeding vertex data into a shader consists of two step, a DMA unit that moves blocks of vertex data into registers or memory closer to the shader and then the attrib converter/loader that feed the actual shader. The DMA unit doesn’t really care whats in the vertex itself, only the address and total size of each vertex. Hopefully you can see where the interface in D3D and GL4.3 comes from. You’re effectively programming the two processes separately.
On at least one platform when programming at a lower level API, it was possible to leave some vertex DMA streams on even if the data wasn’t used, this could be a serious performance loss. The DMA unit would pay the bandwidth cost of retrieving data but then nothing would actually need or use it.
It was a simple pipeline optimisations, because vertex/index is highly predictable (its predefined) you can use simple DMA to ensure the data is in the best place beforehand.

However I don’t believe the latest hardware uses this optimisation (I suspect they use the general cache and thread switches to achieve a similar effect), so its usefulness going forward may be doubtful…

[QUOTE=aqnuep;1241168]I don’t understand what’s the use case here. How stride helps you “skipping over vertices for a LOD scheme”? Also, skipping over vertices should be done by giving a different base index to DrawElements calls as you probably use indices anyways and if you use LOD I barely believe that you want to use the same set of indices. Why would you? That would mean that all of your LOD levels render the same amount of vertices which defeats the purpose.
Also, if you don’t want to use indices, you probably better off sending a different first vertex parameter to your DrawArrays calls instead of always changing the offset and/or stride of your vertex buffers.[/QUOTE]

This assumes that all of your VBO streams are going to be using the same stride or offset, which is not always the case. You may have a different VBO for texcoords as you have for position and normals, and you may only need to change the stride or offset for the position/normals VBO. The old API wouldn’t let you do that without respecifying the full set of vertex attrib pointers; the new one lets you do it with a single BindVertexBuffer which - because stride and offset are separate state - can be much more efficient.

I really get the feeling that this is very new territory for many of you. Because you’ve never had this capability you don’t see the advantages and flexibility of it, and need to have explained in detail what others have been successfully using for well over a decade now. There’s an element of “the Americans have need of the telephone, but we do not. We have plenty of messenger boys” in that, and that’s why I mentioned actually sitting down and writing some code that used it earlier on.

The sentiment that “just because it’s D3D functionality it doesn’t mean that GL has to do it” has a counterpart - just because it’s D3D functionality it doesn’t mean that GL doesn’t have to do it either - because GL is not D3D and can evolve whatever functionality is deemed appropriate; whether or not it’s similar is not relevant. Exhibiting opposition to functionality just because it works in a similar manner to D3D is quite preposterous, to be honest.

Even though it might not make much sense to you from a theoretical standpoint, the reason the spec’s been written like that is that it maps perfectly on the current hardware. There’s no other reason. The stride is just part of the vertex buffer binding.

Would like to see more removal of deprecated functions and stuff. Cleaning.
We have Core and compatibility profile now. There is no reason to not remove/deprecate/clean old cruft form the core profile.

For people who find that it is more trouble than it’s worth:
If it is too much work to replace obsolete functions and rebuild obsolete parts of algorithms. Then why the need to adapt the current program to a new OpenGL version? New features can also force rethinking of architecture.

I was a bit disappointed when I saw the OpenGL ES spec had a section of legacy features.
Because OpenGL ES 2.0 did not have backwards compatibility. Breaking it again would not have surprised many and would be expected.
Please do not do backwards compatibility again with OpenGL ES. Doing this is simply not necessary and allows for a lean specification without a lot of old cruft that makes it more work to build conforming drivers.

That’s a good point, I can accept that one. Though still not as flexible as programmable vertex fetching.

Maps perfectly to what hardware? May fit one, may not fit another. Lots of extensions map well to some hardware but may be pretty inefficient on other. OpenGL tries to match what hardware does as best as possible, however, as usual, there is no one-fits-all design so just assuming that whatever OpenGL supports maps perfectly to any hardware supporting it is just too naive.

Probably to Khronos’ members hardware, otherwise i guess that the feature would be vetoed from core spec.

Of course it doesn’t map to all hardware in existence, but it maps exactly to AMD and NVIDIA hardware since GL3-capable chipsets. I don’t really care about the rest.

There’s also the case that it will make it easier to extend the vertex buffer API going forward (based on the assumption that it maps to, and continues to map to, hardware, of course) - which would result in cleaner, more robust drivers with fewer shenanigans going on behind the scenes. Plus it’s setting clear precedent for something like a hypothetical GL_ARB_multi_index_buffers in a hypothetical future version (a similar API could be used) - and that’s something I don’t think even Alfonse could nitpick over. :wink:

This assumes that all of your VBO streams are going to be using the same stride or offset, which is not always the case. You may have a different VBO for texcoords as you have for position and normals, and you may only need to change the stride or offset for the position/normals VBO. The old API wouldn’t let you do that without respecifying the full set of vertex attrib pointers; the new one lets you do it with a single BindVertexBuffer which - because stride and offset are separate state - can be much more efficient.

That doesn’t explain what this has to do with LODs.

Furthermore, glDrawElementsBaseVertex already dealt with the “offset” issue quite well; you can just render with different indices, using a base index added to the indices you fetch. No need to make glVertexAttribPointer calls again.

[QUOTE=Alfonse Reinheart;1241214]That doesn’t explain what this has to do with LODs.

Furthermore, glDrawElementsBaseVertex already dealt with the “offset” issue quite well; you can just render with different indices, using a base index added to the indices you fetch. No need to make glVertexAttribPointer calls again.[/QUOTE]

Mental note to self: don’t pull random examples out of ass when the Spanish Inquisition are around. :wink:

See my comment on the previous page for one case where a base index is insufficient.

New topic: internalformat_query2.

There’s one minor issue that’s effectively a spec bug.

Internalformat_query2 allows you to query GL_FRAMEBUFFER_RENDERABLE. All well and good. But it doesn’t really say what it means for it to have FULL_SUPPORT. It just says:

What I mean is this: GL_FRAMEBUFFER_UNSUPPORTED is allowed to happen by the spec for the use of formats that aren’t supported, or the use of a combination of formats that aren’t be supported. However the spec sets aside a number of formats which are not allowed to return GL_FRAMEBUFFER_UNSUPPORTED. You can use any combination of any of these formats and the implementation is required to accept it.

If I test a format that isn’t on OpenGL’s required list, and it returns FULL_SUPPORT, does that mean that I can never get UNSUPPORTED if I use it? No matter what? The spec doesn’t say. The exact behavior is not detailed, only that it is “supported”.

I think section 9.4.3 should be amended as follows. It should be:

This would give the query some actual teeth, because right now, it’s not clear what it means to fully support FRAMEBUFFER_RENDERABLE. Also, it explains what CAVEAT support means: that the format can be used in certain combinations with other formats, but it’s not guaranteed to work in combination with all other fully supported formats. NONE obviously means that it can never be renderable no matter what.

See my comment on the previous page for one case where a base index is insufficient.

I think there’s a basic failure to communicate here. I understand why we want to have a separation between buffer objects and vertex formats. I understand how that’s useful.

I don’t understand why we need to have a separation between strides and vertex formats. That’s my only problem with the extension: that the stride is with the buffer and not the format.

Eosie suggests that it’s a hardware thing, and I can understand that. However, NVIDIA’s bindless graphics API also provides separation between format and buffers (well, GPU addresses, but effectively the same thing: buffer+offset). And yet there, they put the stride in the format.

So why the discrepancy? I imagine that NVIDIA’s bindless accurately describes how their hardware works, more or less.

First of all, thank you ARB. The spec seems much clearer in many respects.

There is ClearBufferSubData, why is there not an analogue for textures? Or is it in the specification and I missed it?

No, as far as I can tell there isn’t. I find the whole extension strange and certainly confusing at least to the beginner. Try explaining why to use

glClearBufferData(GL_ARRAY_BUFFER, GL_R32F, GL_RED, GL_FLOAT, 0)

to someone trying to initialize a vertex buffer with zeros instead of using glBufferData with an accordingly sized array of zeros. BTW, I hope I set this call up correctly.

It’s good to have a memset() equivalent for convenience and for performance reasons when resetting a buffer during rendering (i.e. not having to transfer a complete set of data instead of a single value) but currently I can’t really imagine many convincing example uses that justifies introducing 2 (or 4) new APIs. If anyone has some please share.