Thanks for the feedback Overmind and k_szczech.
Overmind’s two use cases are valid for some scenarios, but things are often more complicated…
You have uploaded the texture yourself. Then you don’t need to get it back, you already have it. The GPU memory is not a place to backup your data, keep it in RAM, and you won’t need to read it back.
True, unless there are many textures. Keeping an extra copy of them all in client memory simultaneously will bloat the application unacceptably. In my case, I’m tolerating the read overhead to avoid this.
You have rendered into the texture. Then you already have bound it to an FBO, no harm in just making a ReadPixels (into an PBO, if you’re concerned about parallelism).
This use case is valid for code that continually renders to a texture and reads back immediately. What about code that renders to a collection of textures infrequently compared to the number of times it samples (reads during rendering) the textures. The pathological case is write once, sample (render) many times…
A texture attached to a framebuffer object must be detached before it can be sampled (rendered). So to read a subimage from each texture one needs to[ol][li]bind a framebuffer objectread the texelsunbind the framebuffer object[/ol][/li]That’s assuming one uses one framebuffer object per texture. For a reading a subset of a large collection of textures it may be wiser to use a small pool of framebuffer objects and wear the additional costs of attaching and detaching textures too.
If one needs to read from more than a few textures at once, the overhead starts to add up. Having said that, I haven’t benchmarked the relative costs of the binds/unbinds and the read.
Note that even using pixel buffer objects won’t necessarily increase parallelism much since only one framebuffer object can be active at a time. In contrast, as long as the textures being read aren’t being rendered to, there is much better scope for parallel GetTexSubImage calls in progress while rendering continues.
I think there is a pattern here
a) Things that you rendered are read by ReadPixels.
b) Textures are not a general purpose data store. Buffer objects are used for that.
Or more completely:
[list=A][li]TexImage* and TexSubImage* for writing TexturesGetTexImage ([i]and maybe GetTexSubImage[/i]) for reading Texturesmany OpenGL calls for writing to DRAW_BUFFERSReadPixels for reading READ_BUFFER[/LIST][/li]If the OpenGL state happens to be set correctly, C can also write to textures as a side effect.
For the record: IMHO the GetTexImage function should be removed as well.
I’m all for the “Lean and Mean” approach, but consistency is critical to a good API too.
Functions that set OpenGL state usually have a corresponding Get function. For TexImage*, GetTexImage* seems a better counterpart than a series of calls to configure, bind, read and unbind a framebuffer object.
Conversely, how would you feel about replacing TexImage* with a series of calls to configure, bind, write and unbind a framebuffer object? I’m not being altogether serious here, but it’s what consistency demands when applied ruthlessly to your suggestion.
Of course if the new versions of OpenGL take this buffer-based approach, but with a terse, low-overhead and consistent API, I’m all for it.
As for ‘compressed’ version it won’t be that easy, since compression algorithm can work on block of pixels and therefore you will not be able to read any fragment of texture you want.
I’d guessed that, thus my more tentative suggestion with the compressed version. I thought that I’d ask anyway, in case it was easy for the implementors to stream though existing texture access functionality.
My original post was more to draw attention to a minor inconsistency in the existing spec than to demand a solution to my particular problems. Hope this discussion helps those working on the new specs.