I'm geting a GL_OUT_OF_MEMORY error after calling glReadPixels on a non-multisampled 15000x11235 (642MB) "complete" FBO. GL_OUT_OF_MEMORY is not one of the documented errors that glReadPixels can generate. From my perspective, all of the necessary memory is preallocated, so this error is very mysterious. Would someone please explain why this is happening? I'd like to put an appropriate workaround in my code, e.g., on ATI cards use half of the GL_MAX_RENDERBUFFER_SIZE and on NVIDIA cards use the full value.
This error happened with 32-bit WIndows Vista on a 8GB machine that has a 2GB Radeon HD 7850 and tested with both the Catalyst 12.10 and the 12.11 beta drivers.
Thank you for your time,
Actually, GL_OUT_OF_MEMORY can be generated at any time. Checking the spec, v.4.3, p.16, it says:
Several error generation conditions are implicit in the description of every GL command.
The transfer you are attempting is very large, even on a machine with 8G of memory and a high end graphics card. I suspect that you are squeaking in just under a limit on NVIDIA and just over on AMD. It is likely that some internal allocation has failed in the driver and it can't allocate some temporary buffer to make the transfer. We'll see if there's something we can do in the driver to break such large transfers up.
In the meantime, you could try calling glReadPixels multiple times to transfer regions of the framebuffer. This could get you running again without needing to sacrifice framebuffer resolution.
Thank you for your response.
Thinking about this some more, I see how the driver might allocate a temporary buffer to massage the data format from the FBO's native format to the format requested by glReadPixels. In my case, the FBO was GL_RGBA8, and the glReadPixels format was GL_RGB (because the user wanted to save an image without alpha).
So my question changes to: Are there formats or format and type combinations that won't use a temporary buffer? For example, if I changed glReadPixels to use GL_BGRA/GL_USIGNED_BYTE, would that avoid this problem?
gregcouch wrote:So my question changes to: Are there formats or format and type combinations that won't use a temporary buffer? For example, if I changed glReadPixels to use GL_BGRA/GL_USIGNED_BYTE, would that avoid this problem?
It's very tough to say - a comprehensive list of format combinations that won't allocate any temporary storage would be difficult to build. In order to reduce the chances that you'll need a temporary buffer, my suggestions would be:
Also, to reduce the size of any temporary buffers such that their allocation is more likely to succeed, read in chunks rather than reading the entire framebuffer in one go.