PDA

View Full Version : GL 4 Core Function Loading in Core 3.1+ Confusion



master_of_the_gl
12-31-2015, 03:07 AM
Recently, I removed GLEW from my engine and implemented my own GL function loader. Well, I never really cared about it.
During the refactoring step, I came to download the glcorearb.h file from the gl website and I was not so amused to see what functions became core 4.0.

First of all, I just thought, OpenGL 4.0 is an API for "new" generation hardware. You know, when it started with hw tesselation and stuff. Anyway. Seeing the Transform Feedback function in the GL_VERSION_4_0 section of glcorearb.h somehow breaks my heart.

I really commited to OpenGL 3.1-3.3 API features, because I wanted to port to OpenGL ES 3 soon and I thought that would be like a dream if using OpenGL 3.3 core features. I also really need Transform Feedback, because this is a super nice(and only) OpenGL 3.1+ feature(in my thoughts) that allows you to do GPU only computation. I.e. not being required to go though the CPU.

But what does it mean to see those TF functions in the GL_VERSION_4_0? Well I tried the following:

When I create a GL 3.1, 3.2 or 3.3 context with core profile, the nvidia driver actually supports the TF functions, but it does not support all of the function listed in the GL_VERSION_4_0 section of glcorearb.h file. This is important to me! With an 3.1, 3.2 or 3.3 core profile context, I can actually load the TF functions! With support, I mean wglGetProcAddress is able to load the function.

Now. Creating a 4.0 core profile context, ALL function of the GL_VERSION_4_0 can be loaded!

So whats going on? Being able to load functions listed under GL_VERSION_4_0 in glcorearb.h with a GL 3.1, 3.2 or 3.3 core context?

By any chance, could someone please enlighten me?

Alfonse Reinheart
12-31-2015, 06:35 AM
But what does it mean to see those TF functions in the GL_VERSION_4_0?

