Attaching texture to framebuffer for reading causes slow rendering later

Some context: I have a project which creates thumbnails of textures when they are loaded to be used in the GUI. This is achieved by attaching the texture to a framebuffer and using glReadPixels. It works perfectly, but: If a texture from which a thumbnail was generated is then used later on during rendering, the frame rate drops dramatically. I got rid of all the relevant code except for the part that attaches the texture to the framebuffer, and the same slow-down persists.

So the problem boils down to: I call the following code during initialization, after the texture with name “texID” is created and no longer bound, and after an FBO is bound:

            //attach texture
        gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, 
            GL2.GL_COLOR_ATTACHMENT0, GL2.GL_TEXTURE_2D, texID, 0);
        
        //specify drawbuffers and readbuffers
        gl.glDrawBuffer(GL2.GL_NONE);
        gl.glReadBuffer(GL2.GL_COLOR_ATTACHMENT0);
        
        //check if it worked
        int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);
        if(status != GL2.GL_FRAMEBUFFER_COMPLETE){ 
            throw new Error("FBO status is not GL_FRAMEBUFFER_COMPLETE."); }
        
        //set appropriate viewport
        gl.glViewport(0, 0, width, height);

        //don't do anything (normally glReadPixels stuff would go here)
        
        
        //detach texture
        gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, 
            GL2.GL_COLOR_ATTACHMENT0, GL2.GL_TEXTURE_2D, 0, 0);

Now I render a bunch of stuff, none of which uses “texID”, at about 95 fps. If instead I render the stuff using the texture “texID”, the frame rate drops to about 50. If I render the stuff using the texture “texID”, but do not do the code snippet above, then it renders at about 95 fps.

Am I missing something obvious?

Extra info: The project is written in Java, using JOGL 2.0, running on Ubuntu 10.04 LTS; graphics card is AMD Radeon HD 6700, Catalyst version 11.12.

Have you tried doing



gl.glReadBuffer(GL2.GL_NONE);

at the end of this logic is case the detach is not really taking effect until then?

Thanks for the suggestion; I did try gl.glReadBuffer(GL2.GL_NONE) before and/or after the “detach texture” line. It has no observable effect.

Also, I tried running this project in Windows 7 (with Catalyst version 12.3), and the same thing happens–using a previously-attached texture yields about 50 fps, and using a different texture yields about 180 fps (for some reason running this project in Windows has always gotten much higher frame rates–I haven’t tried figuring out why and anyway it’s probably unrelated to this issue–but it’s interesting that both drop to around the same frame rate).

Does it matter what raster image you use as the texture?

It a bit difficult to root the performance problem but from what you describe you may have this situation:

  1. Render to texture 0
  2. Switch to another FBO and readpixels from texture 0

The (2) will have to flush the previous FBO which means that the readpixels will stop and wait until the rendering to the texture 0 is finished. A good way to avoid this is to put other computation intensive tasks between (1) and (2).

Hope this is relevant and that will help you.

[QUOTE=Godlike;1243691]It a bit difficult to root the performance problem but from what you describe you may have this situation:

  1. Render to texture 0
  2. Switch to another FBO and readpixels from texture 0

The (2) will have to flush the previous FBO which means that the readpixels will stop and wait until the rendering to the texture 0 is finished. A good way to avoid this is to put other computation intensive tasks between (1) and (2).

Hope this is relevant and that will help you.[/QUOTE]

Hmm, I’m still thinking about this answer–it doesn’t quite match up with what I’m doing, but maybe you are on to something. Just to be clear, I’m never rendering to a texture which is attached to an FBO for reading. Also, attaching the texture to the FBO happens only initially, and is never done again.

Sorry, I am not completely sure what you mean by this.

Try using two FBOs: one with the normal texture attached and one with a renderbuffer of the same format attached. Don’t call glReadPixels on the texture-FBO. Instead, use glBlitFramebuffer to blit the image into the renderbuffer, then use glReadpixels on that instead.

I meant trying something like skynet suggested or just attaching a different texture with a different format.

I see. Ultimately I will end up rendering the original texture onto a new texture, and then read the pixels from the new texture. This will sidestep the issue (since I will never render using the new texture), and allow me greater flexibility in how the thumbnail is generated. Even so, I’d like to get to the bottom of why the issue is happening. Something is going on that I don’t understand at all, and that’s never a good thing!