[PATCH 4/4] wined3d: Allow up to 512 MB of persistently mapped memory on 32-bit architectures.

Zebediah Figura zfigura at codeweavers.com
Sun Jan 30 21:05:27 CST 2022


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
The number comes from patches by Matteo Bruni. I haven't tested it with real
applications, though, and I don't make claims as to its appropriateness.

 dlls/wined3d/adapter_vk.c      | 26 +++++++++++++++++++++-----
 dlls/wined3d/context_gl.c      | 10 +++++++++-
 dlls/wined3d/context_vk.c      | 25 ++++++++++++++++++++-----
 dlls/wined3d/cs.c              |  3 +++
 dlls/wined3d/directx.c         |  7 +++++++
 dlls/wined3d/wined3d_private.h | 15 ++++++++++-----
 6 files changed, 70 insertions(+), 16 deletions(-)

diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 17ff6c2678f..c2c47cf8be1 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -381,7 +381,10 @@ static void wined3d_allocator_vk_destroy_chunk(struct wined3d_allocator_chunk *c
     vk_info = &device_vk->vk_info;
 
     if (chunk_vk->c.map_ptr)
+    {
         VK_CALL(vkUnmapMemory(device_vk->vk_device, chunk_vk->vk_memory));
+        adapter_adjust_mapped_memory(device_vk->d.adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE);
+    }
     VK_CALL(vkFreeMemory(device_vk->vk_device, chunk_vk->vk_memory, NULL));
     TRACE("Freed memory 0x%s.\n", wine_dbgstr_longlong(chunk_vk->vk_memory));
     wined3d_allocator_chunk_cleanup(&chunk_vk->c);
@@ -794,6 +797,8 @@ static void *wined3d_bo_vk_map(struct wined3d_bo_vk *bo, struct wined3d_context_
             ERR("Failed to map slab.\n");
             return NULL;
         }
+
+        bo->b.persistent = slab->bo.b.persistent;
     }
     else if (bo->memory)
     {
@@ -804,14 +809,24 @@ static void *wined3d_bo_vk_map(struct wined3d_bo_vk *bo, struct wined3d_context_
             ERR("Failed to map chunk.\n");
             return NULL;
         }
+
+        bo->b.persistent = chunk_vk->c.persistent;
     }
-    else if ((vr = VK_CALL(vkMapMemory(device_vk->vk_device, bo->vk_memory, 0, VK_WHOLE_SIZE, 0, &bo->b.map_ptr))) < 0)
+    else
     {
-        ERR("Failed to map memory, vr %s.\n", wined3d_debug_vkresult(vr));
-        return NULL;
-    }
+        size_t mapped_size;
+
+        if ((vr = VK_CALL(vkMapMemory(device_vk->vk_device, bo->vk_memory, 0, VK_WHOLE_SIZE, 0, &bo->b.map_ptr))) < 0)
+        {
+            ERR("Failed to map memory, vr %s.\n", wined3d_debug_vkresult(vr));
+            return NULL;
+        }
 
-    bo->b.persistent = wined3d_map_persistent();
+        mapped_size = adapter_adjust_mapped_memory(device_vk->d.adapter, bo->size);
+        bo->b.persistent = (mapped_size < MAX_PERSISTENT_MAPPED_BYTES);
+        if (!bo->b.persistent)
+            WARN_(d3d_perf)("Not mapping BO %p as persistent.\n", bo);
+    }
 
     return bo->b.map_ptr;
 }
@@ -842,6 +857,7 @@ static void wined3d_bo_vk_unmap(struct wined3d_bo_vk *bo, struct wined3d_context
     vk_info = context_vk->vk_info;
     device_vk = wined3d_device_vk(context_vk->c.device);
     VK_CALL(vkUnmapMemory(device_vk->vk_device, bo->vk_memory));
+    adapter_adjust_mapped_memory(device_vk->d.adapter, -bo->size);
 }
 
 static void wined3d_bo_slab_vk_lock(struct wined3d_bo_slab_vk *slab_vk, struct wined3d_context_vk *context_vk)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 6479413df47..0ad2a28c461 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2674,6 +2674,7 @@ static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo, struct wined3d_context_
     const struct wined3d_gl_info *gl_info;
     struct wined3d_bo_user *bo_user;
     struct wined3d_bo_gl tmp;
