OpenGL: GL_FRAMEBUFFER_UNSUPPORTED on specific combinations of framebuffer attachments

2.9k views Asked by At

Im trying to attach multiple targets to a framebuffer object. I have the following problem:

There is no error, when using float texture attachments and a depth attachment. There is also no error, when using float texture attachments and integer texture attachments. Although these combinations work, I cant use float, integer and depth attachments at the same time. This results in a GL_FRAMEBUFFER_UNSUPPORTED status.

this is my code:

//working:
Framebuffer fb = Framebuffer(
    1280,720,
    {
        //AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
        AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
        AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
        AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
    }
);

//working:
Framebuffer fb = Framebuffer(
    1280,720,
    {
        AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
        AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
        //AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
        AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
    }
);

//NOT working:
Framebuffer fb = Framebuffer(
    1280,720,
    {
        AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
        AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
        AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
        AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
        AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
    }
);

Note: I only get this error when using my NVidia GTX 970 graphics card. On a bit older ATI card no error occured.

I use glbinding to call glGetError after every gl* function call, so I know, that no other error occured.

this is my constructor code for the Framebuffer object:

Framebuffer::Framebuffer(uint width,uint height,initializer_list<AttachmentInfo> attachments)
:width(width),height(height)
{
    glGenFramebuffers(1,&fbID);
    glBindFramebuffer(GL_FRAMEBUFFER,fbID);

    if(std::none_of(attachments.begin(),attachments.end(),[](const AttachmentInfo& a){
        return a.attachment == GL_DEPTH_ATTACHMENT;
    })){
        //depth test needs either a depth renderbuffer or depth attachment.
        unsigned int rboID=0;
        glGenRenderbuffers(1, &rboID);
        glBindRenderbuffer(GL_RENDERBUFFER, rboID);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,rboID);
    }

    vector<GLenum> buffers;
    glActiveTexture(GL_TEXTURE0);

    for(AttachmentInfo attachment:attachments){
        GLuint tID;
        glGenTextures(1, &tID);
        glBindTexture(GL_TEXTURE_2D,tID);

        GLint param;
        glGetInternalformativ(GL_TEXTURE_2D, attachment.internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1, &param);

        if(param != GL_FULL_SUPPORT){
            _log(WARNING,"Internal format " << attachment.internalFormat << " support is " << GLenum(param) << ".");
        }

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GLint(GL_LINEAR));
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GLint(GL_LINEAR));
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GLint(GL_CLAMP_TO_EDGE));
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GLint(GL_CLAMP_TO_EDGE));

        if(attachment.attachment == GL_DEPTH_ATTACHMENT){
              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GLint(GL_COMPARE_REF_TO_TEXTURE));
              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GLint(GL_LESS));
        }
        glTexStorage2D(GL_TEXTURE_2D,1,attachment.internalFormat,width,height);
        glFramebufferTexture(GL_FRAMEBUFFER, attachment.attachment, tID, 0);

        if(Tools::startsWith(glbinding::Meta::getString(attachment.attachment),"GL_COLOR_ATTACHMENT")){
            buffers.push_back(attachment.attachment);
        }
        texMap[attachment.attachment]=new Texture(tID,GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D,0);
    }
    if(buffers.empty()){
        buffers.push_back(GL_NONE);
    }
    glDrawBuffers(buffers.size(),buffers.data());

    GLenum error=glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(error != GL_FRAMEBUFFER_COMPLETE){
        _log(ERROR,"Framebuffer error: " << error);
    }
    unbind();
}

Im really out of ideas what I can do to make it work...

2

There are 2 answers

1
datenwolf On BEST ANSWER

Im really out of ideas what I can do to make it work...

Your OpenGL implementation tells you, that the configuration you choose is not supported. You have to accept that. The OpenGL specification does not require that particular combination of formats to be supported by all implementation, so if you want to program to be portable and robust, if you get a GL_FRAMEBUFFER_UNSUPPORTED error you'll have to gradually step down your format requirements until a workable combination is found.

A very good hint on what's supported is enumerating all the FBConfigs supported for creating a OpenGL context; usually this is a subset of the permissible FBO configurations.

0
Herman Appelgren On

In case anyone else runs across this question as I did. The exact combination of supported formats vary by OpenGL implementation, but there is a set of formats that any implementation must support. If you stick to those, you won't have to worry about portability. The requirements are described in the OpenGL wiki on Framebuffer Completeness and Required Image Formats.