From 23aaa7e61202ea8fd85a632203039d0f2c02ed49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 6 Jun 2015 06:53:34 +0200
Subject: [PATCH] wined3d: Use real values for memory accounting on NVIDIA
 cards.

FIXME: Reimplement wined3d_device_get_available_texture_mem
       without using the context on the main thread.
---
 dlls/d3d9/tests/device.c  | 11 +++++++----
 dlls/wined3d/adapter_gl.c | 12 ++++++++++++
 dlls/wined3d/device.c     | 23 +++++++++++++++++++++++
 dlls/wined3d/wined3d_gl.h |  1 +
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index f5c89723cb..60836094cf 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -9579,10 +9579,13 @@ static void test_vidmem_accounting(void)
     }
     vidmem_end = IDirect3DDevice9_GetAvailableTextureMem(device);
 
-    ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
-    diff = vidmem_start - vidmem_end;
-    ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
-            2 * i, diff / 1024 / 1024);
+    todo_wine_if(vidmem_start == vidmem_end)
+    {
+        ok(vidmem_start > vidmem_end, "Expected available texture memory to decrease during texture creation.\n");
+        diff = vidmem_start - vidmem_end;
+        ok(diff > 1024 * 1024 * 2 * i, "Expected a video memory difference of at least %u MB, got %u MB.\n",
+                2 * i, diff / 1024 / 1024);
+    }
 
     for (i = 0; i < ARRAY_SIZE(textures); i++)
     {
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index cedd012c89..ace63ed0c8 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -227,6 +227,7 @@ static const struct wined3d_extension_map gl_extension_map[] =
     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2            },
     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION     },
     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3            },
+    {"GL_NVX_gpu_memory_info",              NVX_GPU_MEMORY_INFO           },
 };
 
 static const struct wined3d_extension_map wgl_extension_map[] =
@@ -1010,6 +1011,17 @@ static const struct wined3d_gpu_description *query_gpu_description(const struct
 
         gpu_description = wined3d_get_gpu_description(vendor, device);
     }
+    else if (gl_info->supported[NVX_GPU_MEMORY_INFO])
+    {
+        GLint vram_kb;
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &vram_kb);
+
+        *vram_bytes = (UINT64)vram_kb * 1024;
+        TRACE("Got 0x%s as video memory from NVX_GPU_MEMORY_INFO extension.\n",
+                wine_dbgstr_longlong(*vram_bytes));
+
+        gpu_description = wined3d_get_gpu_description(vendor, device);
+    }
 
     if ((gpu_description_override = wined3d_get_user_override_gpu_description(vendor, device)))
         gpu_description = gpu_description_override;
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 23ba41c56b..19744f778d 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1266,6 +1266,29 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device
 
     driver_info = &device->adapter->driver_info;
 
+    /* We can not acquire the context unless there is a swapchain. */
+    /*
+    if (device->swapchains && gl_info->supported[NVX_GPU_MEMORY_INFO] &&
+            !wined3d_settings.emulated_textureram)
+    {
+        GLint vram_free_kb;
+        UINT64 vram_free;
+
+        struct wined3d_context *context = context_acquire(device, NULL, 0);
+        gl_info->gl_ops.gl.p_glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &vram_free_kb);
+        vram_free = (UINT64)vram_free_kb * 1024;
+        context_release(context);
+
+        TRACE("Total 0x%s bytes. emulation 0x%s left, driver 0x%s left.\n",
+                wine_dbgstr_longlong(device->adapter->vram_bytes),
+                wine_dbgstr_longlong(device->adapter->vram_bytes - device->adapter->vram_bytes_used),
+                wine_dbgstr_longlong(vram_free));
+
+        vram_free = min(vram_free, device->adapter->vram_bytes - device->adapter->vram_bytes_used);
+        return min(UINT_MAX, vram_free);
+    }
+    */
+
     TRACE("Emulating 0x%s bytes. 0x%s used, returning 0x%s left.\n",
             wine_dbgstr_longlong(driver_info->vram_bytes),
             wine_dbgstr_longlong(device->adapter->vram_bytes_used),
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 5241b6c41e..1aaf108366 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -206,6 +206,7 @@ enum wined3d_gl_extension
     NV_VERTEX_PROGRAM2,
     NV_VERTEX_PROGRAM2_OPTION,
     NV_VERTEX_PROGRAM3,
+    NVX_GPU_MEMORY_INFO,
     /* WGL extensions */
     WGL_ARB_PIXEL_FORMAT,
     WGL_EXT_SWAP_CONTROL,
-- 
2.20.1

