DMA via PBO, asynchronous loading of textures

Hello guys,

I want to create a PBO and then use the pack/unpack(correct me if that’s wrong) methods to transfer texture-data from the main memory into the graphics memory. This should be possible via Direct Memory Access(DMA), which should ensure a responsive program with asynchronous loading (rather, transferring).

In short I want to:

[ul][li]Load an image into main memory[]create PBO []transfer pixel data into PBO while rendering a loading [/li]animation [li]use pixel data to display textures or do whatever was intended in the first place [/ul] [/li]
The hard part is creating the PBO and transferring pixel data using DMA…can someone please post some code to help me get started? (if anyone has java code, that’s even better!)

I know I need to use glGenBuffersARB()…but I will need alot more I guess :smiley:

Have you tried this page OpenGL Pixel Buffer Object (PBO) . Its the best tutroial on how to load your bitmap via DMA using PBOs. It helped me out when I use it to update the texture when I’m streaming video.

The hard part is creating the PBO and transferring pixel data using DMA

No, it isn’t. If you can transfer pixel data without PBOs (ie: normally), then you can transfer pixel data with PBOs. It’s really very simple.

You create a Buffer Object, just like you normally would if you were making vertex or index buffers. Except that you bind it to the PACK or UNPACK_BUFFER bindings when you want to call glBufferData on it. Then you fill that buffer using whatever buffer object filling command you like. You put into it exactly the same information you had in the pointer you specify.

If your texture upload code looked like:


//before upload.
void *pData = GetTextureData(...);

//perform upload
glTexSubImage2d(..., pData);

Then now it looks like:


//before upload
void *pData = GetTextureData(...);
glBindBuffer(GL_UNPACK_BUFFER, bufferObj);
glBufferSubData(GL_UNPACK_BUFFER, size, pData);

//perform upload
glBindBuffer(GL_UNPACK_BUFFER, bufferObj);
glTexSubImage2d(..., (void*)0);

Ok, so afaik., glTexSubImage2d() replaces a region of a texture with new data, but how will I know when the DMA has finished uploading the texture? And what problems will this bring if I try to use the data before it finishes?

(I haven’t had experience with VBO’s, thats why I find this a bit tricky)

how will I know when the DMA has finished uploading the texture?

You could set a fence. However, I’m not sure how the interaction between fences and async texture uploading works. Normally, fences are defined based on when a rendering command completes. And I’m not sure that texture uploads count as “rendering commands.”

In general, you don’t know. And you usually don’t need to. Just start the upload at the earliest time you can, and don’t use the texture until the latest possible time after this.

And what problems will this bring if I try to use the data before it finishes?

None. Asynchronous texture uploading is an optimization that the use of PBO allows. However, an implementation is not required to do it. Nor is an implementation forbidden from doing async uploads when PBOs aren’t being used. Some implementations copy the buffer you give glTexImage* into internal memory and do an async upload from there. So your best bet with PBOs is to map them and write the image data directly to them.

It is the job of the OpenGL implementation to properly synchronize rendering commands with things like texture uploads. If the driver wants to have async uploads, then it must ensure that any rendering call that could use the texture will wait until that texture upload has completed.

//before upload
void *pData = GetTextureData(…);
glBindBuffer(GL_UNPACK_BUFFER, bufferObj);
glBufferSubData(GL_UNPACK_BUFFER, size, pData);

//perform upload
glBindBuffer(GL_UNPACK_BUFFER, bufferObj);
glTexSubImage2d(…, (void*)0);

So this is for loading texture into memory ?
Now, How can i bindtexture from PBO ? .) thank you