Commit 5ab6421d authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Make the adapter responsible for context destruction and allocation.

parent 1859ca85
...@@ -4274,6 +4274,51 @@ static void adapter_gl_destroy_device(struct wined3d_device *device) ...@@ -4274,6 +4274,51 @@ static void adapter_gl_destroy_device(struct wined3d_device *device)
heap_free(device_gl); 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) 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; const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
...@@ -4559,7 +4604,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops = ...@@ -4559,7 +4604,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
adapter_gl_destroy, adapter_gl_destroy,
adapter_gl_create_device, adapter_gl_create_device,
adapter_gl_destroy_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_get_wined3d_caps,
adapter_gl_check_format, adapter_gl_check_format,
adapter_gl_init_3d, adapter_gl_init_3d,
......
...@@ -288,9 +288,32 @@ static void adapter_vk_destroy_device(struct wined3d_device *device) ...@@ -288,9 +288,32 @@ static void adapter_vk_destroy_device(struct wined3d_device *device)
heap_free(device_vk); 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) 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 = ...@@ -416,6 +439,7 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
adapter_vk_create_device, adapter_vk_create_device,
adapter_vk_destroy_device, adapter_vk_destroy_device,
adapter_vk_create_context, adapter_vk_create_context,
adapter_vk_destroy_context,
adapter_vk_get_wined3d_caps, adapter_vk_get_wined3d_caps,
adapter_vk_check_format, adapter_vk_check_format,
adapter_vk_init_3d, adapter_vk_init_3d,
......
...@@ -1312,7 +1312,7 @@ static void context_update_window(struct wined3d_context *context) ...@@ -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; struct wined3d_pipeline_statistics_query *pipeline_statistics_query;
const struct wined3d_gl_info *gl_info = context->gl_info; const struct wined3d_gl_info *gl_info = context->gl_info;
...@@ -1482,32 +1482,11 @@ static void wined3d_context_cleanup(struct wined3d_context *context) ...@@ -1482,32 +1482,11 @@ static void wined3d_context_cleanup(struct wined3d_context *context)
heap_free(context->texture_type); 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); 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) DWORD context_get_tls_idx(void)
{ {
return wined3d_context_tls_idx; return wined3d_context_tls_idx;
...@@ -1965,56 +1944,34 @@ static BOOL wined3d_context_init(struct wined3d_context *context, struct wined3d ...@@ -1965,56 +1944,34 @@ static BOOL wined3d_context_init(struct wined3d_context *context, struct wined3d
return TRUE; 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; TRACE("context_no3d %p, swapchain %p.\n", context_no3d, swapchain);
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;
if (!(wined3d_context_init(context, swapchain))) if (!wined3d_context_init(context_no3d, swapchain))
{ return E_FAIL;
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);
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; 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_d3d_info *d3d_info;
const struct wined3d_gl_info *gl_info; const struct wined3d_gl_info *gl_info;
struct wined3d_resource *target; struct wined3d_resource *target;
unsigned int target_bind_flags; unsigned int target_bind_flags;
struct wined3d_device *device;
HGLRC ctx, share_ctx; HGLRC ctx, share_ctx;
unsigned int i; 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; gl_info = context->gl_info;
d3d_info = context->d3d_info; d3d_info = context->d3d_info;
...@@ -2031,7 +1988,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -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)) if (base + WINED3D_MAX_FRAGMENT_SAMPLERS > ARRAY_SIZE(context->rev_tex_unit_map))
{ {
ERR("Unexpected texture unit base index %u.\n", base); 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) 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) ...@@ -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)) if (base + WINED3D_MAX_VERTEX_SAMPLERS > ARRAY_SIZE(context->rev_tex_unit_map))
{ {
ERR("Unexpected texture unit base index %u.\n", base); 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) 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) ...@@ -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, if (!(context->texture_type = heap_calloc(gl_info->limits.combined_samplers,
sizeof(*context->texture_type)))) sizeof(*context->texture_type))))
return FALSE; return E_FAIL;
target = &context->current_rt.texture->resource; target = &context->current_rt.texture->resource;
target_bind_flags = target->bind_flags; target_bind_flags = target->bind_flags;
...@@ -2128,7 +2085,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -2128,7 +2085,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
} }
if (!context->pixel_format) if (!context->pixel_format)
return FALSE; return E_FAIL;
context_enter(context); context_enter(context);
...@@ -2137,7 +2094,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *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); ERR("Failed to set pixel format %d on device context %p.\n", context->pixel_format, context->hdc);
context_release(context); context_release(context);
heap_free(context->texture_type); heap_free(context->texture_type);
return FALSE; return E_FAIL;
} }
share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL; share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
...@@ -2147,7 +2104,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -2147,7 +2104,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
{ {
context_release(context); context_release(context);
heap_free(context->texture_type); heap_free(context->texture_type);
return FALSE; return E_FAIL;
} }
} }
else else
...@@ -2157,7 +2114,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -2157,7 +2114,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
ERR("Failed to create a WGL context.\n"); ERR("Failed to create a WGL context.\n");
context_release(context); context_release(context);
heap_free(context->texture_type); heap_free(context->texture_type);
return FALSE; return E_FAIL;
} }
if (share_ctx && !wglShareLists(share_ctx, ctx)) if (share_ctx && !wglShareLists(share_ctx, ctx))
...@@ -2167,7 +2124,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -2167,7 +2124,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
if (!wglDeleteContext(ctx)) if (!wglDeleteContext(ctx))
ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
heap_free(context->texture_type); heap_free(context->texture_type);
return FALSE; return E_FAIL;
} }
} }
...@@ -2187,7 +2144,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -2187,7 +2144,7 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context)
if (!wglDeleteContext(ctx)) if (!wglDeleteContext(ctx))
ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError()); ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx, GetLastError());
heap_free(context->texture_type); heap_free(context->texture_type);
return FALSE; return E_FAIL;
} }
if (context_debug_output_enabled(gl_info)) if (context_debug_output_enabled(gl_info))
...@@ -2330,7 +2287,42 @@ BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) ...@@ -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); gl_info->gl_ops.gl.p_glScissor(0, 0, 0, 0);
checkGLcall("glScissor"); 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) void wined3d_context_destroy(struct wined3d_context *context)
...@@ -2355,7 +2347,7 @@ 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); 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, const DWORD *context_get_tex_unit_mapping(const struct wined3d_context *context,
......
...@@ -2258,9 +2258,32 @@ static void adapter_no3d_destroy_device(struct wined3d_device *device) ...@@ -2258,9 +2258,32 @@ static void adapter_no3d_destroy_device(struct wined3d_device *device)
heap_free(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) static void adapter_no3d_get_wined3d_caps(const struct wined3d_adapter *adapter, struct wined3d_caps *caps)
...@@ -2299,7 +2322,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops = ...@@ -2299,7 +2322,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
adapter_no3d_destroy, adapter_no3d_destroy,
adapter_no3d_create_device, adapter_no3d_create_device,
adapter_no3d_destroy_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_get_wined3d_caps,
adapter_no3d_check_format, adapter_no3d_check_format,
adapter_no3d_init_3d, adapter_no3d_init_3d,
......
...@@ -2030,6 +2030,11 @@ struct wined3d_context ...@@ -2030,6 +2030,11 @@ struct wined3d_context
unsigned int scissor_rect_count; 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_gl
{ {
struct wined3d_context c; struct wined3d_context c;
...@@ -2040,12 +2045,19 @@ static inline struct wined3d_context_gl *wined3d_context_gl(struct wined3d_conte ...@@ -2040,12 +2045,19 @@ static inline struct wined3d_context_gl *wined3d_context_gl(struct wined3d_conte
return CONTAINING_RECORD(context, struct wined3d_context_gl, c); 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_fb_state
{ {
struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS]; struct wined3d_rendertarget_view *render_targets[MAX_RENDER_TARGET_VIEWS];
struct wined3d_rendertarget_view *depth_stencil; 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); typedef void (*APPLYSTATEFUNC)(struct wined3d_context *ctx, const struct wined3d_state *state, DWORD state_id);
struct wined3d_state_entry struct wined3d_state_entry
...@@ -2712,7 +2724,8 @@ struct wined3d_adapter_ops ...@@ -2712,7 +2724,8 @@ struct wined3d_adapter_ops
BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count, BYTE surface_alignment, const enum wined3d_feature_level *levels, unsigned int level_count,
struct wined3d_device_parent *device_parent, struct wined3d_device **device); struct wined3d_device_parent *device_parent, struct wined3d_device **device);
void (*adapter_destroy_device)(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); void (*adapter_get_wined3d_caps)(const struct wined3d_adapter *adapter, struct wined3d_caps *caps);
BOOL (*adapter_check_format)(const struct wined3d_adapter *adapter, BOOL (*adapter_check_format)(const struct wined3d_adapter *adapter,
const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format, const struct wined3d_format *adapter_format, const struct wined3d_format *rt_format,
...@@ -2771,7 +2784,6 @@ static inline const struct wined3d_adapter_gl *wined3d_adapter_gl_const(const st ...@@ -2771,7 +2784,6 @@ static inline const struct wined3d_adapter_gl *wined3d_adapter_gl_const(const st
struct wined3d_adapter *wined3d_adapter_gl_create(unsigned int ordinal, struct wined3d_adapter *wined3d_adapter_gl_create(unsigned int ordinal,
unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN; unsigned int wined3d_creation_flags) DECLSPEC_HIDDEN;
BOOL wined3d_adapter_gl_create_context(struct wined3d_context *context) DECLSPEC_HIDDEN;
struct wined3d_adapter_vk struct wined3d_adapter_vk
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment