How much video memory do I really have?

Started by
10 comments, last by Krohm 8 years, 12 months ago

In my MacBook Pro (using Bootcamp) on a GeForce GT 750M, the NVidia system information says:

Total available graphics mem: 4096MB

Dedicated video memory: 2048MB GDDR5

System video memory: 2048MB

It's advertised as a 2Gb card but I appear to be running out of video memory at just over 1Gb. I'm handling several 8192x8192 textures for terrain editing (I don't stream whilst using the editor):

2 x D3DFMT_R16F 8192x8192 for flip-flopping the vertex texture (for terrain heights)

1 x D3DFMT_L8 8192x8192 for material type

1 x X8R8G8B8 8192x8192 for terrain normal

That's 4 8192x8192 textures I'm creating - Pix says 6 with an extra D3DFMT_L8 created by Direct3D (not the application) and another X8R8G8B8 - not sure why these are being created, so I've calculated all that (including the ones created without my consent) at 939,524,096 bytes, or 939Mb. The rest of my textures/indexbuffers/vertex buffers according to Pix come to around 70Mb.

That makes it feel to me like I only have 1Gb of space to play in.

Should I be able to use that full 2Gb or not?

Advertisement
are those with or without mipmaps? if you are mipmapping (which I'd expect for a terrain texture, otherwise you'd have noise all over the place and it might render slow) you'd need to add 300MB.

some format might also be not natively supported, e.g L8 might actually be an RGBA8 with just R used.

it also depends on whether your textures are 'dynamic' etc. the driver might create some temporal versions to not stall rendering while the CPU is filling the buffer for the next frame

also, the driver allocates some buffer, maybe 256MB for random stuff
- page table for memory layouts
- shader binaries
- some framebuffer (in 1080p it's 8MB per buffer)
..

windows might allocate some buffer e.g.
- if you alt+tab to another window, it should not fail just because the editor uses all VMem
- there are some textures needed (e.g. the desktop background etc.)
- if you open your task manager and check the extended performance cpu view, you'll see there are probably thousands of 'handles', while those can be everything (windows, fonts, files etc.) if just a few of those are gfx resources (Fonts, DIBs etc.) it can easily accumulate
- (in general, windows is quite crazy in allocating quite a big chunk of resource straight at the start, check how much main memory is gone after booting, that's the percentage of vmem that is probably also gone)

textures also might have some overhead, with mips there might be some alignment, but also some extra space for compression information...
the driver might also divide the memory areas for management reasons (like 128MB for VBs even if you just use 1kb).

in short, NO WAY you can expect to get all you've paid for ;). I always count with 512MB less.

the best way to test it is probably to create a tiny application that allocates 256x256 RGBA32 textures until an allocation fails. place it on desktop, reboot, start it and you'll see your peak budget.

You might be running into memory fragmentation issues. Doesn't mean you're out of video memory, but just that the driver can't find a large enough contiguous space to put a 256MB texture.

shouldn't all modern GPUs support paging? at least nvidia Fermi+ (GTX 4x0 etc.) support the sparse texture extension of OpenGL, which allows you to stick together textures out of random memory pages, so there shouldn't be really a fragmentation >= 64kb of texture size. (unless the drivers restrict that for some reason).

While the GPU may support paging, it's obvious that the OP is using D3D9 which predates this level of hardware, so paging may not be available in the runtime or driver.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Thanks for the replies guys. I'm not using mipmaps for these textures, they're not for display. The 8bit one is accessed with a point filter and is used to determine which material is used at that vertex point and serves as a way for me to blend layers. The R12F ones are both vertex textures used for the heights - I have two because I'm using a shader to raise/lower/smooth the terrain and I need to pass in the vertex texture in order to average across pixels for smoothing. The normal map covers the entire terrain and I need this to happen (even in game mode) because I need that much distant detail. In game mode, I stream in the vertex textures so I have more memory then.

This gets weirder though, I got the out of memory issue when I tried to write the normal map out to disk to see what it looked like. If I don't do that, it all works fine without running out of memory - I even changed my R12F floating point vertex textures back to R32F and it still works fine. I've been flying around the 8192x8192 terrain with full normal map and umpteen detail layers with no memory issues.

I wonder what happens internally when you save texture to disk - it's only that which runs out of memory.

The fragmentation comment was interesting - as these textures are (should be) always on the GPU, are they susceptible to fragmentation or is that only when textures are loaded/unloaded/loaded, etc?

It would depend on how you're saving to disk, really. Are you using D3DXSaveSurfaceToFile or rolling your own?

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.


The fragmentation comment was interesting - as these textures are (should be) always on the GPU, are they susceptible to fragmentation or is that only when textures are loaded/unloaded/loaded, etc?

I actually don't know, but I assumed. Maybe someone who knows more can answer. I don't know enough about the details of how

a D3D9 texture is managed on the GPU - but if anyone external to the driver (or whatever) holds a pointer to that memory, then it can't be moved around in the GPU's (presumably 32-bit?) address space, so I assume you'd be subject to fragmentation.

When exactly do you get the out of memory error? What API call are you making? D3DXSaveTextureToFile? So maybe it's just related to that function. Maybe it writes to a memory buffer first and it can't allocate a big enough chunk? Is this a 32-bit process?

What does the DirectX debug runtime say? Anything interesting?

It would depend on how you're saving to disk, really. Are you using D3DXSaveSurfaceToFile or rolling your own?

Yes (albeit D3DXSaveTextureToFile)


The fragmentation comment was interesting - as these textures are (should be) always on the GPU, are they susceptible to fragmentation or is that only when textures are loaded/unloaded/loaded, etc?

I actually don't know, but I assumed. Maybe someone who knows more can answer. I don't know enough about the details of how

a D3D9 texture is managed on the GPU - but if anyone external to the driver (or whatever) holds a pointer to that memory, then it can't be moved around in the GPU's (presumably 32-bit?) address space, so I assume you'd be subject to fragmentation.

When exactly do you get the out of memory error? What API call are you making? D3DXSaveTextureToFile? So maybe it's just related to that function. Maybe it writes to a memory buffer first and it can't allocate a big enough chunk? Is this a 32-bit process?

What does the DirectX debug runtime say? Anything interesting?

It's a Win 32 bit process. The runtime just says out of memory and the HRESULT for D3DXSaveTextureToFile also returns the code for out of memory. It's quite odd, I've created a couple more 8192 x 8192 textures on top since the error and it's still working fine and they are being used. I guess I just won't call that method and roll my own.

Thanks all

shouldn't all modern GPUs support paging? at least nvidia Fermi+ (GTX 4x0 etc.) support the sparse texture extension of OpenGL, which allows you to stick together textures out of random memory pages, so there shouldn't be really a fragmentation >= 64kb of texture size. (unless the drivers restrict that for some reason).

Under Win32, the biggest fragmentation issue is address space - each process has ~31.5 bits to address all of it's resources.
Virtual paging does nothing to fix address space fragmentation - e.g. even if paging let's us assume that the physical RAM is infinite, we need to be able to claim a large contiguous block of virtual addresses/pages.

As for the D3D9 era, they might not use paging, and might even store addresses using <24bits in places (e.g. by assuming 256byte alignment, 23 bits can fully address 2GB).

As for mips, on disk they add an extra ~33%, but sometimes in video RAM they can add ~mip0pitch*(mip0height-1) -- aka (~100%).

Are you running fullscreen or windowed? Fullscreen might reduce the amout of VRAM that the OS is reserving for itself.

This topic is closed to new replies.

Advertisement