PDA

View Full Version : How to copy texture1 to texture2 efficiently?



rtrobin
04-19-2013, 01:16 AM
I want to copy texture1 to texture2. How can I do this efficiently?
The most stupid method is copying tex1 data from GPU to CPU, and then copy CPU data to GPU.
The stupid code is as below:


float *data = new float[width*height*4];
glBindTexture(GL_TEXTURE_2D, tex1);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data);
glBindTexture(GL_TEXTURE_2D, tex2]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);

As I know, it must exist a method that supports data copying from GPU tex to GPU tex without CPU involved. I consider about using FBO that rendering a tex1 quad to tex2. But somehow I think it is still naive.
So I post here for a high efficient way.
Thanks a lot.

thokra
04-19-2013, 02:17 AM
I will offer two techniques to achieve this:

1) Create a FBO and attach texture2 as color attachment. Render a quad the size of texture1, sample texture1 and output samples to the render target (i.e. texture2).
2) Create a FBO and attach both textures as COLOR_ATTACHMENT0 and COLOR_ATTACHMENT1. Set the draw buffer to COLOR_ATTACHMENT1 and the read buffer to COLOR_ATTACHMENT0. Blit it!

Both methods run entirely on the GPU. You'd have to test which one performs better but if you only copy a single texture per frame it's probably negligible anyway.

Having actually never really used PBOs before, I will say that you probably can achieve something similar with PBOs too.

mobeen
04-19-2013, 02:17 AM
Search for existing or similar threads on the forum for e.g. a simple search on opengl forums returned this
http://www.opengl.org/discussion_boards/showthread.php/165754-How-to-copy-data-from-one-texture-to-another

Google search gave me these
http://www.gamedev.net/topic/398917-duplicate-texture/
which suggests using FBO instead of glGetTexImage as the latter downloads pixel data from VRAM to system memory whereas the FBO method copies data within VRAM using glCopyTexSubImage2D.

This thread http://forums.tigsource.com/index.php?topic=3160.0 suggests using pixel buffer object with gl[Copy]TexSubImage2D function.

PS: Double posting is not allowed here
EDIT: Oops thokra posted just in time with similar answer, follow his reply first.

thokra
04-19-2013, 02:19 AM
PS: Double posting is not allowed here

+1. Please read the forum posting guidelines! Don't cross-post (i.e. posting the same topic in different sub-forums)! Could a mod please delete the corresponding topic in advanced?

rtrobin
04-19-2013, 02:30 AM
Thanks!! I am sorry for my cross-post. I am looking for the "delete" button for my another post. How can I delete my post?...

thokra
04-19-2013, 02:41 AM
Edit Post -> Delete - You can use "Cross-Posting" as reason for deletion.

randall
04-19-2013, 02:49 AM
In OpenGL 4.3 you have glCopyImageSubData.

rtrobin
04-19-2013, 04:00 AM
Edit Post -> Delete - You can use "Cross-Posting" as reason for deletion.
Sorry that I seems super-numbed today, maybe because my lack of sleep recently... I find I could "Edit Post -> Delete" my last post in that thread, but I couldn' t delete whole thread. Does anybody have supervisor identity to delete my post?
1013

aqnuep
04-19-2013, 07:41 AM
There are a couple of options (in order of preference):

1. Use ARB_copy_image to copy between the textures. The images must be format compatible or should have identical internal formats. Also, you might need GL 4.3 to have this extension available.
2. Use NV_copy_image to copy between the textures. This extension is widely supported for a while. The images must have identical internal formats.
3. Use glBlitFrameBuffer. Attach the source texture to one FBO, bind the FBO as READ_FRAMEBUFFER, attach the destination texture to another FBO, bind the FBO as DRAW_FRAMEBUFFER, call glBlitFramebuffer, done. With this approach you can also stretch the texture and you also don't need identical internal formats, though it might be somewhat slower.
4. If no other option available, use a PBO and use GetTexImage then TexSubImage. It's still a 2-step copy, but it's faster than if you would transfer to client memory, as PBOs could be in fast GPU memory.