More info for FRAMEBUFFER_UNSUPPORTED

With current NVIDIA drivers, if I attach a texture to an FBO color attachment, and the texture is not mipmap complete, CheckFramebufferStatus returns FRAMEBUFFER_UNSUPPORTED. As this error could mean just about anything, I spent a considerable amount of time chasing down all manner of possibilities before I finally tried making the texture mipmap complete before attaching it, which resolved the issue.

My suggestion is that OpenGL provide some kind of implementation dependent explanation string that could be queried with GetString( FRAMEBUFFER_STATUS ). If the framebuffer status is FRAMEBUFFER_COMPLETE, this query would return an empty string; otherwise, (and especially in the case of FRAMEBUFFER_UNSUPPORTED), the implementation would return some explanatory text to help the developer determine where their FBO configuration has gone awry. In my case, something like “the texture object at COLOR_ATTACHMENT0 is not mipmap complete.”

Everybody has to go through this. This is so common error originating from the fact that default texture filtering is MIPMAP.

It’s a mistake to try to texture with a non-mipmap complete texture object (and that’s a mistake I still make, occasionally, even after 16 years of OpenGL, sad to say). But this isn’t my point.

It is not specifically an error to attach a texture that isn’t mipmap complete to an FBO, as you are only attaching one layer of the texture. So this could be perfectly valid on some implementations.

My point is that FRAMEBUFFER_UNSUPPORTED gives the developer no clue as to what the problem is. The reason for that status return could be non-mipmap complete attachment (as in my case), or a bad match between color and depth buffer types, or it could be wrong phase of the moon. The spec allows an implementation to return that status for just about any reason whatsoever. As a developer, I’d just like a little more information to help debug my code.

well, nvdidia has something. They provide GLExpert here http://developer.nvidia.com/object/glexpert_home.html

It says a lot more info when FBO returns FRAMEBUFFER_UNSUPPORTED

Thanks, that’s useful, and would be a wonderful solution if NVIDIA were the only hardware I develop on.

OpenGL is a hardware-indendent API. My suggestion is for implementation-specific information exposed in a hardware-indendent manner, much the same way that implementations can provide their own implementation-specific shader compile warnings in the compile log.

A debug layer of some sort was proposed for GL3, but we’ve yet to see hide or hare of it.

A debug log dump area would be great for this sort of thing and it just so happens that’s just how it works in d3d10 (with the addition of pipeline configuration perf tips/warnings and such).

Actually I have seen something ominous myself with respect to FBO’s:


glGenTextures(1, &pT.m_name);
      glBindTexture(m_texture_type, pT.m_name);
      
  
      glTexParameteri(m_texture_type, GL_TEXTURE_WRAP_T, GL_REPEAT);
      glTexParameteri(m_texture_type, GL_TEXTURE_WRAP_S, GL_REPEAT);


      glTexImage2D(m_texture_type, 0, //target and mipmap level
                   pT.m_texture_format,
                   width(), height(), 
                   0, //border size 
                   guess_external_format(pT.m_texture_format), 
                   guess_external_type(pT.m_texture_format),
                   NULL //no data uploaded
                   );

      //NOTE!! Ask to generate mipmaps here!!
      glGenerateMipmap(m_texture_type);

      glBindTexture(m_texture_type, 0);
      

      //attatch the texture to the framebuffer object:
      
      glFramebufferTexture2D(GL_FRAMEBUFFER,
                                pT.m_attatchment_point,
                                m_texture_type,
                                pT.m_name,
                                0);

      check_framebuffer_status();


produces GL_FRAMEBUFFER_UNSUPPORTED. Which is very odd, one can see that I ask for mipmaps to be generated there? Anyone out there know what is going wrong there?

If I add:


