[PATCH 5/5] wined3d: Try to allocate new OpenGL BOs from the client thread for DISCARD maps.

Zebediah Figura zfigura at codeweavers.com
Tue Feb 15 21:28:13 CST 2022


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      | 43 ++++++++++++++++++++++++++++++++++
 dlls/wined3d/buffer.c          |  2 +-
 dlls/wined3d/cs.c              | 36 ++++++++++++++++++++++++++++
 dlls/wined3d/wined3d_private.h |  4 ++++
 4 files changed, 84 insertions(+), 1 deletion(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index bc54f46222f..cb0c34823aa 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4616,6 +4616,49 @@ static void adapter_gl_flush_bo_address(struct wined3d_context *context,
 static bool adapter_gl_alloc_bo(struct wined3d_device *device, struct wined3d_resource *resource,
         unsigned int sub_resource_idx, struct wined3d_bo_address *addr)
 {
+    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    struct wined3d_device_gl *device_gl = wined3d_device_gl(device);
+
+    wined3d_not_from_cs(device->cs);
+    assert(device->context_count);
+
+    if (resource->type == WINED3D_RTYPE_BUFFER)
+    {
+        GLenum usage = GL_STATIC_DRAW;
+        struct wined3d_bo_gl *bo_gl;
+        bool coherent = true;
+
+        if (resource->usage & WINED3DUSAGE_DYNAMIC)
+        {
+            usage = GL_STREAM_DRAW_ARB;
+            coherent = false;
+        }
+
+        if (!(bo_gl = heap_alloc(sizeof(*bo_gl))))
+            return false;
+
+        if (!(wined3d_device_gl_create_bo(device_gl, NULL, resource->size,
+                wined3d_buffer_gl_binding_from_bind_flags(gl_info, resource->bind_flags),
+                usage, coherent, wined3d_resource_gl_storage_flags(resource), bo_gl)))
+        {
+            WARN("Failed to create OpenGL buffer.\n");
+            heap_free(bo_gl);
+            return false;
+        }
+
+        addr->buffer_object = &bo_gl->b;
+        addr->addr = NULL;
+
+        if (!bo_gl->b.map_ptr)
+        {
+            WARN_(d3d_perf)("BO %p (chunk %p) is not persistently mapped.\n",
+                    bo_gl, bo_gl->memory ? bo_gl->memory->chunk : NULL);
+            wined3d_cs_map_bo_address(device->cs, addr, resource->size, WINED3D_MAP_WRITE | WINED3D_MAP_DISCARD);
+        }
+
+        return true;
+    }
+
     return false;
 }
 
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 7c3537e466e..434e21402db 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -137,7 +137,7 @@ void wined3d_buffer_invalidate_location(struct wined3d_buffer *buffer, DWORD loc
     wined3d_buffer_invalidate_range(buffer, location, 0, 0);
 }
 
-static GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, uint32_t bind_flags)
+GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info, uint32_t bind_flags)
 {
     if (!bind_flags)
         return GL_PIXEL_UNPACK_BUFFER;
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 56abc146733..0986165a59d 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -120,6 +120,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_UNLOAD_RESOURCE,
     WINED3D_CS_OP_MAP,
     WINED3D_CS_OP_UNMAP,
+    WINED3D_CS_OP_MAP_BO_ADDRESS,
     WINED3D_CS_OP_BLT_SUB_RESOURCE,
     WINED3D_CS_OP_UPDATE_SUB_RESOURCE,
     WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION,
@@ -454,6 +455,14 @@ struct wined3d_cs_unmap
     HRESULT *hr;
 };
 
+struct wined3d_cs_map_bo_address
+{
+    enum wined3d_cs_op opcode;
+    struct wined3d_bo_address addr;
+    size_t size;
+    uint32_t flags;
+};
+
 struct wined3d_cs_blt_sub_resource
 {
     enum wined3d_cs_op opcode;
@@ -594,6 +603,7 @@ static const char *debug_cs_op(enum wined3d_cs_op op)
         WINED3D_TO_STR(WINED3D_CS_OP_UNLOAD_RESOURCE);
         WINED3D_TO_STR(WINED3D_CS_OP_MAP);
         WINED3D_TO_STR(WINED3D_CS_OP_UNMAP);
+        WINED3D_TO_STR(WINED3D_CS_OP_MAP_BO_ADDRESS);
         WINED3D_TO_STR(WINED3D_CS_OP_BLT_SUB_RESOURCE);
         WINED3D_TO_STR(WINED3D_CS_OP_UPDATE_SUB_RESOURCE);
         WINED3D_TO_STR(WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION);
@@ -2550,6 +2560,31 @@ HRESULT wined3d_device_context_emit_unmap(struct wined3d_device_context *context
     return hr;
 }
 
+static void wined3d_cs_exec_map_bo_address(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_map_bo_address *op = data;
+    struct wined3d_context *context;
+
+    context = context_acquire(cs->c.device, NULL, 0);
+    wined3d_context_map_bo_address(context, &op->addr, op->size, op->flags);
+    context_release(context);
+}
+
+void wined3d_cs_map_bo_address(struct wined3d_cs *cs,
+        struct wined3d_bo_address *addr, size_t size, unsigned int flags)
+{
+    struct wined3d_device_context *context = &cs->c;
+    struct wined3d_cs_map_bo_address *op;
+
+    op = wined3d_device_context_require_space(context, sizeof(*op), WINED3D_CS_QUEUE_MAP);
+    op->opcode = WINED3D_CS_OP_MAP_BO_ADDRESS;
+    op->addr = *addr;
+    op->size = size;
+    op->flags = flags;
+    wined3d_device_context_submit(context, WINED3D_CS_QUEUE_MAP);
+    wined3d_device_context_finish(context, WINED3D_CS_QUEUE_MAP);
+}
+
 static void wined3d_cs_exec_blt_sub_resource(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_blt_sub_resource *op = data;
@@ -2968,6 +3003,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_UNLOAD_RESOURCE             */ wined3d_cs_exec_unload_resource,
     /* WINED3D_CS_OP_MAP                         */ wined3d_cs_exec_map,
     /* WINED3D_CS_OP_UNMAP                       */ wined3d_cs_exec_unmap,
+    /* WINED3D_CS_OP_MAP_BO_ADDRESS              */ wined3d_cs_exec_map_bo_address,
     /* WINED3D_CS_OP_BLT_SUB_RESOURCE            */ wined3d_cs_exec_blt_sub_resource,
     /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE         */ wined3d_cs_exec_update_sub_resource,
     /* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION    */ wined3d_cs_exec_add_dirty_texture_region,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 96ce75fbb58..b8e2a96001a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5018,6 +5018,8 @@ void wined3d_cs_emit_set_render_state(struct wined3d_cs *cs,
 void wined3d_cs_emit_unload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void wined3d_cs_init_object(struct wined3d_cs *cs,
         void (*callback)(void *object), void *object) DECLSPEC_HIDDEN;
+void wined3d_cs_map_bo_address(struct wined3d_cs *cs,
+        struct wined3d_bo_address *addr, size_t size, unsigned int flags) DECLSPEC_HIDDEN;
 
 static inline void wined3d_cs_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id queue_id)
 {
@@ -5201,6 +5203,8 @@ static inline const struct wined3d_buffer_gl *wined3d_buffer_gl_const(const stru
     return CONTAINING_RECORD(buffer, struct wined3d_buffer_gl, b);
 }
 
+GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info,
+        uint32_t bind_flags) DECLSPEC_HIDDEN;
 HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device,
         const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
         void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
-- 
2.34.1




More information about the wine-devel mailing list