Commit 831ff102 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

wined3d: Keep a client reference count for the BO map pointer.

Currently this has no effect. Depending on whether wined3d_map_persistent() returns true, either the client thread doesn't access the map pointer outside of d3d map requests, or the BO is never unmapped. However, we'd like to be able to let NOOVERWRITE maps be accelerated while still being able to unmap arbitrary BOs at arbitrary times from the CS thread. Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent a13fc3bb
...@@ -831,7 +831,18 @@ static void wined3d_bo_vk_unmap(struct wined3d_bo_vk *bo, struct wined3d_context ...@@ -831,7 +831,18 @@ static void wined3d_bo_vk_unmap(struct wined3d_bo_vk *bo, struct wined3d_context
return; return;
} }
wined3d_device_bo_map_lock(context_vk->c.device);
/* The mapping is still in use by the client (viz. for an accelerated
* NOOVERWRITE map). The client will trigger another unmap request when the
* d3d application requests to unmap the BO. */
if (bo->b.client_map_count)
{
wined3d_device_bo_map_unlock(context_vk->c.device);
TRACE("BO %p is still in use by a client thread; not unmapping.\n", bo);
return;
}
bo->b.map_ptr = NULL; bo->b.map_ptr = NULL;
wined3d_device_bo_map_unlock(context_vk->c.device);
if ((slab = bo->slab)) if ((slab = bo->slab))
{ {
......
...@@ -2953,7 +2953,18 @@ static void wined3d_bo_gl_unmap(struct wined3d_bo_gl *bo, struct wined3d_context ...@@ -2953,7 +2953,18 @@ static void wined3d_bo_gl_unmap(struct wined3d_bo_gl *bo, struct wined3d_context
return; return;
} }
wined3d_device_bo_map_lock(context_gl->c.device);
/* The mapping is still in use by the client (viz. for an accelerated
* NOOVERWRITE map). The client will trigger another unmap request when the
* d3d application requests to unmap the BO. */
if (bo->b.client_map_count)
{
wined3d_device_bo_map_unlock(context_gl->c.device);
TRACE("BO %p is still in use by a client thread; not unmapping.\n", bo);
return;
}
bo->b.map_ptr = NULL; bo->b.map_ptr = NULL;
wined3d_device_bo_map_unlock(context_gl->c.device);
wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id); wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
GL_EXTCALL(glUnmapBuffer(bo->binding)); GL_EXTCALL(glUnmapBuffer(bo->binding));
...@@ -3220,6 +3231,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei ...@@ -3220,6 +3231,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
bo->b.buffer_offset = buffer_offset; bo->b.buffer_offset = buffer_offset;
bo->b.memory_offset = bo->b.buffer_offset; bo->b.memory_offset = bo->b.buffer_offset;
bo->b.map_ptr = NULL; bo->b.map_ptr = NULL;
bo->b.client_map_count = 0;
return true; return true;
} }
......
...@@ -463,6 +463,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context ...@@ -463,6 +463,7 @@ static bool wined3d_context_vk_create_slab_bo(struct wined3d_context_vk *context
*bo = slab->bo; *bo = slab->bo;
bo->memory = NULL; bo->memory = NULL;
bo->slab = slab; bo->slab = slab;
bo->b.client_map_count = 0;
bo->b.map_ptr = NULL; bo->b.map_ptr = NULL;
bo->b.buffer_offset = idx * object_size; bo->b.buffer_offset = idx * object_size;
bo->b.memory_offset = slab->bo.b.memory_offset + bo->b.buffer_offset; bo->b.memory_offset = slab->bo.b.memory_offset + bo->b.buffer_offset;
...@@ -541,6 +542,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic ...@@ -541,6 +542,7 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
return FALSE; return FALSE;
} }
bo->b.client_map_count = 0;
bo->b.map_ptr = NULL; bo->b.map_ptr = NULL;
bo->b.buffer_offset = 0; bo->b.buffer_offset = 0;
bo->size = size; bo->size = size;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "wined3d_private.h" #include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
WINE_DECLARE_DEBUG_CHANNEL(d3d_sync); WINE_DECLARE_DEBUG_CHANNEL(d3d_sync);
WINE_DECLARE_DEBUG_CHANNEL(fps); WINE_DECLARE_DEBUG_CHANNEL(fps);
...@@ -3079,7 +3080,7 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str ...@@ -3079,7 +3080,7 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
struct wined3d_client_resource *client = &resource->client; struct wined3d_client_resource *client = &resource->client;
struct wined3d_device *device = context->device; struct wined3d_device *device = context->device;
struct wined3d_bo_address addr; struct wined3d_bo_address addr;
const struct wined3d_bo *bo; struct wined3d_bo *bo;
uint8_t *map_ptr; uint8_t *map_ptr;
if (flags & WINED3D_MAP_DISCARD) if (flags & WINED3D_MAP_DISCARD)
...@@ -3095,13 +3096,29 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str ...@@ -3095,13 +3096,29 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str
addr = client->addr; addr = client->addr;
} }
bo = addr.buffer_object; map_ptr = NULL;
map_ptr = bo ? bo->map_ptr : NULL; if ((bo = addr.buffer_object))
{
wined3d_device_bo_map_lock(device);
if ((map_ptr = bo->map_ptr))
++bo->client_map_count;
wined3d_device_bo_map_unlock(device);
if (!map_ptr)
{
/* adapter_alloc_bo() should have given us a mapped BO if we are
* discarding. */
assert(flags & WINED3D_MAP_NOOVERWRITE);
WARN_(d3d_perf)("Not accelerating a NOOVERWRITE map because the BO is not mapped.\n");
return false;
}
}
map_ptr += (uintptr_t)addr.addr; map_ptr += (uintptr_t)addr.addr;
if (!map_ptr) if (!map_ptr)
{ {
TRACE("Sub-resource is not mapped.\n"); assert(flags & WINED3D_MAP_NOOVERWRITE);
WARN_(d3d_perf)("Not accelerating a NOOVERWRITE map because the sub-resource has no valid address.\n");
return false; return false;
} }
...@@ -3140,14 +3157,23 @@ static bool wined3d_bo_address_is_null(struct wined3d_const_bo_address *addr) ...@@ -3140,14 +3157,23 @@ static bool wined3d_bo_address_is_null(struct wined3d_const_bo_address *addr)
} }
static bool wined3d_cs_unmap_upload_bo(struct wined3d_device_context *context, struct wined3d_resource *resource, static bool wined3d_cs_unmap_upload_bo(struct wined3d_device_context *context, struct wined3d_resource *resource,
unsigned int sub_resource_idx, struct wined3d_box *box, struct upload_bo *bo) unsigned int sub_resource_idx, struct wined3d_box *box, struct upload_bo *upload_bo)
{ {
struct wined3d_client_resource *client = &resource->client; struct wined3d_client_resource *client = &resource->client;
struct wined3d_device *device = context->device;
struct wined3d_bo *bo;
if (wined3d_bo_address_is_null(&client->mapped_upload.addr)) if (wined3d_bo_address_is_null(&client->mapped_upload.addr))
return false; return false;
*bo = client->mapped_upload; if ((bo = client->mapped_upload.addr.buffer_object))
{
wined3d_device_bo_map_lock(device);
--bo->client_map_count;
wined3d_device_bo_map_unlock(device);
}
*upload_bo = client->mapped_upload;
*box = client->mapped_box; *box = client->mapped_box;
memset(&client->mapped_upload, 0, sizeof(client->mapped_upload)); memset(&client->mapped_upload, 0, sizeof(client->mapped_upload));
memset(&client->mapped_box, 0, sizeof(client->mapped_box)); memset(&client->mapped_box, 0, sizeof(client->mapped_box));
......
...@@ -246,6 +246,8 @@ void wined3d_device_cleanup(struct wined3d_device *device) ...@@ -246,6 +246,8 @@ void wined3d_device_cleanup(struct wined3d_device *device)
wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL); wine_rb_destroy(&device->depth_stencil_states, device_leftover_depth_stencil_state, NULL);
wine_rb_destroy(&device->so_descs, device_free_so_desc, NULL); wine_rb_destroy(&device->so_descs, device_free_so_desc, NULL);
wined3d_lock_cleanup(&device->bo_map_lock);
wined3d_decref(device->wined3d); wined3d_decref(device->wined3d);
device->wined3d = NULL; device->wined3d = NULL;
} }
...@@ -5971,6 +5973,8 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined ...@@ -5971,6 +5973,8 @@ HRESULT wined3d_device_init(struct wined3d_device *device, struct wined3d *wined
goto err; goto err;
} }
wined3d_lock_init(&device->bo_map_lock, "wined3d_device.bo_map_lock");
return WINED3D_OK; return WINED3D_OK;
err: err:
......
...@@ -1605,10 +1605,13 @@ do { \ ...@@ -1605,10 +1605,13 @@ do { \
struct wined3d_bo struct wined3d_bo
{ {
/* client_map_count and map_ptr are accessed from both the client and CS
* threads, and protected by wined3d_device.bo_map_lock. */
struct list users; struct list users;
void *map_ptr; void *map_ptr;
size_t buffer_offset; size_t buffer_offset;
size_t memory_offset; size_t memory_offset;
unsigned int client_map_count;
bool coherent; bool coherent;
}; };
...@@ -3946,6 +3949,8 @@ struct wined3d_device ...@@ -3946,6 +3949,8 @@ struct wined3d_device
/* Context management */ /* Context management */
struct wined3d_context **contexts; struct wined3d_context **contexts;
UINT context_count; UINT context_count;
CRITICAL_SECTION bo_map_lock;
}; };
void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_device_cleanup(struct wined3d_device *device) DECLSPEC_HIDDEN;
...@@ -3967,6 +3972,16 @@ HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device, ...@@ -3967,6 +3972,16 @@ HRESULT wined3d_device_set_implicit_swapchain(struct wined3d_device *device,
struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void wined3d_device_uninit_3d(struct wined3d_device *device) DECLSPEC_HIDDEN; void wined3d_device_uninit_3d(struct wined3d_device *device) DECLSPEC_HIDDEN;
static inline void wined3d_device_bo_map_lock(struct wined3d_device *device)
{
EnterCriticalSection(&device->bo_map_lock);
}
static inline void wined3d_device_bo_map_unlock(struct wined3d_device *device)
{
LeaveCriticalSection(&device->bo_map_lock);
}
struct wined3d_device_no3d struct wined3d_device_no3d
{ {
struct wined3d_device d; struct wined3d_device d;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment