PDA

View Full Version : VRAM and Memory Pools. Help!


Nautilus
10-13-2005, 04:03 PM
Hi,
I'm using a sort of texture database class that manages textures for me.
Nothing fancy. It just:
- loads and keeps textures in SYSTEMMEM pool;
- upload textures to DEFAULT pool when needed (SetTexture() call);
- kicks textures from DEFAULT pool in case they 'expire'.

I consider 'expired' the Texture that sit-duck in DEFAULT pool,
unused for X time (that is, X time has passed since last SetTexture() call for that Texture).

Now, for the issue you probably noticed:
What happens when I upload to DEFAULT pool so many Textures that they eat
up more than the available memory?

That's the main problem :dry:

In theory the call to upload the exceeding Textures to DEFAULT pool
should fail.
In practice I don't know why this doesn't happen.

I realized I've always been using enough Texture memory to consume all my
64 MB VRAM... and more.

AFAIK even the Front and Back Buffers reside in DEFAULT pool.
So VRAM immediately drops as I create a working Device.
Let's assume I'm left with 63 MB.

Now, if I put in DEFAULT pool 256 Textures (each 256x256x32bpp, no MipMaps)
I end up with exactly 64 MB just for the Textures.
Which should be more than the available memory.
But I get no errors (?!).
Does it mean that Front and Back buffers are not stored in VRAM?
Ok, new test: Textures + MipMaps.

If for each of the 256 Textures I create a complete MipMap chain
(down to 1x1), the overall Tex. mem. usage becomes 85.3 MB.
Clearly more than what my card can hold.
Yet, I can successifully use this many textures (?!?!).

I'm puzzled :mellow:

I'd like to make my class smarter and detect whether or not there's
room for another Texture in DEFAULT pool, and react accordingly.
Gotta understand how things work, first...

Please, shed some light.
In which cases VRAM is used, and how memory pools work?

Thanks a lot in advance!
Regards.

Goz
10-14-2005, 02:21 AM
Aren't you forgetting about AGP memory?

Alex
10-14-2005, 03:20 AM
Most that has been said here:
http://www.devmaster.net/forums/showthread.php?t=4082
applies to textures as well. You can create a ddraw7 device to query the available memory (video+agp separated) but it's kinda hacky to do so. By the way, there is no way knowing how much mem a texture is going to take up in vid/agp mem exactly. The texture might have a header and some alignment added by th driver. So knowing how much mem is left will give you a hint how many textues *might* fit into the mem.
You should use managed textures where possible.

Alex

Nautilus
10-14-2005, 06:32 AM
@ Goz:
Aren't you forgetting about AGP memory?
Can you elaborate on that?
I know there's AGP memory, but I ignore when and for what is used.
I ignore how much it is as well.
By looking at the GetAvailableTextureMem() function provided by D3D I take now that AGP is used in conjunction with VRAM when it comes down to DEFAULT pool (knowing some more details would be nicer though), and this explains why I'm able to use so much more Textures than what my VRAM can hold.
Am I correct?
Then how can I know in which memory my resources are placed?
The optimal solution would be to place the (most) important stuff in VRAM and let the rest take either VRAM or AGP.
(... guess I'm beating a dead horse, here :blush:)
Well, can I control this at all?



@ Alex:
Thanks for the link (very informative), and I agree with you about D3D crappyness in memory management.

You can create a ddraw7 device to query the available memory (video+agp separated) but it's kinda hacky to do so.
Why d'you say "hacky"?

I know nothing of DDraw, but I'm interested in what you say.
Even a brief explanation will be most appreciated. Pleeeease? :wub:

Thanks for help!

Goz
10-14-2005, 08:01 AM
Can you elaborate on that?
I know there's AGP memory, but I ignore when and for what is used.
I ignore how much it is as well.
By looking at the GetAvailableTextureMem() function provided by D3D I take now that AGP is used in conjunction with VRAM when it comes down to DEFAULT pool (knowing some more details would be nicer though), and this explains why I'm able to use so much more Textures than what my VRAM can hold.
Am I correct?

Yes .. the driver makes a decision as to where the best place is ...

Then how can I know in which memory my resources are placed?

AS far as i know .. you don't ...

The optimal solution would be to place the (most) important stuff in VRAM and let the rest take either VRAM or AGP.
(... guess I'm beating a dead horse, here :blush:)
Well, can I control this at all?

Well ... no ... no you can't. I'd recommend using managed resources and then you can use IDirect3DResource9::SetPriority to force things to hang around in VRAM longer ... Managed does, pretty much, exactly what you are talking about. PLUS its in the card manufacturers best interest to make sur ethe algorithm for doing it is absoloutely optimal ... who knows how the cards work internally? Your method may be sub optimal on some cards and with managed resources its ALL done optimally for a given piece of hardware :)

Alex
10-14-2005, 09:37 AM
GOZ>The problem with hw vendor interests is that they are not 100% the users/programmers interest. HW vendors want to sell new hw. By suppling a basically unscaleable/unpredictable memory management/interface they force customers to buy a gfx card that is at least as good as the gfx bord the game has been developed on. Otherwise there is NO guaranty that it will run at any decent perf. With a proper mem api games could be made a lot more scaleable so that they run well on most gfx cards out there (hence bigger use base, hence more sales of the title). Games must supported the latest gfx features to some extend to be "fancy" gfx wise (also for marketing).

Nautilus>Importand stuff (things that SHOULD end up in vid mem rather the slower agp mem) have to be allocated before less importand stuff. (So render targets first etc..).
And you are right, GetAvailTexMem() gives you AGP+on board vid mem. As said before these values are mere hints because they don't allow you to calculate exactely how many textures you can fit as the actual in memory footprint is unknown to you.
Basically agp memory is system memory(the chips on your mainboard) that can be accessed directly through agp bus. It is mapped especially for that purpose and is nto available to the os to be used as normal system memory. It's not cached on the cpu so writing to it (from the cpu)needs some special considerations (search intel for agp write burst). Depending on the agp revision different peak throughputs can be achieved on agp memory. So accessing agp memory from the gfx card is somewhat faster than accessing other system memory but it is a lot slower than video memory (chips on your gfx board). Check http://graphics.tomshardware.com/graphic/19970805/ for more details.

Alex

Nautilus
10-14-2005, 10:48 AM
*moved in my next post, below Alex's*

Nautilus
10-14-2005, 10:54 AM
Thanks again, guys.
So I can't explicitly decide where to place things...

I was about to post an idea, but Alex's reply came before I
finished writing.

*modifies his post*

Ok, basically VRAM/AGP allocation is a "first come first serve"
thing: if VRAM is available, DEFAULT pool resources end up in it, else they get placed into AGP.

Idea.
If I know how much VRAM a card is equipped with, I can
them "reserve" it by loading dummy resources to DEFAULT
pool until they occupy all VRAM (or just a subportion to be
sure, like 62 MB out of 64 -considering memory alignment
issues and, possibly, additional data Direct3D stores along
with raw data we uploaded-)
Then, later on, I can overwrite the dummy resources with
the real high-priority ones the app need to use.
In this way becomes possible to track VRAM and AGP usage.
Or is this all wrong?

Problem now is: how to retrieve the amount of VRAM
onboard the card my app is using?

Alex
10-14-2005, 03:17 PM
If you allocate a texture of x*y to story many different textures in it and then you have overcome the problems of alignment and header. You'll be able to store a texture(or many smaller ones) that all together take up x*y mem in there without having to deal with alignment and header issues. But you'll get problems with filtering/mipmaps and texture borders. It is possible to execute your ideas for vertex and index buffers (I did that and it works). You should under no circumstances allocate 100% (or anything near that) for one resource type e.g. textures) because vidram is needed for many other things as well (frame buffer, vertex/index buffers, vertex shaders,...). So unless you know exactely what you're doing..use managed textures and buffers!

