[PATCH 2/4] wined3d: Allocate a new bo for busy DISCARD maps.

Henri Verbeet hverbeet at codeweavers.com
Fri Dec 4 08:45:33 CST 2020


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      |  2 +
 dlls/wined3d/buffer.c          | 26 ------------
 dlls/wined3d/context_gl.c      | 72 ++++++++++++++++++++++++++++------
 dlls/wined3d/resource.c        |  5 +--
 dlls/wined3d/view.c            | 25 +++++++++++-
 dlls/wined3d/wined3d_private.h |  9 +++++
 6 files changed, 95 insertions(+), 44 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 4781622d530..b6be5854714 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4867,6 +4867,7 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour
      * the refcount on a device that's in the process of being destroyed. */
     if (swapchain_count)
         wined3d_device_incref(device);
+    list_remove(&view_gl->bo_user.entry);
     wined3d_shader_resource_view_cleanup(&view_gl->v);
     wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl);
     if (swapchain_count)
@@ -4913,6 +4914,7 @@ static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_ac
      * the refcount on a device that's in the process of being destroyed. */
     if (swapchain_count)
         wined3d_device_incref(device);
+    list_remove(&view_gl->bo_user.entry);
     wined3d_unordered_access_view_cleanup(&view_gl->v);
     wined3d_view_gl_destroy(device, &view_gl->gl_view, &view_gl->counter_bo, view_gl);
     if (swapchain_count)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index e179f202cb8..acedc1a183e 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -714,29 +714,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
     return buffer->resource.parent;
 }
 
-/* The caller provides a context and binds the buffer */
-static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
-        uint32_t flags, struct wined3d_context_gl *context_gl)
-{
-    const struct wined3d_gl_info *gl_info = context_gl->gl_info;
-    struct wined3d_bo_gl *bo = &buffer_gl->bo;
-
-    /* No fencing needs to be done if the app promises not to overwrite
-     * existing data. */
-    if (flags & WINED3D_MAP_NOOVERWRITE)
-        return;
-
-    if (flags & WINED3D_MAP_DISCARD)
-    {
-        wined3d_buffer_gl_bind(buffer_gl, context_gl);
-
-        GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage));
-        checkGLcall("glBufferData");
-        bo->command_fence_id = 0;
-        return;
-    }
-}
-
 static void buffer_mark_used(struct wined3d_buffer *buffer)
 {
     buffer->flags &= ~WINED3D_BUFFER_DISCARD;
@@ -954,9 +931,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
                 if (buffer->flags & WINED3D_BUFFER_DISCARD)
                     flags &= ~WINED3D_MAP_DISCARD;
 
-                if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
-                    wined3d_buffer_gl_sync_apple(wined3d_buffer_gl(buffer), flags, wined3d_context_gl(context));
-
                 addr.buffer_object = buffer->buffer_object;
                 addr.addr = 0;
                 buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags);
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 305ca0507ff..f2f6185ecc6 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2650,20 +2650,39 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_
     wined3d_context_gl_poll_fences(context_gl);
 }
 
-void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
-        const struct wined3d_bo_address *data, size_t size, uint32_t flags)
+static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo,
+        struct wined3d_context_gl *context_gl, size_t offset, size_t size, uint32_t flags)
 {
     struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
     const struct wined3d_gl_info *gl_info;
-    struct wined3d_bo_gl *bo;
-    BYTE *memory;
+    struct wined3d_bo_user *bo_user;
+    struct wined3d_bo_gl tmp;
+    uint8_t *map_ptr;
 
-    if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
-        return data->addr;
-
-    if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+    if (flags & WINED3D_MAP_NOOVERWRITE)
         goto map;
 
+    if ((flags & WINED3D_MAP_DISCARD) && bo->command_fence_id > device_gl->completed_fence_id)
+    {
+        if (wined3d_context_gl_create_bo(context_gl, bo->size,
+                bo->binding, bo->usage, bo->coherent, bo->flags, &tmp))
+        {
+            list_move_head(&tmp.users, &bo->users);
+            wined3d_context_gl_destroy_bo(context_gl, bo);
+            *bo = tmp;
+            list_init(&bo->users);
+            list_move_head(&bo->users, &tmp.users);
+            LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
+            {
+                bo_user->valid = false;
+            }
+
+            goto map;
+        }
+
+        ERR("Failed to create new buffer object.\n");
+    }
+
     if (bo->command_fence_id == device_gl->current_fence_id)
         wined3d_context_gl_submit_command_fence(context_gl);
     wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id);
@@ -2674,19 +2693,33 @@ map:
 
     if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
     {
-        memory = GL_EXTCALL(glMapBufferRange(bo->binding, (INT_PTR)data->addr,
-                size, wined3d_resource_gl_map_flags(flags)));
+        map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, offset, size, wined3d_resource_gl_map_flags(flags)));
     }
     else
     {
-        memory = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
-        memory += (INT_PTR)data->addr;
+        map_ptr = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
+        map_ptr += offset;
     }
 
     wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
     checkGLcall("Map buffer object");
 
-    return memory;
+    return map_ptr;
+}
+
+void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
+        const struct wined3d_bo_address *data, size_t size, uint32_t flags)
+{
+    struct wined3d_bo_gl *bo;
+    void *map_ptr;
+
+    if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
+        return data->addr;
+
+    if (!(map_ptr = wined3d_bo_gl_map(bo, context_gl, (uintptr_t)data->addr, size, flags)))
+        ERR("Failed to map bo.\n");
+
+    return map_ptr;
 }
 
 void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl,
