Advanced control of vertical sync.

I’ve been looking at Direct3D and see that it has some very advanced features regarding the control of vertical sync.

D3DPRESENT

More importantly when “D3DPRESENT_INTERVAL_ONE” is used, the CPU is able to idle properly with both the current ATI and nVidia drivers.

OpenGL has terrible problems at the moment with CPU usage, especially with the ATI drivers. This is important when OpenGL is used on the desktop with other applications, to preserve system resources.

This is important cause OpenGL is not just a 3D game API, it is also for desktop and internet browser applications. And OpenGL is perfectly suited to OpenGL graphics on the web cause it should work everywhere.

Therefore I think it is very important to have advanced control of vertical sync, especially to enable applications idle properly and minimize their CPU usage.

That means proper idling in the OpenGL drivers as part of the OpenGL standard, if the developer requires to do so.

At the moment this is not possible with OpenGL and Direct3D is way ahead of this already. This is very fundamental and should of been implemented years ago, cause the latest OpenGL 2.0 cards are very expensive. And who knows when this could be standardised.

The current workaround is to use “Sleep”, but the timings are too coarse. And if the timing resolution is increased, the CPU usage then greatly rises.

At the moment I am being forced to consider Direct3D, because it has much better support for these features. But unfortunately Direct3D will not work on every platform.

Uh, How is the D3D method different from:
http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_swap_control.txt

or on Linux
http://oss.sgi.com/projects/ogl-sample/registry/SGI/swap_control.txt
(not sure about linux - may be a better way now -it is from 1995!)

(make sure that vsync is not being forced off in the drivers first tho!)

or are you saying there should be a platform independant way of doing this? (there probably should, but it is a windowing function)

(or are you saying something completely different?)

I am aware of “wgl_swap_control” but it does not prevent very high CPU usage in the driver (especially ATI’s) when vertical sync is enabled.

We need a standardised way to prevent the CPU polling for the next frame when vertical sync is enabled.

The best way to do it is to allow the CPU to idle when waiting for the next frame to be rendered.

Having proper control like this in the OpenGL standard will protect OpenGL desktop applications from using high amounts of CPU.

Being able to properly control CPU usage will allow better multitasking on the desktop and will help promote OpenGL in the long term.

I still don’t understand what you want the OpenGL spec to do. I see nothing in the D3D spec about preventing CPU polling. I also still don’t understand what the difference between the swap_buffers extension is to D3D. (besides one being a standard part of the API)

I also don’t see how the OpenGL spec can mandate how a driver uses it’s CPU time. (other than “this operation is intended to be lightweight” etc)

Is this a problem on Nvidia cards? If not, it seems your complaint is with the ATI driver guys.

Edit:
I just ran some tests on my Nvidia 6800, the CPU usage is much lower (>50%) when using swap_hint of 1 in my app.

I fail to see where the D3D api provide better control on CPU usage.

I see that only as a driver implementation problem,
and on my gf 6800le win2000 forceware 77.something I do see the cpu idling when using OpenGL-controlled vsync.

I have an ATI X800 and when I run NEHE’s lesson 02 even using the OpenGL wgl_swap_control v-sync extension and the control panel settings to vertical sync always on. I do get vertical sync but also maximum CPU usage.

This does not happen with an nVidia card.

The vertical sync is clearly working with ATI but there is the high CPU usage side effect from it.

Therefore is this a driver fault with ATI’s drivers? I have noticed this with all their drivers including the latest?

Is high CPU usage acceptable? Or is it a fault?

Does the OpenGL spec say anything about CPU usage or can the driver writers do as they please as long as there is vertical sync?

I would like to see less use of the CPU with OpenGL in the future.

I have also submitted driver feedback to ATI via their website about this, but I have had no response from them.

There is a guy on these forums known as Humus that works for ATI. Email him and you will probably get a prompt response:
http://www.humus.ca/index.php?page=Contact

Note that he is currently on holidays for a few more weeks.

For applications that aren’t games, they should just render when a WM_PAINT, and whatever the equivalent is on other OSes, is received.

Yes, ATI has that issue. This isn’t a OpenGL problem. ATI chose to code their drivers that way.

I have also submitted driver feedback to ATI via their website about this, but I have had no response from them.
That’s normal. It may take a very long time or they might never reply unless you are a big house developer.

Looks like there are two ways to go about implementing vertical sync and nVidia and ATI do it differently to each other.

NVIDIA’s technique allows the CPU to idle and ATI’s do not. But there are two different techniques being used here for the same OpenGL program.

What are the advantages of each technique? And what are the techniques?

If vertical sync behaviour could be fully controlled or specified by an OpenGL program, then there would be no differences when the same OpenGL program was used on different graphics cards.

I would prefer to able to control this vertical sync behaviour from within my OpenGL program and therefore think it is a valid enhancement for a future version of OpenGL.

I think it’s simply preferable to have the CPU idle.
I don’t know if the busy loop technique has an advantage. Maybe ATI sees it as better.

Unless the hardware supports a “wait until vertical retrace, then blit” command, there is no way around doing this manually in the driver - poll the retrace and issue the blit (or flip) command when its safe to avoid tearing.

An implementation is not buggy if it elects to poll - there may be no alternative on the given hardware. What’s the issue? If you dont want vsync, you can disable it. I highly doubt the vsync CPU usage is killing your application performance.

There is no problem with application performance with a single OpenGL application. But if multiple applications are used (multitasking), then all the other applications are negatively effected by the high CPU usage caused by the first OpenGL application that polls in its vertical sync.

There is no problem with application performance with a single OpenGL application. But if multiple applications are used (multitasking), then all the other applications are negatively effected by the high CPU usage caused by the first OpenGL application that polls in its vertical sync.
It is not OpenGL’s responsibility or even its place to dictate performance or well-behaved behavior in a multitasking environment. You have a problem with an ATi driver, so take it up with ATi.

I think we have identified two different techniques for vertical sync in OpenGL applications. Each technique is currently used by NVIDIA and ATI respectively. I think it would be very beneficial to be able to specify the technique used via an OpenGL command. Thereby making the same OpenGL program have the same behaviour whether it runs on an ATI graphics card or an NVIDIA graphics card. Resulting in more consistent behavior for OpenGL applications in general.

You miss the point that the driver has no choice if the hardware doesn’t support a wait-for refresh-then-swap method. I can assure you no driver writer worth his salt wants to sit in a tight loop polling a system resource. But when the feature is required and there is no other choice, you do what you have to do.

If the hardware support is available, why would you even want to poll?

That is why there is no user level control for this behavior.

glDesktop, then why do you keep bringing D3D into it?
D3D has no mechanism for dictating whether the CPU should poll or not.
I would imagine your request has been noted, and will subsequently be ignored by the board, because of the reasons stated by others in this thread.

BTW, I assume by your login name you’re trying to use OpenGL to provide an alternative to the Windows desktop environment - so obviously you don’t want GL hogging the CPU, or your customers won’t install it.
Well, hard cheese, there’s nothing in the OpenGL spec that promises a particular swapping method, and there’s no D3D spec at all. Even if GL did introduce a new entry to the spec, older hardware just won’t be able to support it, so you’re still not guarenteed anything.
I would suggest that on startup of your app, you enable vsync, render a couple of simple blank frames, calculate how much CPU was used, then if CPU usage was high, disable vsync. Bob’s yer uncle.

I am getting a mixture of responses about this, which is good and I am thankful for. After all, we just want to improve OpenGL if we can.

I find it hard to believe that such a simple feature like “wait-for refresh-then-swap” is not present in ATI’s high end cards, like the X800. And what also reinforces this, is that using the same card and drivers with Direct3D gives proper idling. So the feature is certainly present with D3D. I assume that the feature is also present in hardware, but they have not taken advantage of it since the OpenGL spec does not say they have to provide the option.

If the OpenGL spec was explicit about this and gave the option if the hardware was present. I’m sure it would guide IHVs into trying to provide the feature to become fully compliant with the spec.

The D3D link was just something I came across the other night. I used “D3DPRESENT_INTERVAL_ONE” and it idled my X800 like magic! I know the example I gave is rough but it does say:

The driver will wait for the vertical retrace period

And I greatly notice the word “wait”, because it idled perfectly for me. Even though wait does not mean sleep or idle.

I really care about OpenGL and don’t want to see it having problems and falling behind the competition. It should be an enabling technology, not something I find unsuitable for what I need. And at the moment it is, so I’m working with Direct3D again.

I’m trying to plant a good seed for OpenGL to help it overcome some of it’s current problems and would one day like to come back to something that can support my needs, in the near future.

So what I really need is proper idling with vertical sync whether it is provided as an option, or is the only correct implementation of vertical sync as defined in the spec.

Also, there are two versions of swap control for OpenGL:

  • GLX_SGI_swap_control
  • WGL_EXT_swap_control

One for Windows and one for X Windows.

I think we should just have one unified one that specifies that the CPU should idle, or at least provided the option of having the CPU idle, if the hardware is available.

Write once, run anywhere!

If there was a bug in ATI’s D3D driver you’d be on the D3D forums spouting the same nonesense.
There’s nothing in the OpenGL spec to say how fast it should draw a triangle, but you’re not demanding that, are you?
Just do as I suggest, and write a little 500 millisecond benchmark that runs on startup.

glDesktop, it’s good that you brought this issue.

The thing is, driver writers know their stuff very well. I have read interviews conducted with some of them. They do A LOT of research.

ATI has had a lot of time to develop their GL driver but they still have this vsync behavior. Ask them about it. Email Evan Hart (ehart there ati.com). He works in their research dept.


Also, there are two versions of swap control for OpenGL:

Yup, and where is the one for the Mac?
WGL for Windows!
GLX for X!
AGL for Apple!

Take a look at GL ES. This young API has done things right.

eglSwapBuffers
eglSwapInterval
and so on