Signed-off-by: Zebediah Figura zfigura@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"