Imagination PowerVR SDK Blog

glBufferData and context sharing

#1

Greetings,

I had the following plan for implementing an asynchronous buffer upload in an OpenGL program:

  • Create shared contextes. Render thread has one, worker thread has one.
  • Worker thread calls glBufferData. Each call allocates and uploads data completely fresh.
  • Render thread probes buffer upload state using fences. Once finished, it starts using the buffer for drawing.

My question now is: Will the glBufferData in the worker thread still affect the performance of the main render thread in some way even if the render thread does not use the unfinished buffer yet?

My fear is that commands from different contexts still end up in the same pipeline and that the syscall emerging from glBufferData will block the commands from the render thread. Or that a swapbuffer on the render thread causes a finish on the worker thread.

Regards

#2

Hi,

just to save a copy I’d use glMap(…) functions instead of glBufferData.

I don’t think glBufferData would affect performance of the main thread IF nothing depends on it in the main thread. If you have a draw call that needs that buffer it will wait.

OpenGL Insights has a great chapter on this topic: https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf

You can use our PVRTune profiler to identify these sync issues. You’ll need an NDA though. You can contact us at devtech@imgtec.com to obtain one.

bests,
Marton

#3

The reason why I use glBufferData is because allocation and initialization is at the same spot in the worker thread so I assume it didn’t matter.

Isn’t PVRTune part of the SDK?

#4

Hi,

glBufferData is not really optimal in any case these days as it has to allocate a fresh buffer every time, make sure that data is copied and only then it can return. It potentially blocks for long.
I’d just recommend using glMap(…)

PVRTuneDeveloper comes with our SDK installer. PVRTuneComplete (which is the one you need) has to be obtained separately.

bests,
Marton

#5

But I need glBufferData anyways because I have to allocate memory and GLES doesn’t seem to have glBufferStorage yet. And since it’s in a worker thread, it shouldn’t block the main render thread, right?
I assume that you think I’m pooling things and want to reuse memory as much as possible.

#6

Hi,

oh right, well yea in that case only use it for allocation and suballocate (well map and manage) memory however you need it.

bests,
Marton

#7

Ok, I have a follow up question regarding glWaitSync. If the upload thread starts a large upload that takes say 500ms and then calls glFenceSync and the render thread uses the buffer immediately won’t the rendering still be delayed / stutter by ~ 500 ms even if the render thread is not?

#8

Hi,

glWaitSync returns immediately, but the GL server thread is blocked until the sync object created using glFenceSync is signalled. I think rendering would be delayed by 500ms in this case, but your application could continue working on all threads.

bests,
Marton

#9

So if I have other stuff that I could render immediately then the correct way to handle this would be to probe the buffer handle with glClientWaitSync and not issue render calls for buffers that haven’t been uploaded yet, right?

#10

I think you can just use glGetSync to query the status of the sync object (signalled or not). Yes if not signalled you can issue commands for other stuff.

1 Like
#11

glGetSync doesn’t flush or finish like other get functions, does it?

#12

Hi,

no it does not.

Marton

1 Like