[PATCH 3/3] wined3d: Factor out buffer bo_user invalidation.

Zebediah Figura zfigura at codeweavers.com
Wed Oct 20 00:12:01 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      | 23 ++++++++
 dlls/wined3d/adapter_vk.c      | 10 ++++
 dlls/wined3d/buffer.c          | 98 ++++------------------------------
 dlls/wined3d/directx.c         |  5 ++
 dlls/wined3d/wined3d_private.h | 13 ++++-
 5 files changed, 59 insertions(+), 90 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index f1cdbffe718..86fe40aa73f 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4604,6 +4604,28 @@ static void adapter_gl_flush_bo_address(struct wined3d_context *context,
     wined3d_context_gl_flush_bo_address(wined3d_context_gl(context), data, size);
 }
 
+static void adapter_gl_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+    struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+    struct wined3d_bo_gl *bo_gl = wined3d_bo_gl(bo);
+
+    if (context_gl->c.transform_feedback_active && bo_gl->binding == GL_TRANSFORM_FEEDBACK_BUFFER
+            && wined3d_context_is_graphics_state_dirty(&context_gl->c, STATE_STREAM_OUTPUT))
+    {
+        /* It's illegal to (un)bind GL_TRANSFORM_FEEDBACK_BUFFER while transform
+         * feedback is active. Deleting a buffer implicitly unbinds it, so we
+         * need to end transform feedback here if this buffer was bound.
+         *
+         * This should only be possible if STATE_STREAM_OUTPUT is dirty; if we
+         * do a draw call before destroying this buffer then the draw call will
+         * already rebind the GL target. */
+        WARN("Deleting buffer object %p, disabling transform feedback.\n", bo_gl);
+        wined3d_context_gl_end_transform_feedback(context_gl);
+    }
+
+    wined3d_context_gl_destroy_bo(context_gl, bo_gl);
+}
+
 static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device,
         struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -5057,6 +5079,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
     .adapter_unmap_bo_address = adapter_gl_unmap_bo_address,
     .adapter_copy_bo_address = adapter_gl_copy_bo_address,
     .adapter_flush_bo_address = adapter_gl_flush_bo_address,
+    .adapter_destroy_bo = adapter_gl_destroy_bo,
     .adapter_create_swapchain = adapter_gl_create_swapchain,
     .adapter_destroy_swapchain = adapter_gl_destroy_swapchain,
     .adapter_create_buffer = adapter_gl_create_buffer,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 02a359c4f07..9251f790064 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1182,6 +1182,15 @@ static void adapter_vk_flush_bo_address(struct wined3d_context *context,
     flush_bo_range(context_vk, bo, (uintptr_t)data->addr, size);
 }
 
+static void adapter_vk_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+    struct wined3d_bo_vk *bo_vk = wined3d_bo_vk(bo);
+
+    wined3d_context_vk_destroy_bo(wined3d_context_vk(context), bo_vk);
+    bo_vk->vk_buffer = VK_NULL_HANDLE;
+    bo_vk->memory = NULL;
+}
+
 static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device,
         struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -1834,6 +1843,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
     .adapter_unmap_bo_address = adapter_vk_unmap_bo_address,
     .adapter_copy_bo_address = adapter_vk_copy_bo_address,
     .adapter_flush_bo_address = adapter_vk_flush_bo_address,
+    .adapter_destroy_bo = adapter_vk_destroy_bo,
     .adapter_create_swapchain = adapter_vk_create_swapchain,
     .adapter_destroy_swapchain = adapter_vk_destroy_swapchain,
     .adapter_create_buffer = adapter_vk_create_buffer,
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 55dcd9e67e8..4aa450bcc28 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -164,35 +164,6 @@ static GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_
     return GL_ARRAY_BUFFER;
 }
 