+    size_t mapped_size;
 
     if (flags & WINED3D_MAP_NOOVERWRITE)
         goto map;
@@ -2710,11 +2711,13 @@ map:
     gl_info = context_gl->gl_info;
     wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
 
+    mapped_size = adapter_adjust_mapped_memory(device_gl->d.adapter, bo->size);
+
     if (gl_info->supported[ARB_BUFFER_STORAGE])
     {
         GLbitfield gl_flags;
 
-        bo->b.persistent = wined3d_map_persistent();
+        bo->b.persistent = (mapped_size < MAX_PERSISTENT_MAPPED_BYTES);
 
         /* When mapping the bo persistently, we need to use the access flags
          * used to create the bo, instead of the access flags passed to the
@@ -2772,6 +2775,8 @@ static void wined3d_bo_gl_unmap(struct wined3d_bo_gl *bo, struct wined3d_context
     GL_EXTCALL(glUnmapBuffer(bo->binding));
     wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
     checkGLcall("Unmap buffer object");
+
+    adapter_adjust_mapped_memory(context_gl->c.device->adapter, -bo->size);
 }
 
 void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
@@ -2927,6 +2932,9 @@ void wined3d_context_gl_destroy_bo(struct wined3d_context_gl *context_gl, struct
     GL_EXTCALL(glDeleteBuffers(1, &bo->id));
     checkGLcall("buffer object destruction");
     bo->id = 0;
+
+    if (bo->b.map_ptr)
+        adapter_adjust_mapped_memory(context_gl->c.device->adapter, -bo->size);
 }
 
 bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizeiptr size,
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 97c60719489..52f5d0c44aa 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -27,6 +27,7 @@
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 
 VkCompareOp vk_compare_op_from_wined3d(enum wined3d_cmp_func op)
 {
@@ -261,6 +262,7 @@ void *wined3d_allocator_chunk_vk_map(struct wined3d_allocator_chunk_vk *chunk_vk
 {
     struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
     const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    size_t mapped_size;
     void *map_ptr;
     VkResult vr;
 
@@ -269,12 +271,20 @@ void *wined3d_allocator_chunk_vk_map(struct wined3d_allocator_chunk_vk *chunk_vk
 
     wined3d_allocator_chunk_vk_lock(chunk_vk);
 
-    if (!chunk_vk->c.map_ptr && (vr = VK_CALL(vkMapMemory(device_vk->vk_device,
-            chunk_vk->vk_memory, 0, VK_WHOLE_SIZE, 0, &chunk_vk->c.map_ptr))) < 0)
+    if (!chunk_vk->c.map_ptr)
     {
-        ERR("Failed to map chunk memory, vr %s.\n", wined3d_debug_vkresult(vr));
-        wined3d_allocator_chunk_vk_unlock(chunk_vk);
-        return NULL;
+        if ((vr = VK_CALL(vkMapMemory(device_vk->vk_device,
+                chunk_vk->vk_memory, 0, VK_WHOLE_SIZE, 0, &chunk_vk->c.map_ptr))) < 0)
+        {
+            ERR("Failed to map chunk memory, vr %s.\n", wined3d_debug_vkresult(vr));
+            wined3d_allocator_chunk_vk_unlock(chunk_vk);
+            return NULL;
+        }
+
+        mapped_size = adapter_adjust_mapped_memory(device_vk->d.adapter, WINED3D_ALLOCATOR_CHUNK_SIZE);
+        chunk_vk->c.persistent = (mapped_size < MAX_PERSISTENT_MAPPED_BYTES);
+        if (!chunk_vk->c.persistent)
+            WARN_(d3d_perf)("Not mapping chunk %p as persistent.\n", chunk_vk);
     }
 
     ++chunk_vk->c.map_count;
@@ -305,6 +315,8 @@ void wined3d_allocator_chunk_vk_unmap(struct wined3d_allocator_chunk_vk *chunk_v
     chunk_vk->c.map_ptr = NULL;
 
     wined3d_allocator_chunk_vk_unlock(chunk_vk);
+
+    adapter_adjust_mapped_memory(device_vk->d.adapter, -WINED3D_ALLOCATOR_CHUNK_SIZE);
 }
 
 VkDeviceMemory wined3d_context_vk_allocate_vram_chunk_memory(struct wined3d_context_vk *context_vk,
@@ -976,7 +988,10 @@ void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const
     }
 
     if (bo->b.map_ptr)
+    {
         VK_CALL(vkUnmapMemory(device_vk->vk_device, bo->vk_memory));
+        adapter_adjust_mapped_memory(device_vk->d.adapter, -bo->size);
+    }
     wined3d_context_vk_destroy_vk_memory(context_vk, bo->vk_memory, bo->command_buffer_id);
 }
 
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 67933a90c5d..498dd2b69dd 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -22,6 +22,7 @@
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
 WINE_DECLARE_DEBUG_CHANNEL(d3d_sync);
 WINE_DECLARE_DEBUG_CHANNEL(fps);
 
@@ -3090,6 +3091,8 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
 
             if (!addr.buffer_object || addr.buffer_object->persistent)
                 client->addr = addr;
+            else
+                WARN_(d3d_perf)("BO %p is not persistently mapped.\n", addr.buffer_object);
         }
         else
         {
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 1b34d2eceaa..e8c86f3dc02 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -157,6 +157,13 @@ UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
     return adapter->vram_bytes_used;
 }
 
+ssize_t adapter_adjust_mapped_memory(struct wined3d_adapter *adapter, ssize_t size)
+{
+    ssize_t ret = InterlockedExchangeAddSizeT(&adapter->mapped_size, size) + size;
+    TRACE("Adjusted mapped adapter memory by %zd to %zd.\n", size, ret);
+    return ret;
+}
+
 void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
 {
     unsigned int output_idx;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c0dd2cee037..fe72559d399 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3457,6 +3457,12 @@ struct wined3d_output
 
 HRESULT wined3d_output_get_gamma_ramp(struct wined3d_output *output, struct wined3d_gamma_ramp *ramp) DECLSPEC_HIDDEN;
 
+#ifdef _WIN64
+#define MAX_PERSISTENT_MAPPED_BYTES SSIZE_MAX
+#else
+#define MAX_PERSISTENT_MAPPED_BYTES (512 * 1024 * 1024)
+#endif
+
 /* The adapter structure */
 struct wined3d_adapter
 {
@@ -3475,6 +3481,8 @@ struct wined3d_adapter
     void *formats;
     size_t format_size;
 
+    ssize_t mapped_size;
+
     const struct wined3d_vertex_pipe_ops *vertex_pipe;
     const struct wined3d_fragment_pipe_ops *fragment_pipe;
     const struct wined3d_state_entry_template *misc_state_template;
@@ -3554,6 +3562,7 @@ BOOL wined3d_adapter_gl_init_format_info(struct wined3d_adapter *adapter,
 BOOL wined3d_adapter_no3d_init_format_info(struct wined3d_adapter *adapter) DECLSPEC_HIDDEN;
 BOOL wined3d_adapter_vk_init_format_info(struct wined3d_adapter_vk *adapter_vk,
         const struct wined3d_vk_info *vk_info) DECLSPEC_HIDDEN;
+ssize_t adapter_adjust_mapped_memory(struct wined3d_adapter *adapter, ssize_t size) DECLSPEC_HIDDEN;
 UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount) DECLSPEC_HIDDEN;
 
 BOOL wined3d_caps_gl_ctx_test_viewport_subpixel_bits(struct wined3d_caps_gl_ctx *ctx) DECLSPEC_HIDDEN;
@@ -4015,6 +4024,7 @@ struct wined3d_allocator_chunk
     struct list available[WINED3D_ALLOCATOR_CHUNK_ORDER_COUNT];
     struct wined3d_allocator *allocator;
     unsigned int map_count;
+    bool persistent;
     void *map_ptr;
 };
 
@@ -6636,11 +6646,6 @@ static inline void wined3d_context_gl_reference_buffer(struct wined3d_context_gl
     wined3d_context_gl_reference_bo(context_gl, wined3d_bo_gl(buffer->buffer_object));
 }
 
-static inline bool wined3d_map_persistent(void)
-{
-    return sizeof(void *) >= sizeof(uint64_t);
-}
-
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 
-- 
2.34.1




More information about the wine-devel mailing list