PDA

View Full Version : What must be done when glUnmapBufferARB fails ?



kettch
09-02-2008, 02:58 AM
Hi,

I've had some problems with buffer corruption for the past few days, and only recently managed to narrow the problem to glUnmapBufferARB returning GL_FALSE. I've searched for what must be done in this case. Some say that the "data must be resubmitted". I must admit I have no idea what this could mean. Here's what I tried so far :

- After glUnmapBufferARV fails, I reset the data with glBufferDataARB with a NULL pointer. My code fails later with a glDrawRangeElements throwing a GL_INVALID_OPERATION (leading me to believe the buffer is still mapped)
- The same, with another glUnmapBufferARB after the glBufferDataARB call. Unfortunately, glUnmapBufferARB still returns GL_FALSE.
- Just another glUnmapBufferARB without a glBufferDataARB; it fails again.

With these results, I can't understand what I'm supposed to do... If I don't do anything, it will fail later when I try to draw with that buffer. If I try unmapping again, it fails again.

More than that, I just can't understand how this could fail ? The only possible cases specified in the VBO spec are context resizing, and some other, that don't happen at all in my app. This error happens in my code when a second thread with a second context (shared to the first on the main thread that is doing the rendering) is loading geometry in the VBOs. From the VBO spec again, this is a case that should work, even without locking the threads so that they don't work together, which I do anyway...

Anyone got any insights on this ?

Thanks

yooyo
09-02-2008, 09:11 AM
Can you post piece of code. Is this context sharing have some other issues? In my practice, context sharing works the best only if app create two RC's share objects and then do first wglMakeCurrent call.

In case of VBO, you can map buffer from render thread, pass pointer to loader thread, do something usefull in render thread (draw progressbar :) ) and wait until loader thread signal when its done. Then, from render thread, unmap buffer and use it.

kettch
09-02-2008, 09:52 AM
Can you post piece of code.

That would be quite difficult... I'll see if I can strip it to something simple, but the nesting of VBO + threads + shared RCs make it difficult to present in a forum ;)


Is this context sharing have some other issues? In my practice, context sharing works the best only if app create two RC's share objects and then do first wglMakeCurrent call.

Not sure I understood correctly. I have no other noticeable problem. Textures are working fine when loading from that second RC, the only problem comes from VBO corruption.
Since I have only one RC for each thread at most, only one of them is current at any time for a given thread.


In case of VBO, you can map buffer from render thread, pass pointer to loader thread, do something usefull in render thread (draw progressbar :) ) and wait until loader thread signal when its done. Then, from render thread, unmap buffer and use it.

The whole point of using a loader thread is to be able to load data without affecting the rendering thread too much. What you're presenting is actually what happens, but the progress bar, in my case, is a rendering of a "loading" object. This way of doing things works flawlessly on Mac OS X (an Apple guy said that on OS X's imp of OGL, VBO data was never corrupted, btw...)., but it doesn't on Windows, and I see no clear reason why.

yooyo
09-02-2008, 03:39 PM
So.. from loader thread you map VBO and copy data, while in render thread you are using that VBO as source? wow!

From VBO spec:

How is synchronization enforced when buffer objects are shared by
multiple OpenGL contexts?

RESOLVED: It is generally the clients' responsibility to
synchronize modifications made to shared buffer objects. GL
implementations will make some effort to avoid deletion of in-use
buffer objects, but may not be able to ensure this handling.



btw... can you tell us which hw, os & driver you use?

Jackis
09-03-2008, 02:21 PM
For me, I got glUnmapBuffer() with GL_FALSE result only if I wrote more bytes, than buffer was created for with preceeding glBufferData call.

kettch
09-04-2008, 06:09 AM
So.. from loader thread you map VBO and copy data, while in render thread you are using that VBO as source? wow!

From VBO spec:

How is synchronization enforced when buffer objects are shared by
multiple OpenGL contexts?

RESOLVED: It is generally the clients' responsibility to
synchronize modifications made to shared buffer objects. GL
implementations will make some effort to avoid deletion of in-use
buffer objects, but may not be able to ensure this handling.



btw... can you tell us which hw, os & driver you use?

I believe that's actually the problem... I noticed a section in the VBO spec but didn't notice a detail : they specify that you can map a VBO from a thread and render from a VBO on another thread, but that they should be different VBOs.
I'll have to find a solution to go around that...