[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