Flipping on DirectX

Hello everyone.

I’d developed some commercial titles for Win32, and I’m considering porting
them to SDL in order to make them available on Linux.

One thing I’m concerned about is performance. I do not wish to get any
performance hit by using SDL. So I’m looking throught the SDL code and
comparing with my own (and learning a couple of things in the process).

Reviewing the DirectX video code (file: video/windx5/SDL_dx5video.c), I’d found
the following code (line 1923)

result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);

This code produces a synchronous flip. DirectX is capable of doing
asynchronous hardware accelerated flips, so that the main processor can do
something more productive than waiting for vertical retrace.

This can be achieved simply by eliminating the DDFLIP_WAIT flag, so I think
there may be a good reason why this flag is set in the first place.

Can anyone please explain me why the flag is set?

Thanks in advance,
Jose Luis Sanchez.

Admittedly, there is plenty the CPU can do (safely)
while waiting for the retrace. The reality is most 2d
games are just trying to pump out frames as fast as
possible, and just want to draw to the next frame… I
think what you might be looking for is TRIPPLE
BUFFERING
so that you can be displaying one frame,
while queueing one frame to appear on the next flip,
and drawing on the third frame. Currently, SDL does
not support tripple buffering, but if you want to to
do non-drawing operations while waiting for the
retrace, probably the most portable thing to do is to
put the non-drawing code in another thread, so that it
can start crunching while waiting for your retrace…

The big problem with drawing right away after a
non-blocking flip, is that in a double buffer
situation, the destination frame will still be
visable…

Best Wishes,

-Loren

— Jos? Luis S?nchez wrote:> Hello everyone.

I’d developed some commercial titles for Win32, and
I’m considering porting
them to SDL in order to make them available on
Linux.

One thing I’m concerned about is performance. I do
not wish to get any
performance hit by using SDL. So I’m looking
throught the SDL code and
comparing with my own (and learning a couple of
things in the process).

Reviewing the DirectX video code (file:
video/windx5/SDL_dx5video.c), I’d found
the following code (line 1923)

result = IDirectDrawSurface3_Flip(dd_surface,
NULL, DDFLIP_WAIT);

This code produces a synchronous flip. DirectX is
capable of doing
asynchronous hardware accelerated flips, so that the
main processor can do
something more productive than waiting for vertical
retrace.

This can be achieved simply by eliminating the
DDFLIP_WAIT flag, so I think
there may be a good reason why this flag is set in
the first place.

Can anyone please explain me why the flag is set?

Thanks in advance,
Jose Luis Sanchez.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do You Yahoo!?
HotJobs - Search Thousands of New Jobs
http://www.hotjobs.com

El Wed, 7 Aug 2002 23:49:58 -0700 (PDT)
Loren Osborn <linux_dr at yahoo.com> escribi?:

Admittedly, there is plenty the CPU can do (safely)
while waiting for the retrace. The reality is most 2d
games are just trying to pump out frames as fast as
possible, and just want to draw to the next frame… I
think what you might be looking for is TRIPPLE
BUFFERING
so that you can be displaying one frame,
while queueing one frame to appear on the next flip,
and drawing on the third frame. Currently, SDL does
not support tripple buffering, but if you want to to
do non-drawing operations while waiting for the
retrace, probably the most portable thing to do is to
put the non-drawing code in another thread, so that it
can start crunching while waiting for your retrace…

Althought I do use triple buffering on Windows (BTW, I’d wonder why this option
isn’t selectable on SDL), there are a full range of things to do unrelated to
drawing.

A game might use the wasted processor cycles to recalculate positions, load
data, decompress sound, all of them unrelated to drawing.

I don’t believe on the “use-a-thread” proposition. On a general basis, I try
to reduce multithreading to a bare minimum, because of the timeslice
granularity (around 20 ms on most PC operating systems), insufficient or bad OS
implementation (lack of system-blocking calls for example), etc.

In fact, if you put a thread waiting for Flip() to finish, that thread will
anyway consume a good amount of CPU cycles (depending of thread priority); it
may even consume ALL CPU cycles leaving all other threads stopped. That’s not
what I want.

Anyway, is there any interest in such things as 2D performance? Or the only
way is to branch out a 2D-optimized version of SDL?

Regards,
Wizord.

10ms on Linux on x86. But yeah.

With the 2.6 kernel, this will change to 1ms or so.On Thu, Aug 08, 2002 at 04:01:19PM +0200, Jos? Luis S?nchez wrote:

to reduce multithreading to a bare minimum, because of the timeslice
granularity (around 20 ms on most PC operating systems), insufficient or bad OS
implementation (lack of system-blocking calls for example), etc.


Matthew Miller @Matthew_Miller http://www.mattdm.org/
Boston University Linux ------> http://linux.bu.edu/

El Thu, 8 Aug 2002 22:27:16 -0400
Matthew Miller escribi?:> On Thu, Aug 08, 2002 at 04:01:19PM +0200, Jos? Luis S?nchez wrote:

to reduce multithreading to a bare minimum, because of the timeslice
granularity (around 20 ms on most PC operating systems), insufficient or
bad OS implementation (lack of system-blocking calls for example), etc.

10ms on Linux on x86. But yeah.

With the 2.6 kernel, this will change to 1ms or so.

Oh, I love to do games for Linux, but I fear this will not solve my original
question related to DirectX.

Regards,
Wizord.

