PDA

View Full Version : glReadPixels very slow on 6600gt



powermax
06-18-2008, 06:38 PM
I tested the same code below on nvidia 6600gt and nvidia 8600gt.
The first took 400 ms and the second 6 ms for an 256x256 image.
Is this normal?



...
int* ids = new int[m_aantalPixels];
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
glTime.restart();
glReadPixels(0,0,m_width,m_height,GL_RGBA,GL_UNSIG NED_BYTE,ids);
cerr << "Elapsed time: " << glTime.elapsed() << "\n";
glReadBuffer(GL_BACK);
...


thx

-NiCo-
06-19-2008, 01:29 AM
Are you sure your timer code is accurate and takes the asynchronous nature of the OpenGL API into account?
If you want some more reliable timer results, I suggest you use:



...
int* ids = new int[m_aantalPixels];
glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
glFinish();
glTime.restart();
for (int i=0;i<1000;++i)
glReadPixels(0,0,m_width,m_height,GL_RGBA,GL_UNSIG NED_BYTE,ids);
glFinish();
cerr << "Readback time: " << glTime.elapsed()/1000.0 << "\n";
glReadBuffer(GL_BACK);
...

-NiCo-
06-19-2008, 01:37 AM
One other thing. I noticed you used glReadBuffer(GL_COLOR_ATTACHMENT1_EXT) and glReadBuffer(GL_BACK)
without switching from your application created FBO to you window system provided framebuffer.

I'm not 100%, but I think you can only use GL_COLOR_ATTACHMENTi_EXT for application created FBOs and GL_FRONT,GL_BACK,... for your window system provided framebuffer.

Do you get any GL errors?

powermax
06-19-2008, 11:48 AM
Are you sure your timer code takes the asynchronous nature of the OpenGL API into account?
I'm just using QTime (Qt) as timer, so probably not?
But my program goes very slow thanks to only these lines of code. When i remove them, it runs fast.

I tried your suggestion code to get an average time and it gave me: Readback time: 180.191 ms.

The code below gives no error in the first two checkErrors.
The last checkError gives: Error: invalid enumerant.



glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
checkError();
glReadPixels(0,0,m_width,m_height,GL_RGBA,GL_UNSIG NED_BYTE,ids);
glFinish();
checkError();
glReadBuffer(GL_BACK);
checkError();

-NiCo-
06-19-2008, 02:20 PM
That's because GL_BACK is not a valid enumerant for an application created FBO like I said in my previous post.
Have you tried using GL_BGRA instead of GL_RGBA?

powermax
06-19-2008, 04:25 PM
I have tried it now, but it doesn't seem to make a difference.
I tried these combinations:


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glReadPixels(0,0,m_width,m_height,GL_BGRA,GL_UNSIG NED_BYTE,ids);




glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
glReadPixels(0,0,m_width,m_height,GL_BGRA,GL_UNSIG NED_INT_8_8_8_8_REV,ids);

dletozeun
06-20-2008, 01:20 AM
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glReadPixels(0,0,m_width,m_height,GL_BGRA,GL_UNSIG NED_BYTE,ids);




glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
glReadPixels(0,0,m_width,m_height,GL_BGRA,GL_UNSIG NED_INT_8_8_8_8_REV,ids);


What do you expect that this code do?

If you want to copy the current read buffer into a texture use glCopyTexSubImage2D instead of glReadPixels

powermax
06-20-2008, 11:27 AM
First I render to 2 fbo textures with a shader. One fbo texture is used for reading back values from the gpu to the cpu with glReadPixels. This works on my other gpu in 6 ms and the values i get back are correct. I use them in my program on the cpu. The second fbo texture is used in rendering to the framebuffer.

The glTexImage2D line is located where the fbo and textures are initialy created. The glReadPixels line is located before fbo->unbind.

Dj3hut1
06-25-2008, 12:10 AM
Hello,

there are some tips in the OpenGL FAQ (http://www.opengl.org/resources/faq/technical/performance.htm#perf0070) to increase the performance of glReadPixels.

dj3hut1