It means that NVIDIA probably supports ARB_transform_feedback2 (https://www.opengl.org/registry/specs/ARB/transform_feedback2.txt) and/or ARB_transform_feedback3 (https://www.opengl.org/registry/specs/ARB/transform_feedback3.txt). These are both "backwards-compatibility extensions" or "core extensions"; so they use the same function entrypoints as the core OpenGL version feature. That way, hardware that can't support all of, for example, OpenGL 4.0 can express support for parts of it via extensions.

If you're going to write an OpenGL loader (and I have no idea why you'd want to, since there are many of them with varying featuresets (https://www.opengl.org/wiki/OpenGL_Loading_Library)), then you must make sure to only load functions for things you've verified are actually available. Many OpenGL implementations will return non-NULL function pointers for everything, even for `glFunctionThatDoesntExist`. You should use the version number and the extension list to define what functionality is available.

master_of_the_gl
12-31-2015, 07:31 AM
I though, Transform Feedback is OpenGL 3.1-3.3 domain!? It really bugs me that especially DrawTransformFeedback is in OpenGL 4 domain! I really do not understand why this is in OpenGL 4 Domain. Isn't OpenGL 4.0 supposed to mainly introduce the new tesselation/compute functionality?
If I take a look into the Transform Feedback extensions, I can not see any note of OpenGL 4. It is rather mentioning OpenGL 2!


The OpenGL Shading Language (GLSL) is required. OpenGL 2.0 or the ARB_shader_objects extension is required.


What is the general way of figuring out which feature is supported in which version of OpenGL?
If I created an OpenGL 3 core profile context, can I assume to be provided with ALL OpenGL 3 Core functionality?
What do you call core functionlity. Is it still call "extensions"?

Let's say, you implemented Transform Feeback into your engine and you require it for certain algorithm(make it fast). What would you tell a customer which OpenGL Version(compatible graphics card) he/she requires in order to run the program?

GClements
12-31-2015, 10:02 AM
I though, Transform Feedback is OpenGL 3.1-3.3 domain!?
glBeginTransformFeedback is 3.0. glBindTransformFeedback and glDrawTransformFeedback are 4.0. glDrawTransformFeedbackInstanced is 4.2. glCreateTransformFeedbacks is 4.5.



It really bugs me that especially DrawTransformFeedback is in OpenGL 4 domain! I really do not understand why this is in OpenGL 4 Domain. Isn't OpenGL 4.0 supposed to mainly introduce the new tesselation/compute functionality?
If I take a look into the Transform Feedback extensions, I can not see any note of OpenGL 4. It is rather mentioning OpenGL 2!

The only "domains" are (desktop) OpenGL and OpenGL ES. Other than that, OpenGL versions aren't maintained in parallel. The publication of the OpenGL 4.0 specification meant that there would be no more OpenGL 3.x versions.



What is the general way of figuring out which feature is supported in which version of OpenGL?

The specification for a particular version specifies everything that's provided by that version. The OpenGL 4 reference pages (https://www.opengl.org/sdk/docs/man4/) list the supported versions for each function at the bottom of each page. If specific parameters or combinations of parameters require a particular version higher than that for the function itself, it is usually documented in the Notes section.



If I created an OpenGL 3 core profile context, can I assume to be provided with ALL OpenGL 3 Core functionality?

Yes.



What do you call core functionlity. Is it still call "extensions"?

An extension is anything that isn't core functionality. Most core functionality in later versions started out as an extension before being added to core. However: it's not uncommon for the version added to core to differ from the extension in some respect, and even if there is no difference, the core version is not the extension. You can't expect to be able to use functions or enumerants ending in EXT, NV, etc unless you've queried for the extension and found it to be present, regardless of the version. And you can't assume that you can "mix and match" the two, e.g. using enumerants from the extension with functions from the core version or vice versa.



Let's say, you implemented Transform Feeback into your engine and you require it for certain algorithm(make it fast). What would you tell a customer which OpenGL Version(compatible graphics card) he/she requires in order to run the program?
Which transform-feedback features? If you only need the functions which are present in 3.0, then you only need 3.0. If you need glDrawTransformFeedback() then you need 4.0.

master_of_the_gl
12-31-2015, 10:25 AM
First of all. Thank you for your explanations!

I am particularly talking about ARB_transform_feedback2 (https://www.opengl.org/registry/specs/ARB/transform_feedback2.txt).

I totally commited to that extension because I thought it is within OpenGL 3.1-3.3 featureset. Very important: Pre OpenGL 4 capable hardware! Targeting OpenGL 3.x and OpenGL ES 3 is very important to me.

Now, the extension text mentions DrawTransformFeedback and in fact I am also using it a lot! But I can not see any mention of OpenGL 4 in that text. So I wonder why, in this example, DrawTransformFeedback became an OpenGL 4 Core feature?! The text only refers to OpenGL 2.1.

Why does ARB_transform_feedback2 has become an OpenGL 4 Core feature when OpenGL 4 hardware is not required for that feature?

P.S.

Allow me ask the other way around: Is it possible to create an OpenGL 4.0 core profile context on a graphics card that does not feature OpenGL 4 hardware feature like tesselation?

Alfonse Reinheart
12-31-2015, 02:39 PM
Isn't OpenGL 4.0 supposed to mainly introduce the new tesselation/compute functionality?

No. It includes lots of things. Some require very specific hardware, but many of them could also be implemented on lesser hardware. That's why extensions like ARB_transform_feedback2 exist; so that pre-4.x hardware can still expose that particular functionality without having to expose it all.


Targeting OpenGL 3.x and OpenGL ES 3 is very important to me.

Then you have made a mistake and need to undo it. ARB_transform_feedback2 isn't supported in OpenGL ES of any kind.

If you want to prevent such mistakes in the future, you should use an OpenGL Loading Library (https://www.opengl.org/wiki/OpenGL_Loading_Library) that provides version-specific loaders. Where you can say "only give me what core OpenGL 3.3 provides", and the headers you get will only have core functions from that version.


Now, the extension text mentions DrawTransformFeedback and in fact I am also using it a lot! But I can not see any mention of OpenGL 4 in that text. So I wonder why, in this example, DrawTransformFeedback became an OpenGL 4 Core feature?! The text only refers to OpenGL 2.1.

Why does ARB_transform_feedback2 has become an OpenGL 4 Core feature when OpenGL 4 hardware is not required for that feature?

Think of it like this.

It's a required feature of OpenGL 4.x. But it's an optional feature of any OpenGL version 2.0 or better. It may be available or it may not. The way you state that an optional feature is available on the current OpenGL implementation is with an extension.

So if the OpenGL version is 4.0+ OR ARB_transform_feedback2 is available, then the functionality is there. That's what you do to test for it. And if your program relies on it, then you need to have your program terminate if the condition fails.


Allow me ask the other way around: Is it possible to create an OpenGL 4.0 core profile context on a graphics card that does not feature OpenGL 4 hardware feature like tesselation?

No.

GClements
12-31-2015, 03:04 PM
Now, the extension text mentions DrawTransformFeedback and in fact I am also using it a lot! But I can not see any mention of OpenGL 4 in that text.

ARB_transform_feedback2 says


Status

Complete. Approved by the ARB at the 2010/01/22 F2F meeting.
Approved by the Khronos Board of Promoters on March 10, 2010.

OpenGL 4.0 was published March 11, 2010, i.e. it didn't exist at the time that the extension was being formalised.

More generally, extensions are normally written against the oldest core version which it is practical to extend. The purpose of transform-feedback is to store the outputs from a vertex shader, which means that it's going to be rather awkward to write it as an extension to a version which doesn't have shaders (i.e. any 1.x version).



Why does ARB_transform_feedback2 has become an OpenGL 4 Core feature when OpenGL 4 hardware is not required for that feature?

Writing an extension against a specific version of the standard doesn't say anything about the type of hardware required to implement that extension. Just because it's written against 2.1, that doesn't mean that the extension can be implemented on any hardware which can fully implement 2.1, only that it's practical to write the extension specification without needing to refer to language which was added in later versions.

But even if it can be implemented on 3.x hardware, OpenGL 3.3 and OpenGL 4.0 were both released on March 11th, i.e. the day after the extension became final. In theory, it could have been incorporated into either. The choice may have been dictated by practical considerations, e.g. if the extension was initially formulated at a time when drivers for 3.3 were well advanced but drivers for 4.0 were at an early stage or not yet started, excluding it from 3.3 could have avoided delays in providing drivers.



Allow me ask the other way around: Is it possible to create an OpenGL 4.0 core profile context on a graphics card that does not feature OpenGL 4 hardware feature like tesselation?
In theory, yes: it's entirely possible to provide a conforming OpenGL implementation for a 1990s-era VGA card, but it's going to be implemented entirely in software. In practice, vendors typically don't bother supporting OpenGL versions which would require substantial software fallbacks. They expose the highest version which can be fully implemented in hardware then whichever individual extensions the hardware supports. That allows the application to select an approach which is appropriate for the hardware.

It's not possible (or at least it shouldn't be possible) to create a 4.0 context with a hardware+driver combination where some 4.0 feature simply isn't available. If you successfully create a 4.0 context, glCreateShader(GL_TESS_EVALUATION_SHADER) isn't allowed to fail with GL_INVALID_ENUM.

Having said that, vendors do sometimes take liberties with conformance. E.g. the noise functions were part of GLSL since the beginning. They were eventually deprecated in 4.4 because no-one actually implemented them.

Alfonse Reinheart
12-31-2015, 05:24 PM
More generally, extensions are normally written against the oldest core version which it is practical to extend. The purpose of transform-feedback is to store the outputs from a vertex shader, which means that it's going to be rather awkward to write it as an extension to a version which doesn't have shaders (i.e. any 1.x version).

It's important to note that "written against" and "minimal version" are not always the same version number. For example, transform_feedback2 is written against OpenGL 2.1, so all of its changes are relative to that specification. But the minimum version it says that it requires is 2.0.

master_of_the_gl
01-01-2016, 09:02 AM
For me, OpenGL 3.3 to OpenGL 4.0 was like the transition of DX10 to DX11 which was like the transition from non-tessellation hardware to tessellation hardware. So that API versions transition became dependent on the hardware due to tessellation. So in my eyes, making a feature core OpenGL 4.0 that does not require tessellation, makes no sense to me, because ARB_transform_feedback2 has a wide range of usefullnes that could be used on pre tessellation hardware. Yes I understand that it can still be present due to implemented extensions. But saying my app requires OpenGL 3.3 core instead of "I basically only need OpenGL 3.3 core but I also need some functionality of OpenGL 4 core that do not depend on hardware and could be there. Here's the list.", just sounds better.

So then, lets say, you know, you have a DirectX 10 compatible GPU. Would you buy a game/application that requires DirectX 11? I suppose you would not. Becuase you want that hardware implemented goodness of functionality.

How would you say that in OpenGL language? Where do you draw the compatibility line WITHOUT passing a 100 line extension list to the customer listing all OpenGL extension that are required for running your program?

Because you could basically say, my application requires OpenGL 2.0 but with this list of extensions. I think no one would be interested in that list. How would you explain to a customer, what hardware is required to run the program by telling an OpenGL version? As a customer you may be confronted with a decision like "Do I have to buy new hardware in order to run that program?"

Alfonse Reinheart
01-01-2016, 09:46 AM
For me, OpenGL 3.3 to OpenGL 4.0 was like the transition of DX10 to DX11 which was like the transition from non-tessellation hardware to tessellation hardware. So that API versions transition became dependent on the hardware due to tessellation.

Your belief that D3D11 == "tessellation" is based on marketing speak and buzzwords, not actual facts. Tessellation may have been the marque feature of D3D11, but it was hardly the only thing it brought to the table.

D3D11 represented a higher level of functionality than D3D10. But that higher level included a lot more than just tessellation.


So in my eyes, making a feature core OpenGL 4.0 that does not require tessellation, makes no sense to me, because ARB_transform_feedback2 has a wide range of usefullnes that could be used on pre tessellation hardware.

And what about "pre-tessellation hardware" that cannot actually implement transform_feedback2? Your problem is that you believe that this functionality is purely an API change. It is not.

Yes, binding transform feedback state into an object is purely an API change. But that's not all TF2 provides. It allows you to pause and resume feedback operations. It allows you to render feedback operations without doing a GPU-CPU readback.

Pausing feedback operations requires that the feedback hardware be able to do that. This means the hardware has to be able to store its current position to some location, then restore that current location later. Rendering feedback operations requires... basically most of the same stuff that ARB_draw_indirect does.

I don't see why you're so up in arms about things like transform_feedback_2, when there are far more eggregious pieces of functionality that could be implemented on GL 3.3 hardware that aren't core 3.3. Like ARB_separate_shader_objects, most of ARB_enhanced_layouts, ARB_explicit_uniform_locations, ARB_texture_storage, ARB_buffer_storage, and so forth. None of them are specific to hardware versions.


So then, lets say, you know, you have a DirectX 10 compatible GPU. Would you buy a game/application that requires DirectX 11? I suppose you would not. Becuase you want that hardware implemented goodness of functionality.

How would you say that in OpenGL language?

I wouldn't specify an OpenGL version. I would specific the specific hardware that I know will work. Like GeForce GT 2xx or better, Radeon HD 3xxx or better, Intel HD 4xxx or better. Not only is that more specific, it's easier for a user to know when they have the right hardware. They don't have to look up a version number; they just look up what their hardware is.

master_of_the_gl
01-01-2016, 11:02 AM
And what about "pre-tessellation hardware" that cannot actually implement transform_feedback2? Your problem is that you believe that this functionality is purely an API change. It is not.

This is basically my problem. I assumed that it is fully hardware implementable without "newer" tessellation hardware. I thought it is some kind cure to the problem of not having ARB_draw_indirect on OpenGL 3.x compatible hardware... Ok, I see my problem now.



I don't see why you're so up in arms about things like transform_feedback_2, when there are far more eggregious pieces of functionality that could be implemented on GL 3.3 hardware that aren't core 3.3. Like ARB_separate_shader_objects, most of ARB_enhanced_layouts, ARB_explicit_uniform_locations, ARB_texture_storage, ARB_buffer_storage, and so forth. None of them are specific to hardware versions.

Because I implemented an algorithm that mainly uses transform_feedback_2 for computation and I was in the believe that the algorithm could run on older hardware that barely supports OpenGL 3.3 but not OpenGL 4. I was wrong as I was wrong about the OpenGL ES 3 thoughts. I didn't looked it up exactly enough.



I wouldn't specify an OpenGL version. I would specific the specific hardware that I know will work. Like GeForce GT 2xx or better, Radeon HD 3xxx or better, Intel HD 4xxx or better. Not only is that more specific, it's easier for a user to know when they have the right hardware. They don't have to look up a version number; they just look up what their hardware is.

But that requires the user to check if her graphics card is newer than the one you specified and it requires you, the developer, to check if the driver actually implements that feature for all those graphics cards. Maybe I am wrong about that too, but if I read, "this graphics card is compatible to DirectX 11", can I assume that this graphics card supports ALL DirectX 11 features as a consumer as well as a developer? So could I equally say that "this product requires Core OpenGL 3.3", everyone can assume ALL features being implemented in the driver that can be look up in glcorearb.h, up to the specific section in that file?



It's important to note that "written against" and "minimal version" are not always the same version number. For example, transform_feedback2 is written against OpenGL 2.1, so all of its changes are relative to that specification. But the minimum version it says that it requires is 2.0.

This is very confusing and I assume that I can not derive any association to core features from the raw spec files?!



If you want to prevent such mistakes in the future, you should use an OpenGL Loading Library that provides version-specific loaders. Where you can say "only give me what core OpenGL 3.3 provides", and the headers you get will only have core functions from that version.

I would like to cut out some dependencies from my engine, so the gl loading has fallen first. Even if it means that I make mistakes. To be perfectly honest, only because we have Unity or UE doesn't mean the world has to stop coding OpenGL, C++ or anything else that is fun.

Alfonse Reinheart
01-02-2016, 08:34 AM
This is basically my problem. I assumed that it is fully hardware implementable without "newer" tessellation hardware. I thought it is some kind cure to the problem of not having ARB_draw_indirect on OpenGL 3.x compatible hardware... Ok, I see my problem now.

Well, it very well may be. But you won't know from looking at extension lists or version numbers. You will only know by looking at the actual hardware itself.

For example, this database (http://delphigl.de/glcapsviewer/gl_listreports) or this tool that contains a database (http://www.realtech-vr.com/glview/). If you want to know what hardware supports which features, those are good resources. Not the XML spec files.

In this case, you can see (http://delphigl.de/glcapsviewer/listreports2.php?listreportsbyextension=GL_ARB_tra nsform_feedback2) that there's quite a lot of OpenGL 3.3 hardware that does support ARB_transform_feedback2. Is it universal? No idea. But it seems pretty substantial. I personally would not feel uncomfortable saying that Radeon HD 3xxx+, GeForce GT 2xx+, and Intel HD 4xxx+ would support it.


But that requires the user to check if her graphics card is newer than the one you specified and it requires you, the developer, to check if the driver actually implements that feature for all those graphics cards. Maybe I am wrong about that too, but if I read, "this graphics card is compatible to DirectX 11", can I assume that this graphics card supports ALL DirectX 11 features as a consumer as well as a developer? So could I equally say that "this product requires Core OpenGL 3.3", everyone can assume ALL features being implemented in the driver that can be look up in glcorearb.h, up to the specific section in that file?

I wouldn't. Remember: there are always driver bugs; even if it claims to support something, that doesn't mean it's correctly supported. So comprehensive testing is always important.


This is very confusing and I assume that I can not derive any association to core features from the raw spec files?!

The confusion comes from you trying to equate version numbers with hardware that can implement it. If you stop doing that, the confusion goes away.

EXT_transform_feedback is written against OpenGL 2.1. ARB_transform_feedback2 does not in any way rely on features from higher OpenGL versions. So... why would it be written against 3.3 or 4.0, when it could be written against 2.1 and thus used in tandem with EXT_transform_feedback?

And the raw spec files make it clear that the functions/enums in ARB_transform_feedback2 are incorporated into core OpenGL 4.0, not 3.3 or 2.1.


I would like to cut out some dependencies from my engine, so the gl loading has fallen first. Even if it means that I make mistakes.

Well I hope the time you've spent on this issue was totally worth the whole... two files you gave up in external dependencies.


To be perfectly honest, only because we have Unity or UE doesn't mean the world has to stop coding OpenGL, C++ or anything else that is fun.

I will never understand the need some people have to make things harder for themselves. I can understand writing a loader if you have specific features you want that no loader provides. Like not exposing functions/enums outside of certain versions, or using a C++11-style interface or exporting to Python or whatever. But if a tool exists, works, is simple to use, and does exactly what you need... I see no advantage to throwing it away.

There's a huge chasm between "save myself some trouble in using OpenGL" and "give up total control of my application to an engine". Trying to equate them is just false equivalence.

master_of_the_gl
01-04-2016, 07:48 AM
I think I see the problem of having a GPU vendor commiting to a OpenGL version. Say a vendor makes the statement "GPU X supports OpenGL Version 4". Could we say that, this GPU would also support further OpenGL 4.x versions? I dont know. But this could be a problem, because if that GPU does not implement some feature of, say, OpenGL 4.10, the game of "you need OpenGL 4 + this list of extensions" would start from the beginning. Because I think you can not sync a GPU architecture change with some OpenGL version, so it could be the case that one GPU supports OpenGL 4.0-4.3 and the next arch could support OpenGL 4.0-4.10... I every though there is some sort of synchronization...
And so it is easier to name some minimum version and try yourself up with extensions with the promise of vendors have extension(ARB or not) very possibly implemented. So it totally makes sense to name the GPU and NOT the OpenGL version.



There's a huge chasm between "save myself some trouble in using OpenGL" and "give up total control of my application to an engine". Trying to equate them is just false equivalence.

Well, if you put it that way, you might be right. But you could also abstract things and say "what does save me the most trouble?". I would say, it is the way of least resistance. And so you could straight skip all that OpenGL/fundamental C++/APIs/massive learning/investing huge amounts of time/(and so many other things) and come straight to Unity or any other very high level engine(with editor and what not) that will save you the most trouble. Right?

And with your following statement, I would assume, you mean the abstract version of "what does save me the most trouble?".



I will never understand the need some people have to make things harder for themselves.

I would say, its passion!

Thank you very much for taking so much time answering my questions! I think I understand things better now and I'll be more aware of some details in loading the GL functions myself.