Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to tell whether an OpenGL operation is finished?

OpenGL functions are defined as though they operate synchronously. But rendering functions (and others) will often be executed asynchronously by the GPU. OpenGL will effectively hide this: if you do something that requires the results of an operation (such as reading from a framebuffer that has been rendered to), OpenGL will stop CPU operations until the GPU has reached that point.

That is functional, but hardly ideal for performance, since the CPU basically blocks until the GPU is done. Is there a way to determine if a particular operation has completed, so that you know that a dependent operation will be executed without so much CPU blocking?

like image 347
Nicol Bolas Avatar asked Aug 13 '13 19:08

Nicol Bolas


People also ask

Are OpenGL calls blocking?

OpenGL calls will only block, if the result of the call modifies client side memory and depends of data generated by previous OpenGL calls. In other words, when doing OpenGL calls, the OpenGL implementation internally generates a dependency tree to keep track of what depends on what.

Is OpenGL asynchronous?

With client memory, it must copy all of the vertices out of the client-side arrays. All of this means that OpenGL is a very asynchronous renderer, even if it is defined synchronously.


1 Answers

Yes, there is. Assuming you have access to OpenGL 3.2+ or the ARB_sync extension.

If you want to know when a particular command has finished, you can insert a "fence" sync object into the command stream immediately after issuing that command. This is done with the glFenceSync function.

You must store the pointer returned by this function. With that pointer in hand, you can query whether the fence has completed by checking whether the fence is signaled with the glGetSync function. Like this:

GLint isSignaled = 0;
glGetSync(syncObj, GL_SYNC_STATUS, 1, NULL, &isSignaled);

if(isSignaled == GL_SIGNALED)
{
  //Prior commands have completed.
}
else
{
  //Not done yet.
}

If you run out of other stuff to do, you don't need to wait for the sync object to finish; you can just do whatever OpenGL process you wanted to do. That will induce the CPU block for you.

Once you're finished with the sync object, you must delete it. Use the glDeleteSync function to do so.

like image 144
Nicol Bolas Avatar answered Sep 23 '22 06:09

Nicol Bolas