Search code examples
c++c++11openglopengl-3opengl-4

Multisample framebuffer only incomplete with renderbuffer


I am setting up a multisampled framebuffer with 4 color attachments and 1 depth stencil attachment. It currently is incomplete with GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE. If I dont attach the renderbuffer it works perfectly. Debug output isnt printing anything, and glGetError() isnt showing any problems.

GLint samples;
glGetIntegerv(GL_MAX_SAMPLES, &samples);

const GLuint target = GL_TEXTURE_2D_MULTISAMPLE;
const GLenum format[TEXTURES_PER_FBO] = {
    GL_RGBA32F, GL_RGB32F, GL_RGB32F, GL_R8UI   // TODO tune these
};

// create render textures
glGenTextures(NUM_TEXTURES, textures);
for (int i = 0; i < NUM_TEXTURES; i++) {
    glActiveTexture(GL_TEXTURE0 + i);
    glBindTexture(target, textures[i]);
    const int index = i % TEXTURES_PER_FBO;
    glTexStorage2DMultisample(target, samples, format[index], width, height, false);
}

glGenRenderbuffers(1, &depth);
glBindRenderbuffer(GL_RENDERBUFFER, depth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width, height);

// create first framebuffer with depth attachment
glGenFramebuffers(NUM_FBOS, fbos);
glBindFramebuffer(GL_FRAMEBUFFER, fbos[0]);
for (int i = 0; i < TEXTURES_PER_FBO; i++) {
    const GLenum index = GL_COLOR_ATTACHMENT0 + i;
    glFramebufferTexture2D(GL_FRAMEBUFFER, index, target, textures[i], 0);
}
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

'status' is GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE

I have tested it on both a gtx 980 and 480 on windows. I dont have access to others at the moment, but I'll try to get some if this isnt resolved. If you need more code for context, it can be found here Thanks!


Solution

  • You need to pass GL_TRUE for the fixedsamplelocations (last) argument of glTexStorage2DMultisample() if you also have renderbuffer attachements. Otherwise you'll get exactly the GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE error you observe.

    From the list of possible glCheckFramebufferStatus() results in the spec (e.g. page 311 of the OpenGL 4.5 spec, section "9.4.2 Whole Framebuffer Completeness"):

    The value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures; and, if the attached images are a mix of renderbuffers and textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures. {FRAMEBUFFER_INCOMPLETE_MULTISAMPLE}

    So you need to change the call to this to get a valid FBO configuration:

    glTexStorage2DMultisample(target, samples, format[index], width, height, GL_TRUE);