-/* Context activation is done by the caller. */
-static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
-        struct wined3d_context_gl *context_gl)
-{
-    struct wined3d_resource *resource = &buffer_gl->b.resource;
-
-    if (!buffer_gl->b.buffer_object)
-        return;
-
-    if (context_gl->c.transform_feedback_active && (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
-            && wined3d_context_is_graphics_state_dirty(&context_gl->c, STATE_STREAM_OUTPUT))
-    {
-        /* It's illegal to (un)bind GL_TRANSFORM_FEEDBACK_BUFFER while transform
-         * feedback is active. Deleting a buffer implicitly unbinds it, so we
-         * need to end transform feedback here if this buffer was bound.
-         *
-         * This should only be possible if STATE_STREAM_OUTPUT is dirty; if we
-         * do a draw call before destroying this buffer then the draw call will
-         * already rebind the GL target. */
-        WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl);
-        wined3d_context_gl_end_transform_feedback(context_gl);
-    }
-
-    buffer_gl->b.bo_user.valid = false;
-    list_remove(&buffer_gl->b.bo_user.entry);
-    wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
-    buffer_gl->b.buffer_object = 0;
-}
-
 /* Context activation is done by the caller. */
 static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buffer_gl,
         struct wined3d_context_gl *context_gl)
@@ -557,12 +528,6 @@ BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
     return buffer->buffer_ops->buffer_prepare_location(buffer, context, location);
 }
 
-static void wined3d_buffer_unload_location(struct wined3d_buffer *buffer,
-        struct wined3d_context *context, unsigned int location)
-{
-    buffer->buffer_ops->buffer_unload_location(buffer, context, location);
-}
-
 BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
         struct wined3d_context *context, DWORD location)
 {
@@ -674,6 +639,14 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer, struct wined3d_co
     return 0;
 }
 
+static void wined3d_buffer_unload_bo(struct wined3d_buffer *buffer, struct wined3d_context *context)
+{
+    buffer->bo_user.valid = false;
+    list_remove(&buffer->bo_user.entry);
+    context->device->adapter->adapter_ops->adapter_destroy_bo(context, (struct wined3d_bo *)buffer->buffer_object);
+    buffer->buffer_object = 0u;
+}
+
 static void buffer_resource_unload(struct wined3d_resource *resource)
 {
     struct wined3d_buffer *buffer = buffer_from_resource(resource);
@@ -688,7 +661,7 @@ static void buffer_resource_unload(struct wined3d_resource *resource)
 
         wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM);
         wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER);
-        wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
+        wined3d_buffer_unload_bo(buffer, context);
         buffer_clear_dirty_areas(buffer);
 
         context_release(context);
@@ -719,7 +692,7 @@ static void wined3d_buffer_destroy_object(void *object)
     if (buffer->buffer_object)
     {
         context = context_acquire(buffer->resource.device, NULL, 0);
-        wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
+        wined3d_buffer_unload_bo(buffer, context);
         context_release(context);
     }
     heap_free(buffer->conversion_map);
@@ -1238,12 +1211,6 @@ static BOOL wined3d_buffer_no3d_prepare_location(struct wined3d_buffer *buffer,
     return FALSE;
 }
 
-static void wined3d_buffer_no3d_unload_location(struct wined3d_buffer *buffer,
-        struct wined3d_context *context, unsigned int location)
-{
-    TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
-}
-
 static void wined3d_buffer_no3d_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
         const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges)
 {
@@ -1259,7 +1226,6 @@ static void wined3d_buffer_no3d_download_ranges(struct wined3d_buffer *buffer, s
 static const struct wined3d_buffer_ops wined3d_buffer_no3d_ops =
 {
     wined3d_buffer_no3d_prepare_location,
-    wined3d_buffer_no3d_unload_location,
     wined3d_buffer_no3d_upload_ranges,
     wined3d_buffer_no3d_download_ranges,
 };
@@ -1302,23 +1268,6 @@ static BOOL wined3d_buffer_gl_prepare_location(struct wined3d_buffer *buffer,
     }
 }
 
-static void wined3d_buffer_gl_unload_location(struct wined3d_buffer *buffer,
-        struct wined3d_context *context, unsigned int location)
-{
-    TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
-
-    switch (location)
-    {
-        case WINED3D_LOCATION_BUFFER:
-            wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context));
-            break;
-
-        default:
-            ERR("Unhandled location %s.\n", wined3d_debug_location(location));
-            break;
-    }
-}
-
 /* Context activation is done by the caller. */
 static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
         const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges)
@@ -1369,7 +1318,6 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
 static const struct wined3d_buffer_ops wined3d_buffer_gl_ops =
 {
     wined3d_buffer_gl_prepare_location,
-    wined3d_buffer_gl_unload_location,
     wined3d_buffer_gl_upload_ranges,
     wined3d_buffer_gl_download_ranges,
 };
