gl_Position undef in ARB_separate_shader_objects?

I was experimenting with GL 4.1’s ARB_separate_shader_objects on my Windows box which has a ATI Radeon HD 5850, and Catalyst 11.1a.

If I feed this into glCreateShaderProgramv():

#version 410

void main()
{
    gl_Position = vec4(0.0f, 0.0f, 0.0f, 0.0f);
}

I get this error in the info log:

Shader Compile Log:
Vertex shader failed to compile with the following errrors:
ERROR: 0:5: error(#143) Undeclared identifier gl_Position
ERROR: error(#273) 1 compilation errors. No code generated

But I discovered adding a gl_PerVertex block fixes it:

#version 410

out gl_PerVertex
{
    vec4 gl_Position;
};

void main()
{
    gl_Position = vec4(0.0f, 0.0f, 0.0f, 0.0f);
}

Then it compiles fine.

Is this correct behaviour? I ask because I never ran into this when using ARB_separate_shader_objects with NVIDIA on Linux.

Now this is just getting weird…

When I compile this with glCreateShaderProgramv():

#version 410

uniform mat4 projection;
uniform mat4 modelView;

layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in vec3 normal;

out gl_PerVertex
{
	vec4 gl_Position;
};

void main()
{
	gl_Position = projection * modelView * vec4(position, 1.0f);
}

It fails to link with this:

Vertex shader(s) failed to link.
ERROR: error(#280) Not all shaders have valid object code

Shader Compile Log:
Vertex shader was successfully compiled to run on hardware.

Same story with fragment shader:

#version 410

out vec4 fragColor;

void main()
{
	fragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
Fragment shader(s) failed to link.
ERROR: error(#280) Not all shaders have valid object code

Shader Compile Log:
Fragment shader was successfully compiled to run on hardware.

What does this mean?!?

What does this mean?!?

glCreateShaderProgramv is very well defined in the extension specification. It creates a shader object, compiles it, if it compiled, it creates a program object and links the shader into that program. Then it concatenates the shader’s log into the program and returns the program.

Therefore, if you get different results when you do this manually (except for the shader log concatenation), then it is a driver bug.

The first problem is specified in the spec,
The following vertex shader outputs may be redeclared at global scope to specify a built-in output interface, with or without special qualifiers:
gl_Position
gl_PointSize

The second problem may be a bug in the driver. We will verify it first.

The following vertex shader outputs may be redeclared at global scope

It doesn’t say I must do…

glCreateShaderProgramv is very well defined in the extension specification.

OK, I copied the code exactly as it is in the spec… and guess what? I get the same errors!

glCompileShader, returns GL_COMPILE_STATUS of GL_TRUE, and that message “Vertex shader compiled successfully…” so the compile is fine.

The problem is when I go to link it! glLinkProgram returns GL_COMPILE_STATUS of GL_FALSE, and that message “… Not all shaders have valid object code” so the link has failed.

It seems that it is ignoring that GL_PROGRAM_SEPARABLE is GL_TRUE, so complains about the program missing a compiled fragment shader and vice versa for the separated fragment shader.

I will now try using the old fashioned glUseProgram way to see if it works…

Just tested a normal program with glUseProgram and everything compiles, links, and draws fine with the above shaders.

Strange how I’m the first one to notice some serious bugs in both NVIDIA’s and ATI’s implementation of ARB_separate_shader_objects! Has no one else used it yet?

P.S. Frank Li: I’m not sure if you noticed but Alfonse and Groovounet are still awaiting an update of this bug: http://www.opengl.org/discussion_boards/…8472#Post288472

someone should be fired for such an attitude

There are other paragraph specified the built-in input and output,
[b]To use any built-in input or output in the gl_PerVertex and gl_PerFragment blocks in separable program objects, shader code must redeclare those blocks prior to use. A separable program will fail to link if:

  • any shader uses a built-in block member not found in the redeclaration of that block.[/b]

For your another SSO problem, we can’t reproduce the “Not all shaders have valid object code” issue. Could you please paste the source code out for investigation? Thanks.

There are other paragraph specified the built-in input and output,

You have got to be kidding. Did the ARB think even a little about this extension before just shoving it out there? Just a little bit?

The main difference between EXT_spo and ARB_spo is that the ARB version actually works with non-built-in outputs/inputs. But it’s clear that nobody actually thought about the consequences of much of the language. This has lead to an incredibly terrible specification.

The ARB added locations to all inputs and outputs, so that linking could be done based on locations rather than names. Except that this only works for separate programs; if you link two shader stages, it only links by name. This is incredibly unintuitive.

And now we have this pointless bit of insanity. You have to redeclare any built-ins you use. Why? There’s no reason at all for it.

It’s obvious that the ARB rushed this extension out for SIGGRAPH; there were only 6 months between the EXT_spo and ARB_spo specs. Is there going to be a fix for all the problems with this extension?

Maybe the ARB needs to slow down with its speed of updates. If they’re going to put out bad specs like this one, it’d be better if they did nothing at all.

Sorry about the delay, but I have been away for a week.

I have uploaded the code that causes the bug to http://www.leithalweapon.geek.nz/BaseGL.zip

I haven’t bothered to tidy it up too much but it is a simple program so should be easy to follow.

Let me know if you need anything else.

You call compileShader in class Shader constructor, at that time, shader source haven’t been loaded from file. so m_source is empty.

following is the call stack
BaseGL.exe!Shader::compileShader() Line 65 C++
BaseGL.exe!Shader:hader(const char * name=0x012228b0, unsigned int type=0x00008b31) Line 8 C++
BaseGL.exe!VertexShader::VertexShader(const char * name=0x012228b0) Line 6 + 0x56 bytes C++
BaseGL.exe!Graphics::init() Line 219 + 0x30 bytes C++
BaseGL.exe!Graphics::Graphics() Line 15 C++
BaseGL.exe!WinMain() Line 7 C++
BaseGL.exe!__tmainCRTStartup() Line 574 + 0x35 bytes

Empty string can be compiled successfully, but it will fail in link time, since we can’t find main function. so our driver report following error:

Vertex shader failed to link.
ERROR: [linker] error(#280) Not all shaders have valid object code
Shader Compile Log:
Vertex shader was successfully compiled to run on hardware.

And you have a typo error in Shader::attach, after fix it, the result of glGetProgramPipelineiv will be valid.

Thank you frank. I hope I did not waste your time…

Interesting that empty string is valid compilable GLSL. Never occurred to me that the string might be empty when it compiled!

Perhaps adding a warning to the log when shader is missing the main function would be a useful addition.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.