[PATCH 5/6] wined3d: Make the adapter responsible for context destruction and allocation.

Henri Verbeet hverbeet at codeweavers.com
Tue May 7 05:30:10 CDT 2019


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      |  48 ++++++++++++++-
 dlls/wined3d/adapter_vk.c      |  28 ++++++++-
 dlls/wined3d/context.c         | 132 +++++++++++++++++++----------------------
 dlls/wined3d/directx.c         |  30 +++++++++-
 dlls/wined3d/wined3d_private.h |  16 ++++-
 5 files changed, 176 insertions(+), 78 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 972d051a6b2..be21fd8f349 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4273,6 +4273,51 @@ static void adapter_gl_destroy_device(struct wined3d_device *device)
     heap_free(device_gl);
 }
 
+static HRESULT adapter_gl_create_context(struct wined3d_swapchain *swapchain, struct wined3d_context **context)
+{
+    struct wined3d_context_gl *context_gl;
+
+    TRACE("swapchain %p, context %p.\n", swapchain, context);
+
+    if (!(context_gl = heap_alloc_zero(sizeof(*context_gl))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(wined3d_context_gl_init(context_gl, swapchain)))
+    {
+        WARN("Failed to initialise context.\n");
+        heap_free(context_gl);
+        return E_FAIL;
+    }
+
+    TRACE("Created context %p.\n", context_gl);
+    *context = &context_gl->c;
+
+    return WINED3D_OK;
+}
+
+static void adapter_gl_destroy_context(struct wined3d_context *context)
+{
+    struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+
+    if (context_gl->c.current && context_gl->c.tid != GetCurrentThreadId())
+    {
+        struct wined3d_gl_info *gl_info;
+
+        /* Make a copy of gl_info for wined3d_context_gl_cleanup() use, the
+         * one in wined3d_adapter may go away in the meantime. */
+        gl_info = heap_alloc(sizeof(*gl_info));
+        *gl_info = *context_gl->c.gl_info;
+        context_gl->c.gl_info = gl_info;
+        context_gl->c.destroyed = 1;
+
+        return;
+    }
+
+    wined3d_context_gl_cleanup(context_gl);
+    TlsSetValue(context_get_tls_idx(), NULL);
+    heap_free(context_gl);
+}
+
 static void adapter_gl_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
 {
     const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
@@ -4558,7 +4603,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
     adapter_gl_destroy,
     adapter_gl_create_device,
     adapter_gl_destroy_device,
-    wined3d_adapter_gl_create_context,
+    adapter_gl_create_context,
+    adapter_gl_destroy_context,
     adapter_gl_get_wined3d_caps,
     adapter_gl_check_format,
     adapter_gl_init_3d,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index d6438945361..4ef142384cd 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -288,9 +288,32 @@ static void adapter_vk_destroy_device(struct wined3d_device *device)
     heap_free(device_vk);
 }
 
-static BOOL adapter_vk_create_context(struct wined3d_context *context)
+static HRESULT adapter_vk_create_context(struct wined3d_swapchain *swapchain, struct wined3d_context **context)
 {
-    return TRUE;
+    struct wined3d_context *context_vk;
+
+    TRACE("swapchain %p, context %p.\n", swapchain, context);
+
+    if (!(context_vk = heap_alloc_zero(sizeof(*context_vk))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(wined3d_context_vk_init(context_vk, swapchain)))
+    {
+        WARN("Failed to initialise context.\n");
+        heap_free(context_vk);
+        return E_FAIL;
+    }
+
+    TRACE("Created context %p.\n", context_vk);
+    *context = context_vk;
+
+    return WINED3D_OK;
+}
+
+static void adapter_vk_destroy_context(struct wined3d_context *context)
+{
+    wined3d_context_cleanup(context);
+    heap_free(context);
 }
 
 static void adapter_vk_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
@@ -416,6 +439,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
     adapter_vk_create_device,
     adapter_vk_destroy_device,
     adapter_vk_create_context,
+    adapter_vk_destroy_context,
     adapter_vk_get_wined3d_caps,
     adapter_vk_check_format,
     adapter_vk_init_3d,
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index fdf7f9ccc65..5cc0c57a514 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1312,7 +1312,7 @@ static void context_update_window(struct wined3d_context *context)
     }
 }
 
