Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- dlls/wined3d/adapter_gl.c | 33 ++++++++++++++++ dlls/wined3d/adapter_vk.c | 33 ++++++++++++++++ dlls/wined3d/directx.c | 33 ++++++++++++++++ dlls/wined3d/swapchain.c | 90 +++++++++++++++++++++++++++--------------- dlls/wined3d/wined3d_private.h | 16 ++++++++ 5 files changed, 173 insertions(+), 32 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 86e347d8562..e60437d2812 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4649,6 +4649,37 @@ static void adapter_gl_uninit_3d(struct wined3d_device *device) wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); }
+static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) +{ + struct wined3d_swapchain *swapchain_gl; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_gl = heap_alloc_zero(sizeof(*swapchain_gl)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_gl_init(swapchain_gl, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_gl); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_gl); + *swapchain = swapchain_gl; + + return hr; +} + +static void adapter_gl_destroy_swapchain(struct wined3d_swapchain *swapchain) +{ + wined3d_swapchain_cleanup(swapchain); + heap_free(swapchain); +} + static const struct wined3d_adapter_ops wined3d_adapter_gl_ops = { adapter_gl_destroy, @@ -4660,6 +4691,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops = adapter_gl_check_format, adapter_gl_init_3d, adapter_gl_uninit_3d, + adapter_gl_create_swapchain, + adapter_gl_destroy_swapchain, };
static BOOL wined3d_adapter_gl_init(struct wined3d_adapter_gl *adapter_gl, diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c index 0dc64580702..a3098475595 100644 --- a/dlls/wined3d/adapter_vk.c +++ b/dlls/wined3d/adapter_vk.c @@ -463,6 +463,37 @@ static void adapter_vk_uninit_3d(struct wined3d_device *device) wined3d_context_cleanup(context_vk); }
+static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) +{ + struct wined3d_swapchain *swapchain_vk; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_vk = heap_alloc_zero(sizeof(*swapchain_vk)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_vk_init(swapchain_vk, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_vk); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_vk); + *swapchain = swapchain_vk; + + return hr; +} + +static void adapter_vk_destroy_swapchain(struct wined3d_swapchain *swapchain) +{ + wined3d_swapchain_cleanup(swapchain); + heap_free(swapchain); +} + static const struct wined3d_adapter_ops wined3d_adapter_vk_ops = { adapter_vk_destroy, @@ -474,6 +505,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops = adapter_vk_check_format, adapter_vk_init_3d, adapter_vk_uninit_3d, + adapter_vk_create_swapchain, + adapter_vk_destroy_swapchain, };
static unsigned int wined3d_get_wine_vk_version(void) diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 967348dd00e..d175842e4c0 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -2354,6 +2354,37 @@ static void adapter_no3d_uninit_3d(struct wined3d_device *device) wined3d_context_cleanup(context_no3d); }
+static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) +{ + struct wined3d_swapchain *swapchain_no3d; + HRESULT hr; + + TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", + device, desc, parent, parent_ops, swapchain); + + if (!(swapchain_no3d = heap_alloc_zero(sizeof(*swapchain_no3d)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_swapchain_no3d_init(swapchain_no3d, device, desc, parent, parent_ops))) + { + WARN("Failed to initialise swapchain, hr %#x.\n", hr); + heap_free(swapchain_no3d); + return hr; + } + + TRACE("Created swapchain %p.\n", swapchain_no3d); + *swapchain = swapchain_no3d; + + return hr; +} + +static void adapter_no3d_destroy_swapchain(struct wined3d_swapchain *swapchain) +{ + wined3d_swapchain_cleanup(swapchain); + heap_free(swapchain); +} + static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops = { adapter_no3d_destroy, @@ -2365,6 +2396,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops = adapter_no3d_check_format, adapter_no3d_init_3d, adapter_no3d_uninit_3d, + adapter_no3d_create_swapchain, + adapter_no3d_destroy_swapchain, };
static void wined3d_adapter_no3d_init_d3d_info(struct wined3d_adapter *adapter, unsigned int wined3d_creation_flags) diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 43907755b62..4d277c7a5e2 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -32,7 +32,7 @@ static void wined3d_swapchain_destroy_object(void *object) swapchain_destroy_contexts(object); }
-static void swapchain_cleanup(struct wined3d_swapchain *swapchain) +void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { HRESULT hr; UINT i; @@ -131,12 +131,10 @@ ULONG CDECL wined3d_swapchain_decref(struct wined3d_swapchain *swapchain) wined3d_device_uninit_3d(device); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
- swapchain_cleanup(swapchain); swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent); + swapchain->device->adapter->adapter_ops->adapter_destroy_swapchain(swapchain);
wined3d_mutex_unlock(); - - heap_free(swapchain); }
return refcount; @@ -578,7 +576,7 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, context_release(context); }
-static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain) +static void swapchain_frontbuffer_updated(struct wined3d_swapchain *swapchain) { struct wined3d_texture *front_buffer = swapchain->front_buffer; struct wined3d_context *context; @@ -592,7 +590,19 @@ static void swapchain_gl_frontbuffer_updated(struct wined3d_swapchain *swapchain static const struct wined3d_swapchain_ops swapchain_gl_ops = { swapchain_gl_present, - swapchain_gl_frontbuffer_updated, + swapchain_frontbuffer_updated, +}; + +static void swapchain_vk_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, + const RECT *dst_rect, unsigned int swap_interval, uint32_t flags) +{ + FIXME("Not implemented.\n"); +} + +static const struct wined3d_swapchain_ops swapchain_vk_ops = +{ + swapchain_vk_present, + swapchain_frontbuffer_updated, };
static void swapchain_gdi_frontbuffer_updated(struct wined3d_swapchain *swapchain) @@ -684,7 +694,7 @@ static void swapchain_gdi_present(struct wined3d_swapchain *swapchain, swapchain_gdi_frontbuffer_updated(swapchain); }
-static const struct wined3d_swapchain_ops swapchain_gdi_ops = +static const struct wined3d_swapchain_ops swapchain_no3d_ops = { swapchain_gdi_present, swapchain_gdi_frontbuffer_updated, @@ -783,8 +793,9 @@ static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *stat return hr; }
-static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, - struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, + const struct wined3d_swapchain_ops *swapchain_ops) { const struct wined3d_adapter *adapter = device->adapter; struct wined3d_resource_desc texture_desc; @@ -795,6 +806,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 HWND window; HRESULT hr;
+ wined3d_mutex_lock(); + if (desc->backbuffer_count > 1) { FIXME("The application requested more than one back buffer, this is not properly supported.\n" @@ -806,15 +819,11 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 && desc->swap_effect != WINED3D_SWAP_EFFECT_COPY) FIXME("Unimplemented swap effect %#x.\n", desc->swap_effect);
- if (device->wined3d->flags & WINED3D_NO3D) - swapchain->swapchain_ops = &swapchain_gdi_ops; - else - swapchain->swapchain_ops = &swapchain_gl_ops; - window = desc->device_window ? desc->device_window : device->create_parms.focus_window; if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window, device->wined3d, adapter->ordinal))) return hr;
+ swapchain->swapchain_ops = swapchain_ops; swapchain->device = device; swapchain->parent = parent; swapchain->parent_ops = parent_ops; @@ -973,6 +982,8 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3
wined3d_swapchain_get_gamma_ramp(swapchain, &swapchain->orig_gamma);
+ wined3d_mutex_unlock(); + return WINED3D_OK;
err: @@ -1006,30 +1017,47 @@ err: wined3d_texture_decref(swapchain->front_buffer); }
+ wined3d_mutex_unlock(); + return hr; }
+HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("swapchain_no3d %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_no3d, device, desc, parent, parent_ops); + + return wined3d_swapchain_init(swapchain_no3d, device, desc, parent, parent_ops, &swapchain_no3d_ops); +} + +HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain *swapchain_gl, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("swapchain_gl %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_gl, device, desc, parent, parent_ops); + + return wined3d_swapchain_init(swapchain_gl, device, desc, parent, parent_ops, &swapchain_gl_ops); +} + +HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain *swapchain_vk, struct wined3d_device *device, + struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops) +{ + TRACE("swapchain_vk %p, device %p, desc %p, parent %p, parent_ops %p.\n", + swapchain_vk, device, desc, parent, parent_ops); + + return wined3d_swapchain_init(swapchain_vk, device, desc, parent, parent_ops, &swapchain_vk_ops); +} + HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain) { struct wined3d_swapchain *object; HRESULT hr;
- TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n", - device, desc, parent, parent_ops, swapchain); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; - - wined3d_mutex_lock(); - hr = swapchain_init(object, device, desc, parent, parent_ops); - wined3d_mutex_unlock(); - if (FAILED(hr)) - { - WARN("Failed to initialize swapchain, hr %#x.\n", hr); - heap_free(object); + if (FAILED(hr = device->adapter->adapter_ops->adapter_create_swapchain(device, + desc, parent, parent_ops, &object))) return hr; - }
if (desc->flags & WINED3D_SWAPCHAIN_HOOK) wined3d_hook_swapchain(object); @@ -1040,18 +1068,16 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win if (FAILED(hr = wined3d_device_set_implicit_swapchain(device, object))) { wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - swapchain_cleanup(object); + device->adapter->adapter_ops->adapter_destroy_swapchain(object); wined3d_mutex_unlock(); - heap_free(swapchain); return hr; } wined3d_mutex_unlock(); }
- TRACE("Created swapchain %p.\n", object); *swapchain = object;
- return WINED3D_OK; + return hr; }
static struct wined3d_context *swapchain_create_context(struct wined3d_swapchain *swapchain) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c628b2fa80d..e63d5e65c2f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2775,6 +2775,9 @@ struct wined3d_adapter_ops const struct wined3d_format *ds_format); HRESULT (*adapter_init_3d)(struct wined3d_device *device); void (*adapter_uninit_3d)(struct wined3d_device *device); + HRESULT (*adapter_create_swapchain)(struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain); + void (*adapter_destroy_swapchain)(struct wined3d_swapchain *swapchain); };
/* The adapter structure */ @@ -4233,6 +4236,7 @@ struct wined3d_swapchain };
void wined3d_swapchain_activate(struct wined3d_swapchain *swapchain, BOOL activate) DECLSPEC_HIDDEN; +void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; struct wined3d_context *swapchain_get_context(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; void swapchain_destroy_contexts(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; HDC swapchain_get_backup_dc(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN; @@ -4240,6 +4244,18 @@ void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) DECLSPE void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain, const struct wined3d_device *device) DECLSPEC_HIDDEN;
+HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain *swapchain_gl, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + +HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain *swapchain_vk, + struct wined3d_device *device, struct wined3d_swapchain_desc *desc, + void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN; + /***************************************************************************** * Utility function prototypes */