summaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/nine/resource9.c
diff options
context:
space:
mode:
authorPatrick Rudolph <[email protected]>2015-09-30 16:42:10 +0200
committerAxel Davy <[email protected]>2016-02-04 22:12:17 +0100
commit1a893ac8869a0be08582f3b224d1a92ff37fc400 (patch)
tree6912bfddcb4c3f75a5b7343fd46dc1738d496ca5 /src/gallium/state_trackers/nine/resource9.c
parenta961ec335d5f38c07181e4956341c9b4cca59fa4 (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.c32
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);
}