0

I'm working with shaders just now and I'm observing some very strange behavior. I've loaded this vertex shader:

#version 150

uniform float r;
uniform float g;
uniform float b;
varying float retVal;
attribute float dummyAttrib;

void main(){
    retVal = dummyAttrib+r+g+b; //deleting dummyAttrib = corruption
    gl_Position = gl_ModelViewProjectionMatrix*vec4(100,100,0,1);
}

First of all I render with glDrawArrays(GL_POINTS,0,1000) with this shader without nothing special, just using shader program. If you run this shader and set point size to something visible, you should see white square in middle of screen (I'm using glOrtho2d(0,200,0,200)). DummyAttrib is just some attrib - my shaders won't run if there's none. Also I need to actually use that attribute so normally I do something like float c = dummyAttrib.That is also first question I would like to ask why it is that way.

However this would be fine but when you change the line with comment (retval=...) to retVal = r+g+b; and add that mentioned line to use attrib (float c = dummyAttrib), strange things happen. First of all you won't see that square anymore, so I had to set up transform feedback to watch what's happening.

I've set the dummyAttrib to 5 in each element of field and r=g=b=1. With current code the result of transform feedback is 8 - exactly what you'd expect. However changing it like above gives strange values like 250.128 and every time I modify the code somehow (just reorder calls), this value changes. As soon as I return that dummyAttrib to calculation of retVal everything is magically fixed.

This is why I think there's some sort of shader corruption. I'm using the same loading interface for shaders as I did in projects before and these were flawless, however they were using attributes in normal way, not just dummy for actually running shader.

These 2 problems can have connecion. To sum up - shader won't run without any attribute and shader is corrupted if that attribute isn't used for setting varying that is used either in fragment shader or for transform feedback.

PS: It came to my mind when I was writing this that it looks like every variable that isn't used for passing into next stage is opt out. This could opt out attribute as well and then this shader would be without attribute and wouldn't work properly. Could this be a driver fault? I have Radeon 3870HD with current catalyst version 2010.1105.19.41785.

1 Answer 1

1

In case of your artificial usage (float c = dummyAttrib) the attribute will be optimized out. The question is what your mesh preparing logic does in this case. If it queries used attributes from GL it will get nothing. And with no vertex attributes passed the primitive will not be drawn (behavior of my Radeon 2400HD on any Catalyst).

So, basically, you should pass an artificial non-used attribute (something like 1 byte per vertex on some un-initialized buffer) if GL reports attributes are not at all.

Sign up to request clarification or add additional context in comments.

8 Comments

Great that someone else experience the same behavior with attributes being opt out. I've asked here first, but if I got no answer yesterday I'd be switching between different catalyst versions whole day. However how to querry if attribute has been opt out? I've used glGetActiveAttrib and this returns "dummyAttrib" in name. Also what means passing 1 byte from unitialized buffer? That smells like access violation.
If glGetActiveAttrib returns you dummyAttrib in both cases - than it looks like a mystery and you'll need a test case to be sent to ATI. Passing 1-byte-per-vertex attribute in an allocated but not initialized buffer will not be an access violation.
What is the second case? I querry just after linking the shader. And for that not initialized buffer - I know what you mean now, but what is the difference from what I'm doing now (other than that byte is four times smaller than float)? How can I set up attribute when in fact GL would report that there are non avalible. I could do this via built-in attributes, but I don't want to mess with those (I got enough of these strange bugs from nowhere)
First case: retVal = dummyAttrib+r+g+b; Second case: c = dummyAttrib; GL reports to you the attributes shader uses. You are still free to pass any data with your draw call. (No need for buil-in attribs).
I modified shader to c=dummyAttrib; and retVal=5;. I can still get this attribute name by glGetActiveAttrib, but the result of transform feedback should be 5 and is 0 - that means the shader doesn't work and dummyAttrib is opt out. However this must happen in runtime, more specificaly in drawing call, because I couldn't querry that attribute without any problem if it was done in linking stage. And I have bound that empty-but-allocated buffer right before drawArrays but nothing had changed and I knew that it wouldn't. Maybe I'm missing the point of what you're saying?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.