//no filtering
glTexParameteri(m_texture_type, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(m_texture_type, GL_TEXTURE_MIN_FILTER,GL_NEAREST);

all nasties go away.

Edit: Ahh nevermind, I truly posted without thinking! Ahem: in my code I was also attaching integer texture targets, and for those you are not supposed to do filtering at all… though I would think that glGenerateMipmap should have generated an error on integer textures.

One more edit: looking at the GL 3.2 specification, for minification filtering, I only see this:

When target is TEXTURE_RECTANGLE, certain texture parameter values may not be specified. In this case, the error INVALID_ENUM is generated if the TEXTURE_WRAP_S, TEXTURE_WRAP_T, or TEXTURE_WRAP_R parameter is set to REPEAT or MIRRORED_REPEAT. The error INVALID_ENUM is generated if TEXTURE_MIN_FILTER is set to a value other than NEAREST or LINEAR (no mipmap filtering is permitted).

(page 157-160)

Is there anywhere in the spec that actually says that filtering is NOT allowed to integer textures?

Edit: too fast to post:

If the internal format of the arrays is integer (see (see table 3.12), TEXTURE_MAG_FILTER must be NEAREST and TEXTURE_MIN_FILTER must be NEAREST or NEAREST_MIPMAP_NEAREST.

page 171 on texture completeness.

Another edit: I don’t know if this is a driver bug or not, but using GL_NEAREST_MIPMAP_NEAREST on an integer texture and then using glGenerateMipmap still will generate GL_FRAMEBUFFER_UNSUPPORTED, and looking at how glGenerateMipmap is specified it looks like integer texture targets should work ok with glGenerateMipmap.

though I would think that glGenerateMipmap should have generated an error on integer textures.

Why not? You are perfectly free to have integral mipmaps on these textures. As for exactly what glGenerateMipmap will do with integral values, well, it will blend them. Just like it does for float values. And so forth.

I don’t know if this is a driver bug or not, but using GL_NEAREST_MIPMAP_NEAREST on an integer texture and then using glGenerateMipmap still will generate GL_FRAMEBUFFER_UNSUPPORTED, and looking at how glGenerateMipmap is specified it looks like integer texture targets should work ok with glGenerateMipmap.

GL_FRAMEBUFFER_UNSUPPORTED is something that an implementation can do for basically any reason. However, I honestly can’t see how it can be anything other than a driver bug if filtering settings affect its use as a render target.

Giggles:

GL_FRAMEBUFFER_UNSUPPORTED is something that an implementation can do for basically any reason. However, I honestly can’t see how it can be anything other than a driver bug if filtering settings affect its use as a render target.

ahem: what this post started as: if you have a texture which has mipmap filtering enabled (i.e. GL_MIN_FILTER is not GL_LINEAR or GL_NEAREST) but the mipmaps are not generated, then attaching that texture to an FBO is an error according to the specification, and the driver is to return GL_FRAMEBUFFER_UNSUPPORTED. For example:


1) Make texture, but do not make mipmaps.
2) set minification filtering to GL_NEAREST
3) attach to FBO

Is ok, but:


1) Make texture, but do not make mipmaps.
2) attach to FBO

which leaves the minification filter at using mipmaps will than make the FBO status be GL_FRAMEBUFFER_UNSUPPORTED.So the texture filter settings DO affect if an FBO will accept a texture as a render target.

LOL

I think the point he’s making is: the default min filter is not likely to change; rather we need to situate this thing in our minds so that it sits comfortably, as it’s almost certainly going to be sitting there for an extended period of time.

The greater log dumping issue, however, merits further consideration, IMHO - something with a user configurable and flush-able filtering system.

I would love the fabled debug GL3 context to come, but sighs.

One thing that just smells bad on the default filtering deals is this: for integer textures, the default filtering is an invalid value for them, which is just odd ball.

Aye, it’s odd ball; and now that you mention it there is a tinge of foul aloft.

I do seem to recall something similar with the GENERATE_MIPMAP TexParameter and a RECT texture or somesuch.

So the texture filter settings DO affect if an FBO will accept a texture as a render target.

Not according to the OpenGL specification. GL_FRAMEBUFFER_UNSUPPORTED should be returned for a violation of this completeness rule:

This says nothing about filtering parameters. GL_FRAMEBUFFER_UNSUPPORTED is supposed to only be used if the combination of formats doesn’t fit within some implementation-defined limits.

Page 172 of the 3.2 Core spec says that texture completeness only effects texture lookup. Texture completeness does not affect FBO completeness in any way.

