pouët.net

Go to bottom

weird (?) behaviour of glreadpixels with FBOs

category: general [glöplog]
 
Hi all,

I have a question for you which the internets cannot answer. FBOs and glreadpixel: what's the deal ?

On some machines (XP / ATI) it works at full speed, on others (Vista, NVidia) a readpixel operation of around 1m pixels (rgba8) takes over a second !

Is there any other way to use multiple render targets and still get a decent readpixel (I have to read it as uchar*) speed everywhere ?


added on the 2009-07-28 10:38:38 by Navis Navis
hm... glReadPixels is made to read pixels from the color buffer, not from FBOs. To read the content from and FBO/texture you can are supposed to use glGetTexImage( textureID, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer ); with the ID of the texture you rendered to (not the one of the fbo)... Try and let's see if it gets faster like that...

Also, in Vista is (was, few months ago) to recommended to have only one FBO for all the engine, keep it always bound (until the very last color buffer rendering) and simply attach/dettach the render buffers and textures to it, instead of having different FBOs (for each render pass) and bind them, the difference is dramatic.
added on the 2009-07-28 11:25:24 by iq iq
also, maybe using two alternating buffers can help (even frame: buffer1, odd: buffer2)?
added on the 2009-07-28 11:29:21 by arm1n arm1n
Quote:

[12:20] <daffy> there's a new opengl thread on pouet, and it hasn't turned into a directx-v-opengl flame war yet
[12:20] <daffy> and noone has even mentioned linux!
[12:20] <parapete> i'm gonna troll it


Don't use glReadPixels.
Regarding FBO, what is your own policy ?
- having only one FBO as suggested by iq
- having one FBO per size of render texture
- having one FBO for each render texture (seems to be awfully slow though)
added on the 2009-07-28 13:28:58 by ponce ponce
thanks to all. I'll check with my code tomorrow. Seems like it is less hassle to do render to framebuffer twice ... :-(
added on the 2009-07-28 13:58:40 by Navis Navis
iq: That's not correct. glReadPixels reads from the currently bound framebuffer.
added on the 2009-07-28 14:25:47 by kusma kusma
Navis: What are you trying to do?
added on the 2009-07-28 14:28:02 by kusma kusma
a very simple case of:

Render something (very trivial, under normal conditions it should give over 100fps) into two buffers, then read these rgba8 buffers (or part of them) as uchar* in system memory. The size of window is, lets say, 800x600 and there is no need for multisampling.
added on the 2009-07-28 14:40:01 by Navis Navis
OK. I got confused by your statement about rendering twice, and was wondering if you were trying to copy between the back-buffer and front-buffer or something instead.

Anyway, yeah. glReadPixels to client memory isn't fast, but it's not supposed to be THAT slow. Are your FBO and your readback format the same? Do you read back the full buffer? Is the buffer-width (in bytes) dividable by 32? Also make sure that the FBO isn't multisampled even if you don't use it.
added on the 2009-07-28 14:59:41 by kusma kusma
watch out when you clock glReadPixels(): use a glFinish() before it and then measure glReadPixels(). the gl pipe is done so that all your previous GL drawing operations may actually be validated and drawn during glReadPixels(), which asks for all operations to be done on the fbo .
added on the 2009-07-28 15:13:07 by krabob krabob
...except that glFinish does a whole big wad of nothing in some implementations :)
added on the 2009-07-28 15:30:21 by kusma kusma
I haven't got the code in front of me right now, but:

thanks for the "dividable by 32" tip. It seemed to make some difference when I was changing window size. FBOs are not multisampled. FBO and readback format are the same, although I've read something about rgba and bgra, which I'll try tomorrow. glFinish did nothing to improve speed.
added on the 2009-07-28 15:51:48 by Navis Navis
Also aligning the system memory buffer to multiples of 16 (32? 64?) bytes could help depending on how the copying is done...
added on the 2009-07-28 16:12:20 by raer raer
kusma, ok, thx for the info.

Still I would try glGetTexImage, who knows, drivers behave unpredictably sometimes :)
added on the 2009-07-28 16:46:20 by iq iq
little known fact: agp stands for asymmetric graphics port;)
added on the 2009-07-28 16:46:50 by 216 216

login

Go to top