Signed-off-by: Henri Verbeet hverbeet@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 {