Slooooow

Here’s a zipped up example program I’ve written.
All it does is loop around, blitting a blank screen over the top of the
current display.
In a window I’m getting about 12fps with a Windows 98 machine, a TNT 2 Ultra
and Direct X 7.

In full screen mode I’m getting about 20 fps.

This is terrible. What am I doing wrong?

Actually, that’s pretty good. I’m getting 9-10 FPS on my Matrox
Millennium II under X11 (P2-300)

24-bit mode is the slowest mode there is. I recommend running in 16-bit
mode for games, and 32-bit if you have special effects and so forth that
require the extra precision.

Right now, SDL is converting from 24-bit RGB to 16-bit RGB, and that’s
very expensive. If I change both surfaces from being 24-bit to 32-bit,
I get a jump to 21 FPS, even though SDL is still converting from 32 bpp
to my X server’s native 16 bpp. If I change both surfaces to 16-bit, i.e.
set a 16 bit video mode and create a 16 bpp surface, the framerate jumps
to 56 FPS. If I remove the blit and just perform a flip, then the
framerate jumps even higher to 103 FPS.

When using testsprite with 10 sprites on the screen, performing dirty
rectangle updates, I get an amazing 216 frames per second, just with X11
software rendering. When I use accelerated hardware the framerates jump
into the insane thousands of frames per second. :slight_smile:

The moral of the story is: 24bpp is bad, m’kay?

BTW, I changed your event code so it actually responded to quit messages:

// Sam - this code never got triggered
//if( SDL_PollEvent(&event) == 0)
while ( SDL_PollEvent(&event) )
{
if( event.type == SDL_QUIT)
nQuit = true;
}

Enjoy! :slight_smile:
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

Here’s a zipped up example program I’ve written.
All it does is loop around, blitting a blank screen over the top of the
current display.
In a window I’m getting about 12fps with a Windows 98 machine, a TNT 2 Ultra
and Direct X 7.

In full screen mode I’m getting about 20 fps.

This is terrible. What am I doing wrong?________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com
-------------- next part --------------
A non-text attachment was scrubbed…
Name: main.zip
Type: application/x-zip-compressed
Size: 1438 bytes
Desc: not available
URL: http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20000601/20094b09/attachment.bin

Actually, that’s pretty good. I’m getting 9-10 FPS on my Matrox
Millennium II under X11 (P2-300)

24-bit mode is the slowest mode there is. I recommend running in 16-bit
mode for games, and 32-bit if you have special effects and so forth that
require the extra precision.

Right now, SDL is converting from 24-bit RGB to 16-bit RGB, and that’s
very expensive. If I change both surfaces from being 24-bit to 32-bit,
I get a jump to 21 FPS, even though SDL is still converting from 32 bpp
to my X server’s native 16 bpp. If I change both surfaces to 16-bit,
i.e.

set a 16 bit video mode and create a 16 bpp surface, the framerate jumps
to 56 FPS. If I remove the blit and just perform a flip, then the
framerate jumps even higher to 103 FPS.

When using testsprite with 10 sprites on the screen, performing dirty
rectangle updates, I get an amazing 216 frames per second, just with X11
software rendering. When I use accelerated hardware the framerates jump
into the insane thousands of frames per second. :slight_smile:

The moral of the story is: 24bpp is bad, m’kay?

BTW, I changed your event code so it actually responded to quit messages:

Thanks Sam. I didn’t realise I even had that event code in there :slight_smile:
I was cobbling bits and pieces together just as a test case.

That’s fantastic. Exactly what I wanted to know. Yep, I changed to a 16
bit suface and was getting 200 fps without blitting, then about 60 with
blitting at 16 bits.
Haven’t tried dirty rectangle updating, but should be even better. Can’t
thank you enough.

I wonder if this sort of thing should go somewhere for other ‘idiots’ such
as myself?


In fact, one should use the SDL_ANYFORMAT flag when initing screen so that
no convertion at all will be performed
or even better:
screen =
SDL_SetVideoMode(640,480,SDL_GetVideoInfo()->vfmt->BitsPerPixel,0);

repeat after me: “conversion is evil”--------------------------------------------------------------------
Gautier Portet - gautier at tlk.fr
lead programmer at TLK Games
http://www.tlk.fr

Gautier Portet wrote:

[snip]

In fact, one should use the SDL_ANYFORMAT flag when initing screen so that
no convertion at all will be performed
or even better:
screen =
SDL_SetVideoMode(640,480,SDL_GetVideoInfo()->vfmt->BitsPerPixel,0);

repeat after me: “conversion is evil”

Got a question:

Can SDL_SetVideoMode() change the pixel depth? (with the fullscreen
flag)

I know that DirectX can do it, but I was under the impression that under
X, DGA could only change resolution, not depth. Has this changed with
XFree86 4.x? (DGA2?)
How about Beos and the Mac?

background:

A lot of games are going to have an ‘optimal’ pixel depth they’d like to
run in. I have a game which uses 16bit - either 555 or 565.

Currently, I ask SDL which pixel format is likely to ‘best’.
If the ‘best’ format is 16 bit 555 or 565, then I’ll specify that mode
in SDL_SetVideoMode().
If the ‘best’ format is something else, I’ll specify a 16bit 565 surface
and live with the conversion.

I’m happy to put up with the conversion in windowed mode - if the user
is running their desktop in a non-16bit mode then too bad - I’ve just
got to accept the conversion slowdown (and maybe pop up a message box to
inform the user).

But in fullscreen mode it’d be nice to explictly set a 16bit depth.

Ben.–
Ben Campbell (Antipodean Straggler)
Programmer, Creature Labs
ben.campbell at creaturelabs.com
www.creatures.co.uk

Sam Lantinga wrote:

The moral of the story is: 24bpp is bad, m’kay?

I heard that one a few times on this mailing list, but there is
something tickling me about this… Dirk Hohndel told me at Linux Expo
that 24 bpp in XFree86 4.x is faster than 32 bpp!

The explanation is something along the lines that the previous code was
optimized for old ISA bus video cards, where reading is not slower than
writing and that you want to minimize the amount of data transferred as
much as possible, so the cfb code (hmm, right name? not sure) in the
pre-4.x was optimized for this. New cards have very slow reading, but
can block transfer very quickly. 24 bpp means 25% less data than 32 bpp,
so it’s nearly 25% faster for blitting from system memory!–
Pierre Phaneuf
Systems Exorcist

Sam Lantinga wrote:

The moral of the story is: 24bpp is bad, m’kay?

I heard that one a few times on this mailing list, but there is
something tickling me about this… Dirk Hohndel told me at Linux Expo
that 24 bpp in XFree86 4.x is faster than 32 bpp!

The raw copy rate in 24bpp is of course faster than for 32bpp since there
is less data to copy. The more complex rendering you do, the more does 32bpp
catch up with this. Blitting big, homogenous rectangles is probably win for
24bpp, but for smaller, fragmented sprites, 32bpp has a definite advantage,
as for anything requiring pixel addressing.

For the lucky few not having survived our discussions in #sdl, the 24bpp
format now has the same endianness as the other pixel formats. This enables
some further optimizations, so if someone is concerned about 24bpp performance
there is a lot of room for it. Especially interesting is the obvious
unrolling by 4 horizontal pixels, reading 3 words in sequence.

Got a question:

Can SDL_SetVideoMode() change the pixel depth? (with the fullscreen
flag)

Yes.

I know that DirectX can do it, but I was under the impression that under
X, DGA could only change resolution, not depth. Has this changed with
XFree86 4.x? (DGA2?)
How about Beos and the Mac?

X11 in window: No
X11 in DGA 2.0: Yes
framebuffer console: yes
DirectX in window: No
DirectX fullscreen: Yes
BeOS in window: No
BeOS fullscreen: I don’t remember offhand. I think so, as of SDL 1.1
MacOS in window: No
MacOS fullscreen: Yes

In addition, as of SDL 1.1.2, if your X11 display can handle multiple
visuals, SDL will choose the closest matching visual for the best
performance, so for example if your display supports 32 bpp with 8 bpp
overlays, like the G400, then SDL will give you an 8 bpp overlay when
you request an 8-bit surface, and will give you a 32 bpp surface all
other times.

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

Can SDL_SetVideoMode() change the pixel depth? (with the fullscreen
flag)

I know that DirectX can do it, but I was under the impression that under
X, DGA could only change resolution, not depth. Has this changed with
XFree86 4.x? (DGA2?)

XFree86 4 should allow you to choose depths other than the available
visuals. Note that some X servers may provide several depths without any
DGA or vidmode tricks.

A lot of games are going to have an ‘optimal’ pixel depth they’d like to
run in. I have a game which uses 16bit - either 555 or 565.

Currently, I ask SDL which pixel format is likely to ‘best’.
If the ‘best’ format is 16 bit 555 or 565, then I’ll specify that mode
in SDL_SetVideoMode().
If the ‘best’ format is something else, I’ll specify a 16bit 565 surface
and live with the conversion.

This is seldom acceptable, since the overhead will be considerable. Better
use one of the native depths. Try something like:

SDL_Surface *set_vid_mode(int w, int h, int depth, Uint32 flags)
{
int d = SDL_VideoModeOK(w, h, depth, flags);
return d ? SDL_SetVideoMode(w, h, d, flags) : NULL;
}

Actually, that’s pretty good. I’m getting 9-10 FPS on my Matrox
Millennium II under X11 (P2-300)

24-bit mode is the slowest mode there is. I recommend running in 16-bit
mode for games, and 32-bit if you have special effects and so forth that
require the extra precision.

Right now, SDL is converting from 24-bit RGB to 16-bit RGB, and that’s
very expensive. If I change both surfaces from being 24-bit to 32-bit,
I get a jump to 21 FPS, even though SDL is still converting from 32 bpp
to my X server’s native 16 bpp. If I change both surfaces to 16-bit, i.e.
set a 16 bit video mode and create a 16 bpp surface, the framerate jumps
to 56 FPS. If I remove the blit and just perform a flip, then the
framerate jumps even higher to 103 FPS.

When using testsprite with 10 sprites on the screen, performing dirty
rectangle updates, I get an amazing 216 frames per second, just with X11
software rendering. When I use accelerated hardware the framerates jump
into the insane thousands of frames per second. :slight_smile:

The moral of the story is: 24bpp is bad, m’kay?

BTW, I changed your event code so it actually responded to quit messages:

Thanks Sam. I didn’t realise I even had that event code in there :slight_smile:
I was cobbling bits and pieces together just as a test case.

That’s fantastic. Exactly what I wanted to know. Yep, I changed to a 16
bit suface and was getting 200 fps without blitting, then about 60 with
blitting at 16 bits.
Haven’t tried dirty rectangle updating, but should be even better. Can’t
thank you enough.

I wonder if this sort of thing should go somewhere for other ‘idiots’ such
as myself?________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

Strange things have been happening when I have global classes that have an
SDL_Surface that gets freed on destructor call.

This test program crashes upon execution under Win 98 with direct x 7. It
seems simple and straight forward to me. Why does it die?

Thanks for your help,

Rob________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

Mattias Engdeg?rd wrote:

Can SDL_SetVideoMode() change the pixel depth? (with the fullscreen
flag)

I know that DirectX can do it, but I was under the impression that under
X, DGA could only change resolution, not depth. Has this changed with
XFree86 4.x? (DGA2?)

XFree86 4 should allow you to choose depths other than the available
visuals. Note that some X servers may provide several depths without any
DGA or vidmode tricks.

Groovy.

A lot of games are going to have an ‘optimal’ pixel depth they’d like to
run in. I have a game which uses 16bit - either 555 or 565.

