FBO pitfall on nVidia

Today I encountered several serious crashes which even forced me to look for the reset button on my machine :slight_smile: Consider this sequence:

  1. bind an FBO
  2. glPushAttrib(GL_COLOR_BUFFER_BIT)
    3… do some rendering
  3. unbind the FBO (by binding 0)
  4. glPopAttrib()

Apparently GL tries to restore GL_COLOR_ATTACHMENT0_EXT as drawbuffer on the window-system-provided framebuffer, which doesn’t exist.
I looked through the FBO specs and found this:

(81) How should PushAttrib and PopAttrib work with this extension?
…
PushAttrib(COLOR_BUFFER_BIT)
saves the DRAW_BUFFER value of the currently bound
framebuffer object. If the app later calls PopAttrib() this
saved value will be restored even if the framebuffer bound
at the time PopAttrib is called is different from the
framebuffer bound at the time PushAttrib was called.

So it looks like a driver bug. Be warned :slight_smile: The current workaround is to call glPopAttrib() as long as the FBO is still bound.

Oh well, forgot the specs: GF8800GTS, Forceware 158.27 (WinXP 64bit)

Isn’t it better to just set whatever state you want when you’ll be using the FBO and then set it back. I thought pushattrib and popattrib were slow and discouraged.
It’s good for poeple using 3rd party code and they don’t know in what state GL will be left in.

on a related note

this is starting to piss me off majorly

http://www.gamedev.net/community/forums/mod/journal/journal.asp?jn=450912&reply_id=2985943

any ideas how to disable this message (which is factually incorrect)

today + yesterday, the computer was completely unusable for over an hour, it would spawn this messagebox 200x (which seems to be the limit that windows allows) so + cant start up another program eg browse the web, as fast as i get rid of these messageboxes new ones are created.

the problem is related to room temperature

can i somehow disable this warning in the registry?
or is there some system app that will prevent this messagebox from spawning?

Isn’t Push-/PopAttrib going away in LP/ME?

Funny, I’ve never even called the attribute twins before…

P.S. What’s the message say, zed? Must be getting old I can’t make it out.

I don’t think it would a good idea to drop glPushXXX/glPopXXX altogether.

It makes it easier to write reusable code that doesn’t rely on certain external OpenGL state. Also, such code is safer to call, because it will atomatically restore all OpenGL settings it might have had to change.

Having no such functionality means to do it yourself via:
a) read-back of current state, restore afterwards
b) completely track all state-changes and offer a push/pop like functionality through this system.

a) read-back is discouraged, because it is said to be slow

b) makes the reusable code dependend on the outer system. Also, you would have to completely encapsulate opengl to catch all calls. More important: you’d have to force everyone to actually use it. One direct call to GL and your cache is invalid (which you can’t know of).

I guess, that the driver can far better save/restore the state. For instance, restoring the state in the driver allows to skip validation steps.

Of course, I agree, saving for instance the state of uniforms is unreasonable. But pushing/popping the currently bound shader (along with the shader’s bound objects like samplers, images, bound uniform buffers etc) is a good example.

I don’t think it would a good idea to drop glPushXXX/glPopXXX altogether.
Considering that Longs Peak is going almost 100% object-based, there isn’t much state left to push/pop.

along with the shader’s bound objects like samplers, images, bound uniform buffers etc
You should read up on how LP is structured. The pipeline newsletters are the current primary source. None of this will be necessary with LP.

Considering that Longs Peak is going almost 100% object-based, there isn’t much state left to push/pop.

Agreed.

None of this will be necessary with LP.
Well, at least some basic state could be reasonable, something like:

lpPushState(LP_FRAMEBUFFER_BIT|LP_PROGRAM_BIT);
lpBindProgram(myfbo);
lpBindFramebuffer(myshader);
... do some rendering

lpPopState();

So my code can be called without having to care about what fbo/shader/misc state/ has been set before. I admit, that I have no in-depth idea, how offering such functionality could make the specs or implementation more complicated. But from my point of view, it sounds not all too hard.

PS: things get hard in LP, if I wanted to change only certain attributes of an object, like temporarily changing only the depthmask without affecting the rest of the depthbuffer related state. That might look like this:

lpPushState(LP_SAMPLE_OPERATIONS_BIT)

LPsampleops current;
lpGetHandle(LP_CURRENT_SAMPLEOP_OBJECT, &current)
LPsampleops sampleops;
lpCopyObject(current, &sampleops);
lpSetSampleOp(sampleops, LP_DEPTH_MASK, 0);
lpBindSampleops(sampleops);

renderStuff();

lpDestroyObject(sampleops),
lpPopState();

If LPsampleops is immutable, it might look this way:

lpPushState(LP_SAMPLE_OPERATIONS_BIT)

LPsampleops current;
lpGetHandle(LP_CURRENT_SAMPLEOP_OBJECT, &current)

LPsampleopattribs attributes ; (don't know how this might get called)
lpGetSampleOpAttributes(current, &attributes );
lpSetAttribute(attributes, LP_DEPTH_MASK, 0);
LPsampleops sampleops;
lpCreateSampleOps(attributes, &sampleops);
lpBindSampleops(sampleops);

renderStuff();

lpDestroyObject(sampleops),
lpPopState();

This is much code for something that has been a 3-liner in GL :slight_smile:

like temporarily changing only the depthmask without affecting the rest of the depthbuffer related state.
I think the general expectation for these, if they’re in an object at all, is that you should simply swap the object with one that already has the parameters you want.

skynet,

Do you have a simple app that shows this bug that you could post or send to me?