None of the FBO completeness rules explicitly tests the completeness of bound textures. The attachment completeness rules (pp 233-234) say nothing about the texture completeness of attached textures.

It is therefore a driver bug for texture completeness to affect FBO completeness.

For GL_TEXTURE_RECTANGLE, mipmapping is not supported, for integer textures mipmapping is supported, BUT, the only allowed filter modes were so that no filtering really happens (confusing way I put it). to be precise, for integer textures:

TEXTURE_MAG_FILTER must be GL_NEAREST
TEXTURE_MIN_FILTER must be GL_NEAREST or GL_NEAREST_MIPMAP_NEAREST

the true bad odor comes from that the default value for TEXTURE_MIN_FILTER is GL_NEAREST_MIPMAP_LINEAR, which is bad for both integer textures and rectangular textures. Additionally the default value for TEXTURE_MAG_FILTER is GL_LINEAR, which is invalid for integer textures.

Worse, because the texture format is not specified at texture name creation, one must remember to change these values for integer and/or rectangular textures when one calls glTexImageWhatever… oh, only if Khronos was willing to change the texture creation/specification API a little bit.

As for Alfhonse, he is right that that nothing in the specification says that a texture attachment to an FBO must be texture complete, but he is wrong that it is a driver bug, the standard more or less says that FRAMEBUFFER_UNSUPPORTED can happen fro any reason an implementation feels like:

The combination of internal formats of the attached images does not violate
an implementation-dependent set of restrictions.

One could make a hair splitting argument that the above does not allow for weather or not texture completeness applies here, but it is truly then just what one wants to hear. At this point, it is truly splitting hairs though.

But back to the original poster, that FBO status is truly where something more useful than FRAMEBUFFER_UNSUPPORTED is supplied by the GL implementation, plain text is so useful!

One could make a hair splitting argument that the above does not allow for weather or not texture completeness applies here, but it is truly then just what one wants to hear.

How so? The wording clearly states “internal formats of the attached images.” Filtering parameters are not formats; they are parameters. Parameters are set with glTexParameter*; formats are set with glTexImage*.

These are in no way the same thing. The word “format” cannot possibly include “parameters.” This isn’t splitting hairs; this is simply what the specification says.

Also, the 3.0 and above version of FBOs specifically prohibits an implementation from returning GL_FRAMEBUFFER_UNSUPPORTED when using a certain combination of image formats:

Among the required formats are the various signed and unsigned integral formats. So this is two ways now that this implementation is explicitly forbidden from returning GL_FRAMEBUFFER_UNSUPPORTED. This is a driver bug.

No, it isn’t. In fact the specification says exactly the opposite. See EXT_fbo issue 43:

(43) In order for a framebuffer object to be “framebuffer complete”,
must all textures attached to the framebuffer be mipmap
complete (or mipmap cube complete if cubemap texture)?

        RESOLUTION:  resolved, no
        The reason this is a consideration is that some
        architectures require framebuffer-attachable images to be
        located in graphics memory when rendered to, and it may be
        more convenient to allocate and store a texture in graphics
        memory only if the texture is mipmap (cube) complete--i.e.,
        the size and format of all levels are consistent in the
        normal sense of texture compeleteness.
        However, since framebuffer attachment points only really
        deal with single images of a texture level, it seems
        excessive to require the state of the other levels of a
        texture to affect the validty of the framebuffer object
        itself.
        Addtionally, the same difficulties around "incomplete"
        textures already apply to traditional CopyTexSubImage, and
        we have been trying to make the render-to-texture semantics
        similar to CopyTexSubImage.
        Therefore, we chose not to treat render to texture any
        differently than CopyTexSubImage and do not require that the
        attached texture is mipmap (cube) complete.

Not required. We just need a way to query for a textual error message. No more meaningless constants.

Though as such we may yet need a special context of sorts, but only in so far as it may be desirable to expose an opportunity for the driver to reconfigure itself on a debug-ndebug basis - even if only to provide a dump repository.

We don’t need a special context for GLSL shaders. It’s simply a matter of putting a string in the FBO state that gets filled in if an implementation returns GL_FRAMEBUFFER_UNSUPPORTED.