Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

When trying to using my company's D3D9 renderer and allocating everything in D3DPOOL_MANAGED I would run out of memory in the 32-bit process space.

I tried using our D3D9Ex renderer and allocating in D3DPOOL_DEFAULT, but that's giving me an error of 0x8876017C (D3DERR_OUTOFVIDEOMEMORY).

I'm unclear on what this means. Is this implying that the driver will not manage anything in D3DPOOL_DEFAULT?

I have 2.5GB of AGP space and 4GB of device memory, and all of my application meshes and textures are only 2.4GB on disk. I'm only using about half of those at any given time. Is there some hidden limit I'm bumping into here?

share|improve this question
    
Things stored on disk are usually in a more compressed file format, perhaps that much memory isn't enough? –  akaltar Dec 30 '13 at 15:36

2 Answers 2

up vote 3 down vote accepted

To solve this problem, I'd recommend you build a paging or streaming system. This will allow you to dynamically load and unload resources as they are needed, keeping only what is necessary for the current area of your game on the GPU (instead of trying to keep everything there all the time).

If you have single resources (such as textures) that are overly large, you'll have to consider ways to break them up or reorganize them so you don't have single, monolithic, gigabyte textures floating around.

As to the background, or why you get this error:

D3DERR_OUTOFVIDEOMEMORY means that the graphics device is being asked to utilize more resources in a single frame than will fit in video memory.

Using D3DPOOL_DEFAULT for a resource means that that resource will be placed, based on the set of usage criteria you specify when creating the resource, in the most-appropriate memory pool. This is usually video RAM. The API will not manage anything in the default pool like it would with the D3D_MANAGED pool (if the device is lost, you must release and re-create default-pool resources), if that is what you are wondering about.

The error you are getting means that your resources can't all fit. Keep in mind that

  • the size of a texture or any other buffer data on disk (and even in system RAM) does not necessarily equal the size of the resource once it gets to the graphics card. The data may be reorganized and resized to improve performance. It is unfortunately very difficult to get D3D to give you good statistics about on-GPU memory consumption and breakdown.

  • the driver may subdivide GPU memory into buckets for various uses ("this much" for texture memory, "that much" for vertex buffers). You don't necessarily get the full range of physical GPU RAM to do whatever you want with, so you shouldn't write against that assumption.

  • Direct3D may logically subdivide its memory; consider that even if a default-pool resource is not placed on the GPU, D3D keeps the CPU-side D3DPOOL_MANAGED and D3DPOOL_DEFAULT memory pools distinct.

  • the previous two points will result in memory fragmentation, meaning that even if there is physically enough free RAM floating around to satisfy a request, it might not all be contiguous within the same logic pool and thus the request must be denied. This can, in fact, happen even within a single pool of memory (just like it can on the CPU side of things), resulting in a failed allocation.

  • there are other resources besides the textures or buffers you create from your own data on disk that D3D has to maintain on the GPU; they take up some space as well.

Because it's difficult to get D3D to tell you useful things about GPU memory usage breakdowns, you're likely going to need to assume the worst and take a broader approach to solving the problem (as outlined in the beginning).

share|improve this answer
    
Normally managed memory pool would take care of this problem by auto unloading older resources, however, DX9 Ex doesn't allow managed memory. Do you know if DX11 uses a similar system like the D3DPOOL_MANAGED? I'm having trouble finding this info. –  pauld Dec 30 '13 at 16:38
    
That's really a different line of inquiry than this question, but the short answer is "yes." D3D10+ does away with the 9-style pools and device-loss scenarios. –  Josh Petrie Dec 30 '13 at 16:45
    
@Josh Petrie, the information in your answer is helpful, so I'll probably just go ahead and accept it, but I'm seeing a behavior that your answer doesn't explain. When using D3DPOOL_DEFAULT on DX9EX I was formerly able to get about 1/3 of my scene loaded. But when I switch my usage from D3DUSAGE_DYNAMIC to just 0, that change alone allows me to load 2/3 of my scene. I am speculating here that D3DUSAGE_DYNAMIC makes D3DPOOL_DEFAULT load everything into AGP memory, while a 0 loads everything into GPU memory. Is this a reasonable explanation, or am I witnessing some other phenomenon? –  Jonathan Mee Jan 2 at 13:14
    
I'm not in a position at the moment to look up the actual values for the D3DPOOL_* enumerations, and I don't recall what 0 maps to. It's hard to say, but as far as I know there is no setting to force everything into AGP memory like that, so you may be seeing something that is a driver-specific extension behavior or just a coincidental red herring. –  Josh Petrie Jan 2 at 14:55

Your process address space is actually going to be considerably smaller than you think; for a 32-bit program (and this is true even on 64-bit Windows) it's 2GB, so your 2.4GB of resources are going to considerably overflow that.

One way of working around this is to use special startup switches in your boot.ini (XP or lower) or bcdedit options (Vista or higher), which increases you to 3GB for user mode allocations but at the expense of reducing kernel mode allocations to 1GB. Even if it did work for you, all users of your program would also need to do the same, which is a requirement you shouldn't force on them.

You need to look at that 2.4GB of resources and ask yourself a few questions about it.

First of all, do you really need all 2.4GB loaded at the same time? Most games don't load all resources at once; aside from onerous memory requirements it just takes too much time. That's why games are often divided into "maps", and for each map you only load the resources needed by that map. When the player transitions to a different map you unload resources from the previous one and load resources for the new one.

Secondly, it's likely that a lot of your textures are quite high resolution. Do you really need them to be so high? Reducing texture resolution is a great way of reducing memory requirements, and your program will load faster and run faster too.

Using these approaches you should be able to get your memory usage down to something more manageable.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.