PDA

View Full Version : Vertical retrace interrupt?



frink
03-12-2003, 08:33 AM
After issuing a swap buffers command, I call glFinish(), which doesn't return until the vertical retrace. My only problem is that glFinish() ties up the processor, not allowing any other threads to execute. Does anybody know of a blocking OpenGL function call that will give up the processor to another thread until the vertical retrace occurs? I don't want to estimate the vertical retrace by continually checking the time.

jwatte
03-12-2003, 07:13 PM
There ain't no such thing. The implementation specifics of glFinish() are not defined; they're up to the driver. Trying to do it with events or any other "nice" synchronization primitive will incur all the jitter penalty of the Windows scheduler, which may throw dozens of milliseconds of jitter into the mix. When the screen redraws every 15 milliseconds, you really don't want to be doing that. At least not if your business is out-doing your competitors in various benchmarks.

rgpc
03-12-2003, 07:44 PM
Is it valid to call glFinish() after you've swapped buffers? (Personally I don't call glFinish at all - which might be frowned upon?)

How do you know that glFinish() doesn't return until the retrace? Could it be as simple as you have VSync set to always on? If so check your driver settings and set it to always off (as an initial test).

If that's your problem look at wglSwapIntervalEXT() (WGL_EXT_Swap_Control)

HS
03-13-2003, 09:29 AM
glFinish() blocks until every pending operation in the pipeline is completed. In your case calling it is completely unnessary.

Just swap the buffers and your are set.

In a multithreaded app you must call glFlush() in every other thread rendering to that context prior to swapping buffers.

SwapBuffers will call glFlush() for the current thread for you.

Relic
03-14-2003, 12:52 AM
>>In a multithreaded app you must call glFlush() in every other thread rendering to that context prior to swapping buffers. <<

Actually glFlush() is not enough. You must use glFinish().

HS
03-14-2003, 12:35 PM
Originally posted by Relic:
Actually glFlush() is not enough. You must use glFinish().

Why that?

If I have to do call glFinish() every frame it would render the whole concept of a 'pipeline' useless.

I can only think of some rare cases where you have to call glFinish() at all (multithreaded or not).

a.) You need to be sure that all the rendering is done before you save/print/decorate/whatever.

b.) You need to make sure that all the state changes issued by different threads are applied (since doing state changes from different threads is a 'no-no' anyway, its kind of a mood point)

Right now, I only call glFinish() before the application gets terminated so I can make sure that I dont leave any resource leaks behind (maybe a little to much but I like to live on the save side).

Relic
03-17-2003, 04:03 AM
Right, in a single thread program there's no need to call glFinish normally (exceptions are benchmarking or GDI interaction).

I was only referring to multithreading.
In a multithreaded app you need to make sure that all threads not doing the swap have FINISHED rendering before one thread accesses the framebuffer. That can be anything like SwapBuffers, glCopyPixels, etc.

A glFlush only means that the commands which have not been processed so far are started and finish after a finite amount of time (== you don't know when => insecure to swap).
Each slave rendering thread needs to call glFinish, signal in a mutex that it's done and only then the main thread may swap buffers (no need to call glFinish in the main thread, of course).
Doing the swap earlier can result in missing geometry.

dorbie
03-17-2003, 05:22 AM
Another exception is if you care about latency.