PDA

View Full Version : profile detection method



kyle_
05-21-2011, 03:32 PM
Assume we want to create a GLSL shader that uses compatibility profile.

To do that correctly however (by this, i mean first checking for its availability and using only if available), it appears some nasty tricks are necessary.

GLSL compiler exposes certain macros to advertise its capabilities, namely 'GL_core_profile' (always ... duh) and 'GL_compatibility_profile' (if it is supported).

These macros are, however, pretty much useless. Version declaration has to be first non-comment/whitespace thing in a shader, so to obtain the info without getting in erroneous situations, one is forced to compile a shader in core profile that does something conditionally depending on 'GL_compatibility_profile' availability and then inspect output/interface of the shader.

Am i missing something?

Alfonse Reinheart
05-22-2011, 12:05 AM
by this, i mean first checking for its availability and using only if available

Do you want two versions of the shader, one that runs in compatibility and one that runs in core? Or do you want different versions of the same shader?

Can you give some more detail (like an example) of what you're trying to do?


These macros are, however, pretty much useless.

They do exactly what they're supposed to: allow you to conditionally compile code based on whether the profile is core or compatibility.

Yes, you cannot change the version declaration of a shader based on whether the external OpenGL profile is core or compatibility. If you need this ability, you will have to build it in code. That is, use the fact that GLSL shaders are built from multiple strings concatenated together.

Your main shader file should have no version declaration. Instead, the C/C++ code that loads the shader into the shader object will apply a version string as the first string, while the shader's body will be the second string. It's really quite simple.

kyle_
05-22-2011, 01:56 AM
Just a clarification. Im not trying to do anything - this is a theoretical problem only as i think every vendor out there supports compatibility profile in GLSL.


Can you give some more detail (like an example) of what you're trying to do?
Pretty much, set up compatibility profile GLSL shader that _will_ compile (assuming no compiler bugs).

You cant be sure that following will compile (assuming version string advertises 330 for GLSL):


#version 330 compatibility
void main() {}

As compatibility profile is optional. There should be a way to check if its supported. My point it, its stupidly complicated to confirm that support 'the right way'.
Granted one could just compile away and be done with it, but this just doesn't seem right.




These macros are, however, pretty much useless.
They do exactly what they're supposed to: allow you to conditionally compile code based on whether the profile is core or compatibility.

I don't think this is what they do. These macros are unaffected by current shader profile you are compiling with - they just expose GLSL shader compiler capabilities (at least this is how i read their specification).



Implementations providing the compatibility profile provide the following macro:
#define GL_compatibility_profile 1

There is no mention that this macro appears only in compatibility profile.

If what you suggest is true, then there is no way to discover support for compatibility profile, except failing compilation of shader i provided above.


Your main shader file should have no version declaration. Instead, the C/C++ code that loads the shader into the shader object will apply a version string as the first string, while the shader's body will be the second string. It's really quite simple.
This is all cool, but still, how would you check for 'compatibility' profile availability so you can push it to your version string?
My whole point is that you cant (at least in a reasonable way).

Alfonse Reinheart
05-22-2011, 02:10 AM
As compatibility profile is optional. There should be a way to check if its supported.

If you need the compatibility profile, you ask for it at context creation time. If the implementation can't provide it, you don't get a context.

Whether the compatibility profile is supported is not something that shaders should be testing. If a shader relies on the compatibility profile, then the OpenGL code using that shader must also rely on the compatibility profile. If the implementation can't provide this, then the OpenGL code will never get to load the shader to begin with.


There is no mention that this macro appears only in compatibility profile.

That's how spec language works. If the spec says "if A then B", this also means "if not A then not B" unless further language clarifies that.


how would you check for 'compatibility' profile availability so you can push it to your version string?

First, you created the OpenGL profile; you know whether it is compatibility or not. Second, like all other OpenGL state, there is a glGet for this: GL_CONTEXT_PROFILE_MASK. You bitwise-and it with GL_CONTEXT_CORE/COMPATIBILTY_PROFILE_BIT.

So I don't see the problem.

kyle_
05-22-2011, 02:53 AM
As compatibility profile is optional. There should be a way to check if its supported.

If you need the compatibility profile, you ask for it at context creation time. If the implementation can't provide it, you don't get a context.

You appear to assume that compatibility profile in GLSL is somehow tied to compatibility profile of used GL context - which it isnt (at least in any normative way in the specification).
Some of GLSL features are said to be 'described' in GL compatibility spec, but nowhere in GL nor GLSL specifications there is a text that prevents you from creating GLSL shader with 'compatibility' profile inside core GL context. At least i couldnt find any.

I agree that the intent was probably to only allow:
GL core -> only GLSL core
GL comp -> GLSL comp + GLSL core (so that at least shaders migration could be made without requirement to drop display lists and whatnot)



Whether the compatibility profile is supported is not something that shaders should be testing. If a shader relies on the compatibility profile, then the OpenGL code using that shader must also rely on the compatibility profile. If the implementation can't provide this, then the OpenGL code will never get to load the shader to begin with.

Exactly my point. Problem is OpenGL cant check for compatibility support in GLSL shader, and there is no requirement that compatibility GL context supports compatibility GLSL profile.
As i read the spec, it currently allows you to write compatibility shader that uses legacy features in core GL profile and then go 'ooops' since its either unusable on undefined what it does. Would be correct as far as shader language is concerned though.




There is no mention that this macro appears only in compatibility profile.
That's how spec language works. If the spec says "if A then B", this also means "if not A then not B" unless further language clarifies that.

Can you clarify? When referring to compatibility profile features GLSL specification always uses 'when using compatibility profile'. This is not the case here.




how would you check for 'compatibility' profile availability so you can push it to your version string?

First, you created the OpenGL profile; you know whether it is compatibility or not. Second, like all other OpenGL state, there is a glGet for this: GL_CONTEXT_PROFILE_MASK. You bitwise-and it with GL_CONTEXT_CORE/COMPATIBILTY_PROFILE_BIT.
So I don't see the problem.
This would be true if type of GL context had influence on GLSL shader compiler profiles, which i say it doesnt have.

Again problem is highly theoretical anyways, but imo GLSL is decoupled from GL specification so much that your implication above is theoretically incorrect.

Alfonse Reinheart
05-22-2011, 01:09 PM
If you think this is a spec problem, file a bug report on it.