diff options
author | Patrick Rudolph <[email protected]> | 2015-09-30 16:42:10 +0200 |
---|---|---|
committer | Axel Davy <[email protected]> | 2016-02-04 22:12:17 +0100 |
commit | 1a893ac8869a0be08582f3b224d1a92ff37fc400 (patch) | |
tree | 6912bfddcb4c3f75a5b7343fd46dc1738d496ca5 /src/gallium/state_trackers/nine/resource9.c | |
parent | a961ec335d5f38c07181e4956341c9b4cca59fa4 (diff) |
st/nine: Implement NineDevice9_GetAvailableTextureMem
Implement a device private memory counter similar to Win 7.
Only textures and surfaces increment vidmem and may return
ERR_OUTOFVIDEOMEMORY. Vertexbuffers and indexbuffers creation always
succeedes, even when out of video memory.
Fixes "Vampire: The Masquerade - Bloodlines" allocating resources until crash.
Fixes "Age of Conan" allocating resources until crash.
Fixes failing WINE test device.c test_vidmem_accounting().
Signed-off-by: Patrick Rudolph <[email protected]>
Reviewed-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/nine/resource9.c')
-rw-r--r-- | src/gallium/state_trackers/nine/resource9.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/nine/resource9.c b/src/gallium/state_trackers/nine/resource9.c index 56e85156a29..b929c50a83c 100644 --- a/src/gallium/state_trackers/nine/resource9.c +++ b/src/gallium/state_trackers/nine/resource9.c @@ -29,6 +29,7 @@ #include "util/u_hash_table.h" #include "util/u_inlines.h" +#include "util/u_resource.h" #include "nine_pdata.h" @@ -61,6 +62,33 @@ NineResource9_ctor( struct NineResource9 *This, if (Allocate) { assert(!initResource); + + /* On Windows it is possible allocation fails when + * IDirect3DDevice9::GetAvailableTextureMem() still reports + * enough free space. + * + * Some games allocate surfaces + * in a loop until they receive D3DERR_OUTOFVIDEOMEMORY to measure + * the available texture memory size. + * + * We are not using the drivers VRAM statistics because: + * * This would add overhead to each resource allocation. + * * Freeing memory is lazy and takes some time, but applications + * expects the memory counter to change immediately after allocating + * or freeing memory. + * + * Vertexbuffers and indexbuffers are not accounted ! + */ + if (This->info.target != PIPE_BUFFER) { + This->size = util_resource_size(&This->info); + + This->base.device->available_texture_mem -= This->size; + if (This->base.device->available_texture_mem <= + This->base.device->available_texture_limit) { + return D3DERR_OUTOFVIDEOMEMORY; + } + } + DBG("(%p) Creating pipe_resource.\n", This); This->resource = screen->resource_create(screen, &This->info); if (!This->resource) @@ -91,6 +119,10 @@ NineResource9_dtor( struct NineResource9 *This ) * still hold a reference. */ pipe_resource_reference(&This->resource, NULL); + /* NOTE: size is 0, unless something has actually been allocated */ + if (This->base.device) + This->base.device->available_texture_mem += This->size; + NineUnknown_dtor(&This->base); } |