@@ -1480,31 +1428,6 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
     }
 }
 
-static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
-        struct wined3d_context *context, unsigned int location)
-{
-    struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
-    struct wined3d_buffer_vk *buffer_vk = wined3d_buffer_vk(buffer);
-
-    TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
-
-    switch (location)
-    {
-        case WINED3D_LOCATION_BUFFER:
-            buffer_vk->b.bo_user.valid = false;
-            list_remove(&buffer_vk->b.bo_user.entry);
-            wined3d_context_vk_destroy_bo(context_vk, &buffer_vk->bo);
-            buffer_vk->bo.vk_buffer = VK_NULL_HANDLE;
-            buffer_vk->bo.memory = NULL;
-            buffer_vk->b.buffer_object = 0u;
-            break;
-
-        default:
-            ERR("Unhandled location %s.\n", wined3d_debug_location(location));
-            break;
-    }
-}
-
 static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
         const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges)
 {
@@ -1568,7 +1491,6 @@ static void wined3d_buffer_vk_download_ranges(struct wined3d_buffer *buffer, str
 static const struct wined3d_buffer_ops wined3d_buffer_vk_ops =
 {
     wined3d_buffer_vk_prepare_location,
-    wined3d_buffer_vk_unload_location,
     wined3d_buffer_vk_upload_ranges,
     wined3d_buffer_vk_download_ranges,
 };
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index c265bdc8c95..8a5b61dcd68 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2805,6 +2805,10 @@ static void adapter_no3d_flush_bo_address(struct wined3d_context *context,
 {
 }
 
+static void adapter_no3d_destroy_bo(struct wined3d_context *context, struct wined3d_bo *bo)
+{
+}
+
 static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device,
         struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
@@ -3075,6 +3079,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
     .adapter_unmap_bo_address = adapter_no3d_unmap_bo_address,
     .adapter_copy_bo_address = adapter_no3d_copy_bo_address,
     .adapter_flush_bo_address = adapter_no3d_flush_bo_address,
+    .adapter_destroy_bo = adapter_no3d_destroy_bo,
     .adapter_create_swapchain = adapter_no3d_create_swapchain,
     .adapter_destroy_swapchain = adapter_no3d_destroy_swapchain,
     .adapter_create_buffer = adapter_no3d_create_buffer,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8666d9699c9..246fd1d60ea 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1609,6 +1609,11 @@ struct wined3d_bo_gl
     uint64_t command_fence_id;
 };
 
+static inline struct wined3d_bo_gl *wined3d_bo_gl(struct wined3d_bo *bo)
+{
+    return CONTAINING_RECORD(bo, struct wined3d_bo_gl, b);
+}
+
 static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
 {
     return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
@@ -1639,6 +1644,11 @@ struct wined3d_bo_vk
     bool host_synced;
 };
 
+static inline struct wined3d_bo_vk *wined3d_bo_vk(struct wined3d_bo *bo)
+{
+    return CONTAINING_RECORD(bo, struct wined3d_bo_vk, b);
+}
+
 struct wined3d_bo_slab_vk_key
 {
     VkMemoryPropertyFlags memory_type;
@@ -3370,6 +3380,7 @@ struct wined3d_adapter_ops
             const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size);
     void (*adapter_flush_bo_address)(struct wined3d_context *context,
             const struct wined3d_const_bo_address *data, size_t size);
+    void (*adapter_destroy_bo)(struct wined3d_context *context, struct wined3d_bo *bo);
     HRESULT (*adapter_create_swapchain)(struct wined3d_device *device,
             struct wined3d_swapchain_desc *desc,
             struct wined3d_swapchain_state_parent *state_parent, void *parent,
@@ -4982,8 +4993,6 @@ struct wined3d_buffer_ops
 {
     BOOL (*buffer_prepare_location)(struct wined3d_buffer *buffer,
             struct wined3d_context *context, unsigned int location);
-    void (*buffer_unload_location)(struct wined3d_buffer *buffer,
-            struct wined3d_context *context, unsigned int location);
     void (*buffer_upload_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data,
             unsigned int data_offset, unsigned int range_count, const struct wined3d_range *ranges);
     void (*buffer_download_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, void *data,
-- 
2.33.0




More information about the wine-devel mailing list