But you're right, it pretty much works with first come first server (+ the priority stuff).

Alex

Goz
10-16-2005, 04:33 AM
GOZ>The problem with hw vendor interests is that they are not 100% the users/programmers interest. HW vendors want to sell new hw. By suppling a basically unscaleable/unpredictable memory management/interface they force customers to buy a gfx card that is at least as good as the gfx bord the game has been developed on. Otherwise there is NO guaranty that it will run at any decent perf. With a proper mem api games could be made a lot more scaleable so that they run well on most gfx cards out there (hence bigger use base, hence more sales of the title). Games must supported the latest gfx features to some extend to be "fancy" gfx wise (also for marketing).

I can't agree there. Regardless the manufacturers have shown themselves to be very willing to make things "right" so that developers can have an easier task doing things like this. DirectX just doesn't expose enough information to do this kind of self managed allocation scheme alas. And even the info it DOES supply is often badly implemented by IHVs.

To the best of my knowledge Managed is the way that Microsoft recommends, along with nVidia and ATI as well as a whole raft of professional developers. As best i know most games are now done usign it because it IS the best solution available. I know that everyone i know developing PC stuff (as well as the only game i've had released on PC) all use Managed.

But, of course, if you want to make it difficult for yourself .. do go ahead! I'll go with the easier plan myself ;)

Alex
10-16-2005, 07:15 AM
I agree that the interface provided is insufficient to do something like that.
I also agree that using managed stuff is the best way to go currently cause of the insufficient interface.
So yes..managed is the best solution available. BUT it is NOT the best solution that could be provided because it is not really scaleable (that's my whole point). So the HW vendors and microsoft have agreed on a solution that guarantees them lots of hardware sales and is workable in most cases (that's just my guess).
Tem Sweene told me that unreal one uses a kinda selfmade vertex/index buffer management that allocates one big buffer and manages smalles subbuffers inside cause it enabled a perf gain on nvidia hw at the time.
The sad reality is that ms together with the hw vendors provide SOMETHING. Then the developers are left to get it to do what they want without killing perf totally.
A lot of things aren't properly implemented even in the hardware..certain texture caches are not talking to each other causing undefined behaviour when executing certain valid d3d commands etc... So the current 3d hw is in pretty bad shape as soon you try to do anything that is not standard...

Quite frankly, when working on my last comercial 3d engine we had to go through major pains(as anyone who needs to push many polys on d3d today)
because all the stuff you need (instancing, many cheap dips, more const regs to avoid splitting up models for skinning, etc...) is not properly and broadly supported.

On the other hand, hw vendors are quite willing to aid you coding around internal hardware issiues and avoiding the "non standard" paths that make things slow. But that's just patchwork, not curing the actual problem.

Alex