-static void wined3d_context_cleanup(struct wined3d_context *context)
+void wined3d_context_cleanup(struct wined3d_context *context)
 {
     struct wined3d_pipeline_statistics_query *pipeline_statistics_query;
     const struct wined3d_gl_info *gl_info = context->gl_info;
@@ -1482,32 +1482,11 @@ static void wined3d_context_cleanup(struct wined3d_context *context)
     heap_free(context->texture_type);
 }
 
-static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
+void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
 {
     wined3d_context_cleanup(&context_gl->c);
 }
 
-static void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl)
-{
-    if (context_gl->c.current && context_gl->c.tid != GetCurrentThreadId())
-    {
-        struct wined3d_gl_info *gl_info;
-
-        /* Make a copy of gl_info for wined3d_context_gl_cleanup() use, the
-         * one in wined3d_adapter may go away in the meantime. */
-        gl_info = heap_alloc(sizeof(*gl_info));
-        *gl_info = *context_gl->c.gl_info;
-        context_gl->c.gl_info = gl_info;
-        context_gl->c.destroyed = 1;
-
-        return;
-    }
-
-    wined3d_context_gl_cleanup(context_gl);
-    TlsSetValue(wined3d_context_tls_idx, NULL);
-    heap_free(context_gl);
-}
-
 DWORD context_get_tls_idx(void)
 {
     return wined3d_context_tls_idx;
@@ -1965,56 +1944,34 @@ static BOOL wined3d_context_init(struct wined3d_context *context, struct wined3d
     return TRUE;
 }
 
-struct wined3d_context *context_create(struct wined3d_swapchain *swapchain)
+HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d, struct wined3d_swapchain *swapchain)
 {
-    struct wined3d_device *device = swapchain->device;
-    struct wined3d_context_gl *context_gl;
-    struct wined3d_context *context;
-
-    TRACE("swapchain %p.\n", swapchain);
-
-    wined3d_from_cs(device->cs);
-
-    if (!(context_gl = heap_alloc_zero(sizeof(*context_gl))))
-        return NULL;
-    context = &context_gl->c;
+    TRACE("context_no3d %p, swapchain %p.\n", context_no3d, swapchain);
 
-    if (!(wined3d_context_init(context, swapchain)))
-    {
-        heap_free(context_gl);
-        return NULL;
-    }
-    if (!(device->adapter->adapter_ops->adapter_create_context(context)))
-    {
-        wined3d_release_dc(context->win_handle, context->hdc);
-        heap_free(context_gl);
-        return NULL;
-    }
-
-    if (!device_context_add(device, context))
-    {
-        ERR("Failed to add the newly created context to the context list\n");
-        wined3d_context_gl_destroy(context_gl);
-        return NULL;
-    }
-
-    TRACE("Created context %p.\n", context);
+    if (!wined3d_context_init(context_no3d, swapchain))
+        return E_FAIL;
 
-    return context;
+    return WINED3D_OK;
 }
 
-BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
+HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wined3d_swapchain *swapchain)
 {
-    struct wined3d_swapchain *swapchain = context->swapchain;
     const struct wined3d_format *color_format, *ds_format;
-    struct wined3d_device *device = context->device;
+    struct wined3d_context *context = &context_gl->c;
     const struct wined3d_d3d_info *d3d_info;
     const struct wined3d_gl_info *gl_info;
     struct wined3d_resource *target;
     unsigned int target_bind_flags;
+    struct wined3d_device *device;
     HGLRC ctx, share_ctx;
     unsigned int i;
 
+    TRACE("context_gl %p, swapchain %p.\n", context_gl, swapchain);
+
+    if (!wined3d_context_init(&context_gl->c, swapchain))
+        return E_FAIL;
+
+    device = context->device;
     gl_info = context->gl_info;
     d3d_info = context->d3d_info;
 
@@ -2031,7 +1988,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
         if (base + WINED3D_MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(context->rev_tex_unit_map))
         {
             ERR("Unexpected texture unit base index %u.\n", base);
-            return FALSE;
+            return E_FAIL;
         }
         for (i = 0; i < min(count, WINED3D_MAX_FRAGMENT_SAMPLERS); ++i)
         {
@@ -2043,7 +2000,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
         if (base + WINED3D_MAX_VERTEX_SAMPLERS > ARRAY_SIZE(context->rev_tex_unit_map))
         {
             ERR("Unexpected texture unit base index %u.\n", base);
-            return FALSE;
+            return E_FAIL;
         }
         for (i = 0; i < min(count, WINED3D_MAX_VERTEX_SAMPLERS); ++i)
         {
@@ -2054,7 +2011,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
 
     if (!(context->texture_type = heap_calloc(gl_info->limits.combined_samplers,
             sizeof(*context->texture_type))))
-        return FALSE;
+        return E_FAIL;
 
     target = &context->current_rt.texture->resource;
     target_bind_flags = target->bind_flags;
@@ -2128,7 +2085,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
     }
 
     if (!context->pixel_format)
-        return FALSE;
+        return E_FAIL;
 
     context_enter(context);
 
@@ -2137,7 +2094,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
         ERR("Failed to set pixel format %d on device context %p.\n", context->pixel_format, context->hdc);
         context_release(context);
         heap_free(context->texture_type);
-        return FALSE;
+        return E_FAIL;
     }
 
     share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
@@ -2147,7 +2104,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
         {
             context_release(context);
             heap_free(context->texture_type);
-            return FALSE;
+            return E_FAIL;
         }
     }
     else
@@ -2157,7 +2114,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
             ERR("Failed to create a WGL context.\n");
             context_release(context);
             heap_free(context->texture_type);
-            return FALSE;
+            return E_FAIL;
         }
 
         if (share_ctx && !wglShareLists(share_ctx, ctx))
@@ -2167,7 +2124,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
             if (!wglDeleteContext(ctx))
                 ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
             heap_free(context->texture_type);
-            return FALSE;
+            return E_FAIL;
         }
     }
 
@@ -2187,7 +2144,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
         if (!wglDeleteContext(ctx))
             ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
         heap_free(context->texture_type);
-        return FALSE;
+        return E_FAIL;
     }
 
     if (context_debug_output_enabled(gl_info))
@@ -2330,7 +2287,42 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
     gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0);
     checkGLcall("glScissor");
 
-    return TRUE;
+    return WINED3D_OK;
+}
+
+HRESULT wined3d_context_vk_init(struct wined3d_context *context_vk, struct wined3d_swapchain *swapchain)
+{
+    TRACE("context_vk %p, swapchain %p.\n", context_vk, swapchain);
+
+    if (!wined3d_context_init(context_vk, swapchain))
+        return E_FAIL;
+
+    return WINED3D_OK;
+}
+
+struct wined3d_context *context_create(struct wined3d_swapchain *swapchain)
+{
+    struct wined3d_device *device = swapchain->device;
+    struct wined3d_context *context;
+    HRESULT hr;
+
+    TRACE("swapchain %p.\n", swapchain);
+
+    wined3d_from_cs(device->cs);
+
+    if (FAILED(hr = device->adapter->adapter_ops->adapter_create_context(swapchain, &context)))
+        return NULL;
+
+    if (!device_context_add(device, context))
+    {
+        ERR("Failed to add the newly created context to the context list.\n");
+        device->adapter->adapter_ops->adapter_destroy_context(context);
+        return NULL;
+    }
+
+    TRACE("Created context %p.\n", context);
+
+    return context;
 }
 
 void wined3d_context_destroy(struct wined3d_context *context)
@@ -2355,7 +2347,7 @@ void wined3d_context_destroy(struct wined3d_context *context)
 
     device_context_remove(device, context);
 
-    wined3d_context_gl_destroy(wined3d_context_gl(context));
+    device->adapter->adapter_ops->adapter_destroy_context(context);
 }
 
 const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 7e6ac823e5a..6fc5c7bf8bf 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2255,9 +2255,32 @@ static void adapter_no3d_destroy_device(struct wined3d_device *device)
     heap_free(device);
 }
 
-static BOOL wined3d_adapter_no3d_create_context(struct wined3d_context *context)
+static HRESULT adapter_no3d_create_context(struct wined3d_swapchain *swapchain, struct wined3d_context **context)
 {
-    return TRUE;
+    struct wined3d_context *context_no3d;
+
+    TRACE("swapchain %p, context %p.\n", swapchain, context);
+
+    if (!(context_no3d = heap_alloc_zero(sizeof(*context_no3d))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(wined3d_context_no3d_init(context_no3d, swapchain)))
+    {
+        WARN("Failed to initialise context.\n");
+        heap_free(context_no3d);
+        return E_FAIL;
+    }
+
+    TRACE("Created context %p.\n", context_no3d);
+    *context = context_no3d;
+
+    return WINED3D_OK;
+}
+
+static void adapter_no3d_destroy_context(struct wined3d_context *context)
+{
+    wined3d_context_cleanup(context);
+    heap_free(context);
 }
 
 static void adapter_no3d_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
@@ -2296,7 +2319,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
     adapter_no3d_destroy,
     adapter_no3d_create_device,
     adapter_no3d_destroy_device,
-    wined3d_adapter_no3d_create_context,
+    adapter_no3d_create_context,
+    adapter_no3d_destroy_context,
     adapter_no3d_get_wined3d_caps,
     adapter_no3d_check_format,
     adapter_no3d_init_3d,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1eec960c045..3934fba4acd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2029,6 +2029,11 @@ struct wined3d_context
     unsigned int scissor_rect_count;
 };
 
+void wined3d_context_cleanup(struct wined3d_context *context) DECLSPEC_HIDDEN;
+
+HRESULT wined3d_context_no3d_init(struct wined3d_context *context_no3d,
+        struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+
 struct wined3d_context_gl
 {
     struct wined3d_context c;
@@ -2039,12 +2044,19 @@ static inline struct wined3d_context_gl *wined3d_context_gl(struct wined3d_conte
     return CONTAINING_RECORD(context, struct wined3d_context_gl, c);
 }
 
+void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
+HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl,
+        struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+
 struct wined3d_fb_state
 {
     struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS];
     struct wined3d_rendertarget_view *depth_stencil;
 };
 
+HRESULT wined3d_context_vk_init(struct wined3d_context *context_vk,
+        struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
+
 typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id);
 
 struct wined3d_state_entry
@@ -2710,7 +2722,8 @@ struct wined3d_adapter_ops
             BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
             struct wined3d_device_parent *device_parent, struct wined3d_device **device);
     void (*adapter_destroy_device)(struct wined3d_device *device);
-    BOOL (*adapter_create_context)(struct wined3d_context *context);
+    HRESULT (*adapter_create_context)(struct wined3d_swapchain *swapchain, struct wined3d_context **context);
+    void (*adapter_destroy_context)(struct wined3d_context *context);
     void (*adapter_get_wined3d_caps)(const struct wined3d_adapter *adapter, struct wined3d_caps *caps);
     BOOL (*adapter_check_format)(const struct wined3d_adapter *adapter,
             const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format,
@@ -2769,7 +2782,6 @@ static inline const struct wined3d_adapter_gl *wined3d_adapter_gl_const(const st
 
 struct wined3d_adapter *wined3d_adapter_gl_create(unsigned int ordinal,
         unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN;
-BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) DECLSPEC_HIDDEN;
 
 struct wined3d_adapter_vk
 {
-- 
2.11.0




More information about the wine-devel mailing list