@@ -2821,8 +2854,11 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
 
     TRACE("Created buffer object %u.\n", id);
     bo->id = id;
+    bo->size = size;
     bo->binding = binding;
     bo->usage = usage;
+    bo->flags = flags;
+    bo->coherent = coherent;
     list_init(&bo->users);
     bo->command_fence_id = 0;
 
@@ -3698,6 +3734,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
         const struct wined3d_state *state, unsigned int shader_mask)
 {
     struct wined3d_shader_sampler_map_entry *entry;
+    struct wined3d_shader_resource_view_gl *srv_gl;
     struct wined3d_shader_resource_view *view;
     struct wined3d_buffer_gl *buffer_gl;
     struct wined3d_shader *shader;
@@ -3735,6 +3772,10 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
                 buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource));
                 wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
                 wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+
+                srv_gl = wined3d_shader_resource_view_gl(view);
+                if (!srv_gl->bo_user.valid)
+                    wined3d_shader_resource_view_gl_update(srv_gl, context_gl);
             }
             else
             {
@@ -3747,6 +3788,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
 static void context_gl_load_unordered_access_resources(struct wined3d_context_gl *context_gl,
         const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views)
 {
+    struct wined3d_unordered_access_view_gl *uav_gl;
     struct wined3d_unordered_access_view *view;
     struct wined3d_buffer_gl *buffer_gl;
     struct wined3d_texture *texture;
@@ -3768,6 +3810,10 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl
             wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
             wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER);
             wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+
+            uav_gl = wined3d_unordered_access_view_gl(view);
+            if (!uav_gl->bo_user.valid)
+                wined3d_unordered_access_view_gl_update(uav_gl, context_gl);
         }
         else
         {
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index f6e233d8057..2b2088ab771 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -451,12 +451,9 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
         ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
     if (d3d_flags & WINED3D_MAP_READ)
         ret |= GL_MAP_READ_BIT;
-    else if (!(d3d_flags & WINED3D_MAP_DISCARD))
+    else
         ret |= GL_MAP_UNSYNCHRONIZED_BIT;
 
-    if (d3d_flags & WINED3D_MAP_DISCARD)
-        ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
-
     return ret;
 }
 
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 1abbbac4fb4..f2c8ceab461 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -268,7 +268,8 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
     wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
 
     view->target = GL_TEXTURE_BUFFER;
-    gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
+    if (!view->name)
+        gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
 
     wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name);
     if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
@@ -916,6 +917,14 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
     return view->parent;
 }
 
+void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
+        struct wined3d_context_gl *context_gl)
+{
+    create_buffer_view(&srv_gl->gl_view, &context_gl->c, &srv_gl->v.desc,
+            buffer_from_resource(srv_gl->v.resource), srv_gl->v.format);
+    srv_gl->bo_user.valid = true;
+}
+
 static void wined3d_shader_resource_view_gl_cs_init(void *object)
 {
     struct wined3d_shader_resource_view_gl *view_gl = object;
@@ -936,6 +945,8 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object)
 
         context = context_acquire(resource->device, NULL, 0);
         create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
+        view_gl->bo_user.valid = true;
+        list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
         context_release(context);
     }
     else
@@ -1006,6 +1017,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
     if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
         return hr;
 
+    list_init(&view_gl->bo_user.entry);
     wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
 
     return hr;
@@ -1394,6 +1406,14 @@ void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_
     wined3d_buffer_invalidate_location(buffer, ~dst_location);
 }
 
+void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
+        struct wined3d_context_gl *context_gl)
+{
+    create_buffer_view(&uav_gl->gl_view, &context_gl->c, &uav_gl->v.desc,
+            buffer_from_resource(uav_gl->v.resource), uav_gl->v.format);
+    uav_gl->bo_user.valid = true;
+}
+
 static void wined3d_unordered_access_view_gl_cs_init(void *object)
 {
     struct wined3d_unordered_access_view_gl *view_gl = object;
@@ -1410,6 +1430,8 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
 
         context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0));
         create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format);
+        view_gl->bo_user.valid = true;
+        list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
         if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
         {
             struct wined3d_bo_gl *bo = &view_gl->counter_bo;
@@ -1470,6 +1492,7 @@ HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_vi
     if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
         return hr;
 
+    list_init(&view_gl->bo_user.entry);
     wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
 
     return hr;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 67a55c4dedd..a82defbbe7f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1572,9 +1572,12 @@ do {                                                                \
 struct wined3d_bo_gl
 {
     GLuint id;
+    GLsizeiptr size;
     GLenum binding;
     GLenum usage;
 
+    GLbitfield flags;
+    bool coherent;
     struct list users;
     uint64_t command_fence_id;
 };
@@ -5014,6 +5017,7 @@ void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *
 struct wined3d_shader_resource_view_gl
 {
     struct wined3d_shader_resource_view v;
+    struct wined3d_bo_user bo_user;
     struct wined3d_gl_view gl_view;
 };
 
@@ -5028,6 +5032,8 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl
 HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
         const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
         void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
+        struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
 
 struct wined3d_view_vk
 {
@@ -5083,6 +5089,7 @@ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_v
 struct wined3d_unordered_access_view_gl
 {
     struct wined3d_unordered_access_view v;
+    struct wined3d_bo_user bo_user;
     struct wined3d_gl_view gl_view;
     struct wined3d_bo_gl counter_bo;
 };
@@ -5098,6 +5105,8 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
 HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl,
         const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
         void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
+        struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
 
 struct wined3d_unordered_access_view_vk
 {
-- 
2.20.1




More information about the wine-devel mailing list