This can be achieved simply by eliminating the DDFLIP_WAIT flag, so I think
there may be a good reason why this flag is set in the first place.

Can anyone please explain me why the flag is set?

The semantics are that a flip will complete synchronized with the vertical
retrace. You have to guarantee that the surface isn’t touched until the
flip is complete. The correct locking work has already been done in the
Linux DGA and framebuffer console drivers, so it shouldn’t be too hard to
get it working with DirectX. Would you like to take a crack at it?

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

— Sam Lantinga wrote:

This can be achieved simply by eliminating the
DDFLIP_WAIT flag, so I think
there may be a good reason why this flag is set in
the first place.

Can anyone please explain me why the flag is set?

The semantics are that a flip will complete
synchronized with the vertical
retrace. You have to guarantee that the surface
isn’t touched until the
flip is complete. The correct locking work has
already been done in the
Linux DGA and framebuffer console drivers, so it
shouldn’t be too hard to
get it working with DirectX. Would you like to take
a crack at it?

See ya,
-Sam Lantinga, Software Engineer, Blizzard
Entertainment

Oh yeah… I forgot, we can block on the call to
LockSurface… that is a good solution… I still
would like to see tripple-buffer support in SDL 1.3 at
least…

-Loren__________________________________________________
Do You Yahoo!?
HotJobs - Search Thousands of New Jobs
http://www.hotjobs.com

— Matthew Miller wrote:> On Thu, Aug 08, 2002 at 04:01:19PM +0200, Jos? Luis S?nchez wrote:

to reduce multithreading to a bare minimum,
because of the timeslice
granularity (around 20 ms on most PC operating
systems), insufficient or bad OS
implementation (lack of system-blocking calls for
example), etc.

10ms on Linux on x86. But yeah.

With the 2.6 kernel, this will change to 1ms or so.

Admittedly this wasn’t the best use of threads I could
have recommended (I just intended to suggest a
short-term solution)… Even so, I never intended to
suggest polling in another thread… Conditional
variables should not be bound to timeslice
increments… as soon as one thread blocks, any other
runnable thread should start. Not an elegant
solution, but it should work ok without respect to
timslices…

-Loren


Do You Yahoo!?
HotJobs - Search Thousands of New Jobs
http://www.hotjobs.com

El Fri, 09 Aug 2002 17:52:21 -0700
Sam Lantinga escribi?:

This can be achieved simply by eliminating the DDFLIP_WAIT flag, so I think
there may be a good reason why this flag is set in the first place.

Can anyone please explain me why the flag is set?

The semantics are that a flip will complete synchronized with the vertical
retrace. You have to guarantee that the surface isn’t touched until the
flip is complete. The correct locking work has already been done in the
Linux DGA and framebuffer console drivers, so it shouldn’t be too hard to
get it working with DirectX. Would you like to take a crack at it?

DirectX already includes locking semantics. When a Flip is in progress, any
attempt to blit, lock or otherwise access the surface causes a
DDERR_WASSILLDRAWING error.

DirectX’s functions Blt, BltFast and Lock can be instructed to wait until the
flip is complete. In fact, this is the way SDL uses them, so the DDFLIP_WAIT
seems not to be needed anymore.

Best regards,
Wizord.

The semantics are that a flip will complete synchronized with the vertical
retrace. You have to guarantee that the surface isn’t touched until the
flip is complete. The correct locking work has already been done in the
Linux DGA and framebuffer console drivers, so it shouldn’t be too hard to
get it working with DirectX. Would you like to take a crack at it?

DirectX already includes locking semantics. When a Flip is in progress, any
attempt to blit, lock or otherwise access the surface causes a
DDERR_WASSILLDRAWING error.

DirectX’s functions Blt, BltFast and Lock can be instructed to wait until the
flip is complete. In fact, this is the way SDL uses them, so the DDFLIP_WAIT
seems not to be needed anymore.

It’s very possible. Do you get improved performance if you remove the flag?
Do you notice any other problems?

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment

El Mon, 12 Aug 2002 21:14:29 -0700
Sam Lantinga escribi?:

The semantics are that a flip will complete synchronized with the
vertical retrace. You have to guarantee that the surface isn’t touched
until the flip is complete. The correct locking work has already been
done in the Linux DGA and framebuffer console drivers, so it shouldn’t be
too hard to get it working with DirectX. Would you like to take a crack
at it?

DirectX already includes locking semantics. When a Flip is in progress,
any attempt to blit, lock or otherwise access the surface causes a
DDERR_WASSILLDRAWING error.

DirectX’s functions Blt, BltFast and Lock can be instructed to wait until
the flip is complete. In fact, this is the way SDL uses them, so the
DDFLIP_WAIT seems not to be needed anymore.

It’s very possible. Do you get improved performance if you remove the flag?
Do you notice any other problems?

Definately, it gets an improved performance. Obviously, increased performance
varies from machine to machine, but it never hurts.

No other problems noticed, thought.

Regards,
Wizord.

DirectX’s functions Blt, BltFast and Lock can be instructed to wait until
the flip is complete. In fact, this is the way SDL uses them, so the
DDFLIP_WAIT seems not to be needed anymore.

It’s very possible. Do you get improved performance if you remove the flag?
Do you notice any other problems?

Definately, it gets an improved performance. Obviously, increased performance
varies from machine to machine, but it never hurts.

Great, thanks! I’ve made this change in CVS.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment