Vertical retrace in SDL

Hi,
I have noticed that the SDLgears sample program behaves differently
under windows to linux. Windows supports my TNT2 card, and gives a frame
rate of 60fps. Linux does not support it (at least it’s not set up), but
gives me over 100fps! Presumably this is because windows waits for the
vertical retrace but linux does not. How do I make it wait for the
retrace? Otherwise I’m only wasting processor time on frames which are
never displayed.

Incidently could this be why my keyboard reponses are slow under

Linux but no windows?

Also I notice the documentation says that SDL_Flip() waits for

retrace, but doesn’t say that the OpenGL equivilent (forget what it’s
called) will wait.

Thanks in advance for any help,

    David
I have noticed that the SDLgears sample program behaves differently

under windows to linux. Windows supports my TNT2 card, and gives a frame
rate of 60fps. Linux does not support it (at least it’s not set up), but
gives me over 100fps! Presumably this is because windows waits for the
vertical retrace but linux does not. How do I make it wait for the
retrace? Otherwise I’m only wasting processor time on frames which are
never displayed.

And probably observing flicker/shearing.
I don’t know how to fix this under X.

Incidently could this be why my keyboard reponses are slow under

Linux but no windows?

Sounds plausible.

Also I notice the documentation says that SDL_Flip() waits for

retrace, but doesn’t say that the OpenGL equivilent (forget what it’s
called) will wait.

SDL_GL_SwapBuffers. It leaves this to the GLX implementation, I believe
(just calls glXSwapBuffers).

-John–
Underfull \account (badness 10000) has occurred while \spend is active
John R. Hall - Student, Georgia Tech - Contractor, Loki Software

If you don’t wait for the retrace to blit the result, the danger isn’t
really drawing an extra frame or two - after all, who runs processor
intensive programs in the bacgkround of games? You’re not using your game
machine as an Apache server, hopefully… =)

The problem is tearing - where you blit halfway between the retrace and so
half the screen is last frame and the bottom half is this frame. It looks
TERRIBLE.

I haven’t played with SDL or OpenGL Flip function… but my first instinct
is to draw everything with OpenGL, and then call SDL_Flip. You’ll need to
set one of the flags when you create the surface… Again, I am a newbie to
SDL.> ----- Original Message -----

From: esuvs@csv.warwick.ac.uk (Mr D P Williams)
To:
Sent: Friday, January 19, 2001 12:46 PM
Subject: [SDL] vertical retrace in SDL

: Hi,
: I have noticed that the SDLgears sample program behaves differently
: under windows to linux. Windows supports my TNT2 card, and gives a frame
: rate of 60fps. Linux does not support it (at least it’s not set up), but
: gives me over 100fps! Presumably this is because windows waits for the
: vertical retrace but linux does not. How do I make it wait for the
: retrace? Otherwise I’m only wasting processor time on frames which are
: never displayed.
:
: Incidently could this be why my keyboard reponses are slow under
: Linux but no windows?
:
: Also I notice the documentation says that SDL_Flip() waits for
: retrace, but doesn’t say that the OpenGL equivilent (forget what it’s
: called) will wait.
:
: Thanks in advance for any help,
:
: David
:
:
:
:
:

I have noticed that the SDLgears sample program behaves

differently under windows to linux. Windows supports my TNT2
card, and gives a frame rate of 60fps. Linux does not support it
(at least it’s not set up), but gives me over 100fps! Presumably
this is because windows waits for the vertical retrace but linux
does not. How do I make it wait for the retrace? Otherwise I’m
only wasting processor time on frames which are never displayed.

And probably observing flicker/shearing.
I don’t know how to fix this under X.

You can always poll the retrace reg on any VGA compatible card,
provided you can get access to the ports, but this doesn’t solve the
problem. glXSwapBuffers() just throws in a back->front blit command
and then flushes the command FIFO, which means that there can be
quite a few rendering operations to perform before the actual flip
blit stars. The result is a crappy GPU load indicator in the form of
a band of tearing moving over the screen. :frowning:

[…]

Also I notice the documentation says that SDL_Flip() waits

for retrace, but doesn’t say that the OpenGL equivilent (forget
what it’s called) will wait.

SDL_GL_SwapBuffers. It leaves this to the GLX implementation, I
believe (just calls glXSwapBuffers).

…but glXSwapBuffers() of Utah-GLX doesn’t wait for the retrace in
any of the drivers I’ve looked at.

I hacked it into the G400 and Mach64 drivers, adding an extra flush
to avoid the problem described above, but I have some more tuning of
the retrace sync left to do to avoid dropped frames due to missed
retraces. (I’m using the Pentium performance counter to find out when
I’m close enough to the actual retrace, and just resyncing the
internal timer whenever I actually see a retrace.)

I would guess that the DRI GLX drivers for XFree86 4.0.1 should
implement glXSwapBuffers() properly (ie hardware pageflipping rather
than blits), but I haven’t seen it in action yet.

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Friday 19 January 2001 22:32, John R. Hall wrote:

I hate to beat a dead horse, but…

Why can’t SDL have a function like SDL_WaitForRetrace() (that blocks until
the video is completely retraced) be called before SDL_UpdateRects()? For
which platforms is this a problem to implement?

Another thing, we would have to add something to get the video refresh rate
to make this truly useful.

Something else that might be useful is a swap interval call for the double
buffered case. A value of 0 would mean no sync, 1 waits for 1 refresh scan
before swapping, 2 waits for 2 etc.

Why can’t SDL have a function like SDL_WaitForRetrace() (that blocks until
the video is completely retraced) be called before SDL_UpdateRects()? For
which platforms is this a problem to implement?

it’s not possible on x11. For other targets the sync should probably be
built into UpdateRects()

Another thing, we would have to add something to get the video refresh rate
to make this truly useful.

for some applications (mostly emulators, maybe video players), it would be
useful to request a specific refresh rate. this is possible on some targets

You can’t build a refresh into UpdateRects() because you may not want to sync
on each rect update, just the initial one.
However, there is a new development branch starting soon so if anyone has any
fancy ideas…On Sat, Jan 20, 2001 at 06:02:30PM +0100, Mattias Engdegard wrote:

Why can’t SDL have a function like SDL_WaitForRetrace() (that blocks until
the video is completely retraced) be called before SDL_UpdateRects()? For
which platforms is this a problem to implement?

it’s not possible on x11. For other targets the sync should probably be
built into UpdateRects()

Martin

Bother! said Pooh, as the atomic blast consumed him.

Hi,
I have noticed that the SDLgears sample program behaves differently
under windows to linux. Windows supports my TNT2 card, and gives a frame
rate of 60fps. Linux does not support it (at least it’s not set up), but
gives me over 100fps! Presumably this is because windows waits for the
vertical retrace but linux does not. How do I make it wait for the
retrace? Otherwise I’m only wasting processor time on frames which are
never displayed.

It’s possible. Anybody know the details of the Win32 OpenGL drivers?

Incidently could this be why my keyboard reponses are slow under

Linux but no windows?

No, the reason for that is that SDL is pushing the X server as hard as
it can for 3D graphics, and I haven’t found a decent time to perform a
"wait for the X server to catch up" sync. Most of the time this isn’t
a problem, as the X server isn’t very busy while 3D hardware is doing
the GL processing, and can handle events just fine.

Also I notice the documentation says that SDL_Flip() waits for

retrace, but doesn’t say that the OpenGL equivilent (forget what it’s
called) will wait.

The GL equivalent does not wait for retrace. Waiting for retrace isn’t
supported on any of the Linux drivers, that I know of.

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

It’s possible. Anybody know the details of the Win32 OpenGL drivers?

Usually it is a checkbox. For NVIDIA cards you can use NVMAX to toggle
the setting.

The GL equivalent does not wait for retrace. Waiting for
retrace isn’t
supported on any of the Linux drivers, that I know of.

For NVIDIA it is an environment variable that is documented somewhere on
NVIDIA’s site. I think it is possible with DRI to wait for retrace via
an environment variable too.

                     Daniel Vogel, Programmer, Epic Games

Usually it is a checkbox. For NVIDIA cards you can use NVMAX to toggle
the setting.

http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_swap_control.txt

is an WGL extension to control the swap behaviour. AFAIK most drivers on
Windows support it.

                     Daniel Vogel, Programmer, Epic Games

You can’t build a refresh into UpdateRects() because you may not want to sync
on each rect update, just the initial one.

then coalesce multiple calls into one. Multiple calls to UpdateRects() are
a bad idea anyway since it calls XSync() each time

I hate to beat a dead horse, but…

Why can’t SDL have a function like SDL_WaitForRetrace() (that
blocks until the video is completely retraced) be called before
SDL_UpdateRects()? For which platforms is this a problem to
implement?

Anything with buffered hardware acceleration, like most accellerated
OpenGL targets. Well, no problem to implement the sync function; not
even dealing with the fact that a simple busy-wait won’t work well in
a non-RTOS. But it won’t be of much use for those targets, at least
not without hardware pageflipping (ie no back->front blit).

I had to hack glXSwapBuffers of Utah-GLX, adding an extra flush
before the sync, or the tearing got worse than without any retrace
sync at all.

Another thing, we would have to add something to get the video
refresh rate to make this truly useful.

Yep. Should be doable via APIs on most targets. Some retrace timing
measurements followed by some statistics processing should do for
targets that can’t or won’t say anything useful.

Something else that might be useful is a swap interval call for the
double buffered case. A value of 0 would mean no sync, 1 waits for
1 refresh scan before swapping, 2 waits for 2 etc.

Sounds nice… It should probably be implemented in the drivers to
work well, just as retrace sync in general. It would work to have it
all in SDL for truly hardware pageflipping targets, though.

//David

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------> http://www.linuxaudiodev.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |--------------------------------------> david at linuxdj.com -'On Saturday 20 January 2001 15:36, Darrell Walisser wrote: