View Full Version : Bitmaps in VRAM (how many is OK?)
Jamie W
04-12-2007, 02:39 PM
Hello,
I've been pondering this issue (again) ...
In my game, I have 2 main sections, a front-end menu section, and an in-game action section. Both sections of the game make use of different bitmaps, and some bitmaps are common to both sections.
When I started development of my current project, I was manually loading bitmaps to VRAM, and freeing them again, as my game state changed from front-end to in-game.
Scince then, I've changed tact (wisely or not, who can say?) ...
I now just load everything in to VRAM, and hope that the system (PTK) will automatically (magically behind the scenes) shift bitmaps around to take best advantage of available VRAM on a users PC.
Does that actually happen? Not just with PTK, but with other 2d via 3d game engines?
Am I panicing needlessly? Come on. Put me out of my misery ...
Emmanuel
04-12-2007, 03:05 PM
ptk (really Direct3D or OpenGL, so basically any '2d in 3d' engine that lets them manage textures) will automatically move textures from RAM to VRAM. What you need to worry about is the amount of texture data that you need to render in a particular frame; if there isn't enough VRAM, the system will swap textures in and out on every frame, and the framerate will drop like a rock. Fairies for instance has something like 80 megabytes of texture data loaded at the beginning, but it plays at full framerate on an old 8 MB VRAM machine as there's never more than 6 MB of textures or so to render at any given time.
Best regards,
Emmanuel
PeterM
04-12-2007, 06:14 PM
I agree with Emmanuel.
And because you're talking to Direct3D (which may manage VRAM) which talks to the graphics driver (which will manage VRAM), you never really know what's in VRAM and what's not.
Sol_HSA
04-13-2007, 12:27 AM
http://www.steampowered.com/status/survey.html
Steam hardware survey (ok, not exactly the same target market as for indie games, but some kind of guideline nevertheless) says that 83.14% of steam users have at least 128MB of vram.
Jamie W
04-13-2007, 12:41 AM
ptk (really Direct3D or OpenGL, so basically any '2d in 3d' engine that lets them manage textures) will automatically move textures from RAM to VRAM. What you need to worry about is the amount of texture data that you need to render in a particular frame; if there isn't enough VRAM, the system will swap textures in and out on every frame, and the framerate will drop like a rock. Fairies for instance has something like 80 megabytes of texture data loaded at the beginning, but it plays at full framerate on an old 8 MB VRAM machine as there's never more than 6 MB of textures or so to render at any given time.
Best regards,
Emmanuel
That's very useful to know, and also great news for me, thanks Emmanuel.
So as I understand it now, there is no problem loading all bitmaps to VRAM on startup, so long as you're not using too many all at once.
Also, it's probably better to do it your way, because my bitmaps are PNG's, so if I load them all in to VRAM on startup, I (ptk) don't have to keep decoding them every time I manually load them. So things should run smoother.
I've thought of another issue ...
Say I had a racing game with a lot of bitmaps (one for each car) loaded in to VRAM. During the in-game phase, the game scrolls around and the cars are moving too, so that cars will come on screen and go of screen intermitently (it may be on screen for say, 10 seconds).
What would be the performance hit (or any issues?), as a new car comes on screen, or a car goes off screen?
(I know I'm probably worry too much about details, but I like to know the mechanics of it, because I think I'm being too miserly with bitmaps in my current game).
Thanks,
Jamie.
Jamie W
04-13-2007, 12:47 AM
http://www.steampowered.com/status/survey.html
Steam hardware survey (ok, not exactly the same target market as for indie games, but some kind of guideline nevertheless) says that 83.14% of steam users have at least 128MB of vram.
WOW. More powerful spec'd PC's than I would have thought.
Are these stats for the PC's of typical person who downloads casual games, or for PC's of hard-core games?
Sharpfish
04-13-2007, 12:57 AM
Are these stats for the PC's of typical person who downloads casual games, or for PC's of hard-core games?
These are mostly the Half Life 2 / Counter Strike hardcore crowd so I would take that with a pinch of salt for out needs (regardless of steam broadening out into 'indie game downloads' it's still far from casual audience).
Those stats have been around for ages and they don't appear to have changed much, they are definitely not what you want to be aiming at.
I would say 32mb, 16mb or NO mb (shared memory on IGP) are closer to your target if you are talking hardware acceleration.
Emmanuel
04-13-2007, 01:02 AM
If the new car coming on screen sports a bunch of textures that haven't been drawn yet (or that were pushed out of VRAM to make room for others), you'll definitely feel the copy and the game will jitter for a frame. I forgot to mention in my previous post that in order to avoid that, I pre-draw all the necessary textures before I start the rendering loop for a particular section of the game (there's actual calls in D3D to preload, but for simplicity and compatibility with GL, I just issue a bunch of blits to load those textures, and then I don't show that frame).
Best regards,
Emmanuel
Sharpfish
04-13-2007, 01:09 AM
What would be the performance hit (or any issues?), as a new car comes on screen, or a car goes off screen?
Thanks,
Jamie.
When using 3D (even for 2D) some of the biggest hogs are texture swapping, if you can keep as many of your 'sprites' or skins on as few textures as possible it's a lot quicker to grab the portion of the texture you need and slap it on your quad than to invoke texture/render state changes.
If you can fit 4 cars on 1 256x256 texture then better than 4 seperate textures that need swapping to each frame before rendering. Or even better 8 on a 512x512 texture if you are sure the target system can handle that size texture ok (if you are targeting hardware graphics and you are not going too casual then 512x512 textures should be ok for the most part), you can always run checks (caps in D3D) and if need be chop up the textures at run time to a size the hardware can handle.
Basically for decent performance always limit the amount of texture/state changes you do and send enough data to the card so that it doesn't 'stall', not sure how PTK works it may be a lot more basic (hand holding) than that so you may not need to worry about it but if doing it manually you typically would draw all all parts of the 'scene' that use a certain texture, then move to the next texture and draw all the quads/polys using that and so on.
As for the VRam issue, I personally load and clear out between states (because i'm doing it more 'manually') and while I could jam it all in and invoke texture swapping I think it's tider this way. And generally It also depends (in D3D) on what kind of buffer you are using as to how the swapping (if any) will be managed, non-managed/lose-able are generally faster but take more work to stay safe (i.e when you loose focus), I think from what Emmanuel said that it takes care of it for you (with a slight speed penalty that's probably not worth worrying about for small games), however my info is based on DX8 (D3D) not DX7 and there are some differences, I assume it uses D3D in PTK and not Direct Draw though?.
From what was said above though, I think with PTK you don't have to worry about even half of that, just keep your textures logical and don't make a texture file for everything but bunch them up onto 256x256 textures if possible so you end up with less overall ->SetTextures() per frame.
Jamie W
04-13-2007, 04:10 AM
Thanks Guys.
:)
PTK uses (OpenGL or) D3D (DirectX 7).
With QWAK, I've tended to go mostly for the 256*256 texture size, and only have a few textures smaller than that (and nothing larger).
I feel it's pretty important for a game to run smoothly, and like to minimise risk of any 'hiccups' as textures swap in and out of VRAM. I also like to keep things simple (and keep my code cleaner, by not manually loading / unloading textures to / from VRAM). So just trying to get my head round what is the best general approach.
I can see 2 basic approaches here:
A) Manually managing which textures are in VRAM yourself.
B) Loading everything on startup, and then having a 'dry run' frame, of blitting just the textures you need to use for the upcoming phase of your game.
So, to avoid any 'hiccups' (as Emmanuel says will happen when new textures are used and require loading to VRAM), is there really any difference between A and B?
Are there any other important differences between approach A and B?
soniCron
04-13-2007, 04:29 AM
If you're using Direct3D or OpenGL, you don't many options managing textures (except to pack as many sprites onto them as possible). And if you're using a 2D API, blitting them to the screen before the "real" render frame is a waste.
@Paul: If we're talking about 2D-in-3D, how do you manage to draw all sprites on a single texture at a time? Most of my sprites are alpha blended to some degree, so that's not possible -- I have to draw by depth. Do you know something I don't?
Sharpfish
04-13-2007, 05:37 AM
@Paul: If we're talking about 2D-in-3D, how do you manage to draw all sprites on a single texture at a time? Most of my sprites are alpha blended to some degree, so that's not possible -- I have to draw by depth.
Not quite sure what you mean there. I just meant they are packed on a single texture in vram (from your art package or whatever) and then taken from that and applied to their own quads. The point being to only need a single ->SetTexture() call (d3d specific) instead of one for each unique texture/sprite(quad), which helps speed things up as ->SetTexture() is a burden.
When you draw by depth, though I haven't done *much* 2d in 3d (mainly full 3d) in my case I draw by plain texture alone ie a wall texture get's applied to all parts, then a grass one, then a fence one and in that case yes each texture IS unique (in Vram) but that's different from what I was talking about for simple 2D-in 3D.
As far as I know if I took a single texture with 4 background map tiles on (+ built in alpha for ex .png with Alpha channel) and I wanted certain ones at the back and others at the front I would still only ->SetTexture() once (as apposed to setting texture 4 times) but draw my quads in the order I needed them (back ones being first). I admit I haven't needed to do z-ordering with packed textures (only seperate ones) but if the texture is set then I would assume you grab your piece, map it to the quad and draw it in the order you need. I have probably grossly misunderstood what you were getting at so please ignore if that's the case :)
Do you know something I don't?
I doubt it ;)
Nikster
04-13-2007, 06:22 AM
I think what sonicron is saying is that you have to draw in the correct order when using any blends otherwise you're likely to get artifacts, ie:- blending with the background colour rather than the texture underneath, this isn't a problem with opaque textures, and none antialiased textures (GUI) tend to look like crap :) but like you say, if you pack into pages, you're likely to have less settextures.
Sharpfish
04-13-2007, 06:40 AM
I layer many alpha'd textures over each other for my gui system (and backdrops) and they all blend just right, i've never seen any clashes - i Just call their render member functions in the order I need to draw them. I guess some of this comes down to what api/engine you are using. That is with seperate textures though. If they were all packed then I would just set the background texture (block/sprite sheet which contains images of all 'tiles' to be drawn in the same z position) first, draw all the quads from that, set the next layer forward, draw all the quads from that and so on, that is with proper alpha blending etc (even fadeable on the fly).
Actually what I do on my current game (which is not a 2D game using 3D but a 3D game fixed as 2D with 2D elements) is draw a backdrop (stretched texture to screen size) then I render some 3D meshes, then I draw the gui which are various depth alpha'd textures (png) if I call them in this order they render fine with no blending problems but that could be down to the way I have it coded in my draw functions.
So if Daniel is saying he can't draw sprite A from texture A and then sprite B from texture A because they are at different depths then you just pack your sprite sheets by depth (rather than packing abitrarily) to minimise ->setTexture() calls.
And a good speed boost tip (possibly for Jamie) is to turn of back buffer clearing if you are going to have it fully covered with a (vertex z=1) backdrop quad like for instance a full screen backdrop picture that you put sprites over, if the quad is always rendered first and then the sprites, the order will be correct and you won't need to clear the backbuffer.
This has gone a bit off topic by now so, my only tip for the original VRAM question is to keep it to a minimum at all times to minimse the chances of swapping between Ram and Vram, if you don't want to do that you will probably be ok - just check your peak usage in game (rivatuner?) and if it's less than say 32mb then set 32mb as your reccomended requirement on the games download page. If you clear out and reload on state changes, chances are you may get it down to 16mb peak (or whatever) and can lower requirements but ~32 won't harm if you'd rather not optimise it.
And the first reply Emmanuelle gave is really all you needed to know I guess, because its' not critical if it swaps out (manages) your non needed textures (front end) though you may get some hiccups to start with but ok after that. It's the peak while in game with everything you are going to need on screen during the game, so probably your time would be better spent optimising the size of textures that are always used in game and check their peak doesn't exceed a decent low spec computer's typical Vram.
I now just load everything in to VRAM, and hope that the system (PTK) will automatically (magically behind the scenes) shift bitmaps around to take best advantage of available VRAM on a users PC.I think some sort of texture management will still be required for resource heavy games, even with D3D/OpenGL handling the VRAM/System RAM transfers. Because by loading every single textures to system memory means larger system memory requirement.. If it exceed the amount of physical memory installed on that system the textures could end up in system virtual memory on the hard drive ...
Jamie W
04-13-2007, 01:27 PM
I think some sort of texture management will still be required for resource heavy games, even with D3D/OpenGL handling the VRAM/System RAM transfers. Because by loading every single textures to system memory means larger system memory requirement.. If it exceed the amount of physical memory installed on that system the textures could end up in system virtual memory on the hard drive ...
Is that any worse than having to manually load in textures (files from the hard drive + decompression) anyway?
Is that any worse than having to manually load in textures (files from the hard drive + decompression) anyway?Well hehe ya it might be worse but by manually managing what stuff gets loaded in system RAM and making sure everything fits in the physical memory you can really make sure no 'hiccups' occures as the system transferring textures from virtual memory to VRAM..
Jamie W
04-14-2007, 12:45 AM
I honestly don't know Christian; and I defo don't fully understand all the issues here. My mind is still not made up on the issue (to choose option A or B).
If I manually manage textures to / from VRAM:
a) For users with more MB video card, there is more (unnessasary) moving about of textures.
b) As you point out, there is less chance of system memory being filled, and bad consequence of using virtual ram (hard drive).
c) This may be better for users with lower spec systems, but worse for users with higher spec systems?
So:
If my game has less MB of textures, it can be better to let the system manage them.
If my game has many MB of textures, it can be better to manage them manually.
Backov
04-14-2007, 09:01 AM
Don't try to manually manage VRAM - not only is it not really possible because of the way DirectX/OpenGL work these days, it's not even a good idea - they both do a better job than you will do.
You can give "hints" to the API about what you would like stored in VRAM, and as long as you're smart, you can trust it to be as well.
Spaceman Spiff
04-15-2007, 10:33 AM
I'll sixth that -- Don't worry about explicitly managing VRAM, that's DirectX's/OpenGL's job.
In addition to not wasting the layout space on your textures, do make sure to use the most compact texture format appropriate for your image data.
Use DXT1-5 where suitable, and for those textures where the 4x4 DXT cell artifacts would be a problem, strongly consider using 8-bit palletized textures* . With a unique palette per texture possible, I've found it to be a rare case** where 256 colors weren't enough.
* You may know that newer cards have not been supporting palletized textures in hardware for a while now, but if you use an older interface like DX7, know that the driver will just make a pixel shader that emulates the palette with a dependant texture read. If you are using something current like DX9, writing the shader is trivial, even with filtering.
** Alpha data can be the trouble spot. Most programs that do color reduction (quantization) from true color to 8-bit don't bother with the alpha channel. There's a couple out there that do, but I don't have references handy.
vBulletin v3.6.0, Copyright ©2000-2008, Jelsoft Enterprises Ltd.