Currently, I ask SDL which pixel format is likely to ‘best’.
If the ‘best’ format is 16 bit 555 or 565, then I’ll specify that mode
in SDL_SetVideoMode().
If the ‘best’ format is something else, I’ll specify a 16bit 565 surface
and live with the conversion.

This is seldom acceptable, since the overhead will be considerable. Better
use one of the native depths. Try something like:

SDL_Surface *set_vid_mode(int w, int h, int depth, Uint32 flags)
{
int d = SDL_VideoModeOK(w, h, depth, flags);
return d ? SDL_SetVideoMode(w, h, d, flags) : NULL;
}

So what if the depths I need aren’t available?
I think I’d rather run at a slower speed rather than not running at all

  • and display a message to the user saying why their game is going
    slow and what they could do about it.

The windowed mode of my game (as opposed to fullscreen) is always going
to be at the mercy of the users desktop depth anyway…

Ben.–
Ben Campbell (Antipodean Straggler)
Programmer, Creature Labs
ben.campbell at creaturelabs.com
www.creaturelabs.com

SDL_Surface *set_vid_mode(int w, int h, int depth, Uint32 flags)
{
int d = SDL_VideoModeOK(w, h, depth, flags);
return d ? SDL_SetVideoMode(w, h, d, flags) : NULL;
}

So what if the depths I need aren’t available?

Then SDL_VideoModeOK will return the nearest available native mode.

I think I’d rather run at a slower speed rather than not running at all

  • and display a message to the user saying why their game is going
    slow and what they could do about it.

Of course, but running in native 32bpp is much faster than emulating 16bpp
on 32bpp hardware, for instance.

The windowed mode of my game (as opposed to fullscreen) is always going
to be at the mercy of the users desktop depth anyway…

Then make the best of what you have.

Robert Clayton wrote:

Strange things have been happening when I have global classes that have an
SDL_Surface that gets freed on destructor call.

This test program crashes upon execution under Win 98 with direct x 7. It
seems simple and straight forward to me. Why does it die?

Thanks for your help,

Rob


Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

It’s probably because DirectX doesn’t fully comply to the
COM specification, and when you release the library it invalidates
all surfaces. Your surfaces are probably getting DecRef’d after
DirectX has been shut down.

That’s always a problem with global classes and destructors. You don’t
know what order they will run.

It’s probably because DirectX doesn’t fully comply to the
COM specification, and when you release the library it invalidates
all surfaces. Your surfaces are probably getting DecRef’d after
DirectX has been shut down.

That’s always a problem with global classes and destructors. You don’t
know what order they will run.

Oh, okay. So do I just ignore the errors generated by the global classes on
destruction?________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

Robert Clayton wrote:

It’s probably because DirectX doesn’t fully comply to the
COM specification, and when you release the library it invalidates
all surfaces. Your surfaces are probably getting DecRef’d after
DirectX has been shut down.

That’s always a problem with global classes and destructors. You don’t
know what order they will run.

Oh, okay. So do I just ignore the errors generated by the global classes on
destruction?


Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

No. you need to do something to get the right destruct order.
Or avoid global objects like that. That’s what Sam is doing in his
Pirates Ho! series of articles.

No. you need to do something to get the right destruct order.
Or avoid global objects like that. That’s what Sam is doing in his
Pirates Ho! series of articles.

I see. Is difficult because I’ve wrapped some SDL stuff into a global class
I use for displaying certain things. Many other classes assume this class
exists at a global level. This saved me passing references around to every
class, when this global class was used by everything.

How on earth can you control the destruct order?________________________________________________________________________
Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com

No. you need to do something to get the right destruct order.
Or avoid global objects like that. That’s what Sam is doing in his
Pirates Ho! series of articles.

I see. Is difficult because I’ve wrapped some SDL stuff into a global class
I use for displaying certain things. Many other classes assume this class
exists at a global level. This saved me passing references around to every
class, when this global class was used by everything.

Instead of having a global class instance, have a global class pointer.
Then initialize the pointer at runtime.

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