-- v2: wined3d: Don't use separate GL contexts for different swapchains. wined3d: Destroy primary GL context if initialization fails. wined3d: Move backup window / DC handling from the swapchain to the device. wined3d: Get rid of a redundant branch. wined3d: Remove unnecessary index increment in wined3d_context_gl_cleanup_resources(). wined3d: Don't try to access unused buffers in wined3d_context_gl_load_numbered_arrays().
From: Matteo Bruni mbruni@codeweavers.com
wined3d_stream_info_from_declaration() doesn't update elements of the stream_info structure that are not used by the current vertex declaration. That means that there might be obsolete buffer references in stream_info, possibly to buffers that have since been destroyed. --- dlls/wined3d/context_gl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index af46cd9dfd7..5df0865824c 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -5675,7 +5675,6 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c for (i = 0; i < gl_info->limits.vertex_attribs; ++i) { const struct wined3d_stream_info_element *element = &stream_info->elements[i]; - const void *offset = get_vertex_attrib_pointer(element, state); const struct wined3d_stream_state *stream; const struct wined3d_format_gl *format_gl;
@@ -5733,6 +5732,7 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c
if (element->stride) { + const void *offset = get_vertex_attrib_pointer(element, state); unsigned int format_attrs = format_gl->f.attrs;
bo = wined3d_bo_gl_id(element->data.buffer_object);
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/context_gl.c | 2 -- 1 file changed, 2 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 5df0865824c..c790157fd0a 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -2663,8 +2663,6 @@ static void wined3d_context_gl_cleanup_resources(struct wined3d_context_gl *cont wined3d_device_gl_free_memory(device_gl, r->block); if (i != --count) *r = blocks[count]; - else - ++i; } device_gl->retired_block_count = count; }
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/device.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7a37a27b0cd..b7d0b1adebc 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -5848,6 +5848,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, device_init_swapchain_state(device, swapchain); if (wined3d_settings.logo) device_load_logo(device, wined3d_settings.logo); + + hr = device->adapter->adapter_ops->adapter_init_3d(device); } else { @@ -5857,12 +5859,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, wined3d_device_context_set_depth_stencil_view(context, view); }
- if (reset_state) - hr = device->adapter->adapter_ops->adapter_init_3d(device); - - /* All done. There is no need to reload resources or shaders, this will happen automatically on the - * first use - */ + /* All done. There is no need to reload resources or shaders, this will + * happen automatically on the first use. */ return hr; }
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/context_gl.c | 16 +++++++-------- dlls/wined3d/device.c | 35 +++++++++++++++++++++++++++++++++ dlls/wined3d/swapchain.c | 36 ++-------------------------------- dlls/wined3d/wined3d_private.h | 8 ++++---- 4 files changed, 48 insertions(+), 47 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index c790157fd0a..66e4321dd12 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1258,7 +1258,7 @@ success:
static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl) { - struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(context_gl->c.swapchain); + struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); BOOL backup = FALSE;
if (!wined3d_context_gl_set_pixel_format(context_gl)) @@ -1275,23 +1275,20 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context context_gl->valid = 0; WARN("Trying fallback to the backup window.\n");
- /* FIXME: If the context is destroyed it's no longer associated with - * a swapchain, so we can't use the swapchain to get a backup dc. To - * make this work windowless contexts would need to be handled by the - * device. */ - if (context_gl->c.destroyed || !swapchain_gl) + if (context_gl->c.destroyed) { FIXME("Unable to get backup dc for destroyed context %p.\n", context_gl); wined3d_context_gl_set_current(NULL); return FALSE; }
- if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(device_gl))) { wined3d_context_gl_set_current(NULL); return FALSE; }
+ TRACE("Using backup DC %p.\n", context_gl->dc); context_gl->dc_is_private = TRUE; context_gl->dc_has_format = FALSE;
@@ -2032,7 +2029,7 @@ static BOOL wined3d_context_gl_create_wgl_ctx(struct wined3d_context_gl *context context_gl->pixel_format, context_gl->dc);
wined3d_release_dc(context_gl->window, context_gl->dc); - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device)))) { ERR("Failed to retrieve the backup device context.\n"); return FALSE; @@ -2109,7 +2106,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi
if (!context_gl->dc) { - if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl))) + if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device)))) { ERR("Failed to retrieve a device context.\n"); return E_FAIL; @@ -2354,6 +2351,7 @@ void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl) context_gl->c.destroy_delayed = 1; /* FIXME: Get rid of a pointer to swapchain from wined3d_context. */ context_gl->c.swapchain = NULL; + context_gl->c.device = NULL; return; }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b7d0b1adebc..7d2d9a61552 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1225,6 +1225,14 @@ void wined3d_device_gl_delete_opengl_contexts_cs(void *object) else wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); } + + if (device_gl->backup_dc) + { + TRACE("Destroying backup wined3d window %p, dc %p.\n", device_gl->backup_wnd, device_gl->backup_dc); + + wined3d_release_dc(device_gl->backup_wnd, device_gl->backup_dc); + DestroyWindow(device_gl->backup_wnd); + } }
void wined3d_device_gl_create_primary_opengl_context_cs(void *object) @@ -5913,6 +5921,33 @@ void CDECL wined3d_device_get_gamma_ramp(const struct wined3d_device *device, wined3d_swapchain_get_gamma_ramp(swapchain, ramp); }
+HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl) +{ + TRACE("device_gl %p.\n", device_gl); + + if (!device_gl->backup_dc) + { + TRACE("Creating the backup window for device %p.\n", device_gl); + + if (!(device_gl->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", + WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL))) + { + ERR("Failed to create a window.\n"); + return NULL; + } + + if (!(device_gl->backup_dc = GetDC(device_gl->backup_wnd))) + { + ERR("Failed to get a DC.\n"); + DestroyWindow(device_gl->backup_wnd); + device_gl->backup_wnd = NULL; + return NULL; + } + } + + return device_gl->backup_dc; +} + void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) { TRACE("device %p, resource %p.\n", device, resource); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 1712cda2373..79ee427572f 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -98,14 +98,6 @@ void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl)
wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); - - if (swapchain_gl->backup_dc) - { - TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain_gl->backup_wnd, swapchain_gl->backup_dc); - - wined3d_release_dc(swapchain_gl->backup_wnd, swapchain_gl->backup_dc); - DestroyWindow(swapchain_gl->backup_wnd); - } }
static void wined3d_swapchain_vk_destroy_vulkan_swapchain(struct wined3d_swapchain_vk *swapchain_vk) @@ -610,7 +602,8 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, TRACE("Presenting DC %p.\n", context_gl->dc);
pixel_format = &wined3d_adapter_gl(swapchain->device->adapter)->pixel_formats[context_gl->pixel_format]; - if (context_gl->dc == swapchain_gl->backup_dc || (pixel_format->swap_method != WGL_SWAP_COPY_ARB + if (context_gl->dc == wined3d_device_gl(swapchain->device)->backup_dc + || (pixel_format->swap_method != WGL_SWAP_COPY_ARB && swapchain_present_is_partial_copy(swapchain, dst_rect))) { swapchain_blit_gdi(swapchain, context, src_rect, dst_rect); @@ -1842,31 +1835,6 @@ struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapc return wined3d_swapchain_gl_create_context(swapchain_gl); }
-HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) -{ - if (!swapchain_gl->backup_dc) - { - TRACE("Creating the backup window for swapchain %p.\n", swapchain_gl); - - if (!(swapchain_gl->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window", - WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL))) - { - ERR("Failed to create a window.\n"); - return NULL; - } - - if (!(swapchain_gl->backup_dc = GetDC(swapchain_gl->backup_wnd))) - { - ERR("Failed to get a DC.\n"); - DestroyWindow(swapchain_gl->backup_wnd); - swapchain_gl->backup_wnd = NULL; - return NULL; - } - } - - return swapchain_gl->backup_dc; -} - void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain) { UINT i; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index cbee46740b1..47904390ed3 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4294,6 +4294,9 @@ struct wined3d_device_gl } *retired_blocks; SIZE_T retired_blocks_size; SIZE_T retired_block_count; + + HWND backup_wnd; + HDC backup_dc; };
static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device) @@ -4331,6 +4334,7 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, GLenum usage, bool coherent, GLbitfield flags, struct wined3d_bo_gl *bo) DECLSPEC_HIDDEN; void wined3d_device_gl_create_primary_opengl_context_cs(void *object) DECLSPEC_HIDDEN; void wined3d_device_gl_delete_opengl_contexts_cs(void *object) DECLSPEC_HIDDEN; +HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl) DECLSPEC_HIDDEN; GLbitfield wined3d_device_gl_get_memory_type_flags(unsigned int memory_type_idx) DECLSPEC_HIDDEN;
static inline float wined3d_alpha_ref(const struct wined3d_state *state) @@ -5708,9 +5712,6 @@ struct wined3d_swapchain_gl struct wined3d_context_gl **contexts; SIZE_T contexts_size; SIZE_T context_count; - - HDC backup_dc; - HWND backup_wnd; };
static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_swapchain *swapchain) @@ -5720,7 +5721,6 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; -HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
From: Matteo Bruni mbruni@codeweavers.com
--- It turns out that, indeed, this has been broken for a while. --- dlls/wined3d/device.c | 7 +++++-- dlls/wined3d/swapchain.c | 19 +++++++++++++++++++ dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7d2d9a61552..5e64cf9487c 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1256,10 +1256,13 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) return; }
+ context_gl = wined3d_context_gl(context); + if (!wined3d_allocator_init(&device_gl->allocator, ARRAY_SIZE(gl_memory_types), &wined3d_allocator_gl_ops)) { WARN("Failed to initialise allocator.\n"); context_release(context); + wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); return; }
@@ -1269,6 +1272,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) ERR("Failed to allocate shader private data, hr %#x.\n", hr); wined3d_allocator_cleanup(&device_gl->allocator); context_release(context); + wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); return; }
@@ -1278,11 +1282,10 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) device->shader_backend->shader_free_private(device, NULL); wined3d_allocator_cleanup(&device_gl->allocator); context_release(context); + wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); return; }
- context_gl = wined3d_context_gl(context); - wined3d_ffp_blitter_create(&device->blitter, context_gl->gl_info); if (!wined3d_glsl_blitter_create(&device->blitter, device)) wined3d_arbfp_blitter_create(&device->blitter, device); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 79ee427572f..0fd082fac7b 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -1804,6 +1804,25 @@ static struct wined3d_context_gl *wined3d_swapchain_gl_create_context(struct win return context_gl; }
+void wined3d_swapchain_gl_context_destroy(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_context_gl *context_gl) +{ + unsigned int i, j; + + TRACE("swapchain_gl %p, context_gl %p.\n", swapchain_gl, context_gl); + + for (i = 0; i < swapchain_gl->context_count; ++i) + { + if (swapchain_gl->contexts[i] == context_gl) + { + wined3d_context_gl_destroy(swapchain_gl->contexts[i]); + for (j = i; j < --swapchain_gl->context_count; ++j) + swapchain_gl->contexts[j] = swapchain_gl->contexts[j + 1]; + return; + } + } + ERR("context_gl %p not found in the swapchain list.\n", context_gl); +} + void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) { unsigned int i; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 47904390ed3..20194887b7a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5720,6 +5720,8 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s }
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; +void wined3d_swapchain_gl_context_destroy(struct wined3d_swapchain_gl *swapchain_gl, + struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl,
From: Matteo Bruni mbruni@codeweavers.com
This avoids triggering a Mesa slowpath introduced by Mesa commit e7f3a8d6959c74f63c877dd8776fe519d54f946f.
Additionally, it helps applications using multiple swapchains and queries (e.g. the one in bug 43773) by not requiring extra context switches when polling queries. For the records, the actual issue from bug 43773 was probably fixed a long time ago, maybe already by 7b62a970e9ad3b4179394cf54f0232475fe2388a or thereabouts.
The downside of this change is that we'll now end up calling glFinish() when there are multiple threads using the same device when CSMT is disabled. That's a non-default setting and one that should only be used for troubleshooting purposes at this point, so it shouldn't be too bad of an issue. It might also make sense to just get rid of that glFinish() entirely, it's never going to be a complete fix. --- dlls/wined3d/adapter_gl.c | 2 +- dlls/wined3d/context_gl.c | 10 +++++ dlls/wined3d/device.c | 14 ++---- dlls/wined3d/swapchain.c | 81 +++++----------------------------- dlls/wined3d/wined3d_private.h | 7 --- 5 files changed, 26 insertions(+), 88 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index 60a168b5cef..3131fdadeae 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -4567,7 +4567,7 @@ static HRESULT adapter_gl_init_3d(struct wined3d_device *device)
wined3d_cs_init_object(device->cs, wined3d_device_gl_create_primary_opengl_context_cs, wined3d_device_gl(device)); wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - if (!wined3d_swapchain_gl(device->swapchains[0])->context_count) + if (!device->context_count) return E_FAIL;
return WINED3D_OK; diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index 66e4321dd12..2f6db56a961 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -1261,6 +1261,8 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device); BOOL backup = FALSE;
+ TRACE("context_gl %p.\n", context_gl); + if (!wined3d_context_gl_set_pixel_format(context_gl)) { WARN("Failed to set pixel format %d on device context %p.\n", @@ -1366,6 +1368,8 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl) HDC restore_dc; unsigned int i;
+ TRACE("context_gl %p.\n", context_gl); + restore_ctx = wglGetCurrentContext(); restore_dc = wglGetCurrentDC();
@@ -4481,6 +4485,12 @@ static void wined3d_context_gl_activate(struct wined3d_context_gl *context_gl, struct wined3d_texture *texture, unsigned int sub_resource_idx) { wined3d_context_gl_enter(context_gl); + if (texture && texture->swapchain && texture->swapchain != context_gl->c.swapchain) + { + TRACE("Switching context_gl %p from swapchain %p to swapchain %p.\n", + context_gl, context_gl->c.swapchain, texture->swapchain); + context_gl->c.swapchain = texture->swapchain; + } wined3d_context_gl_update_window(context_gl); wined3d_context_gl_setup_target(context_gl, texture, sub_resource_idx); if (!context_gl->valid) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 5e64cf9487c..02ac8ef2c6a 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1187,7 +1187,6 @@ bool wined3d_device_gl_create_bo(struct wined3d_device_gl *device_gl, struct win void wined3d_device_gl_delete_opengl_contexts_cs(void *object) { struct wined3d_device_gl *device_gl = object; - struct wined3d_swapchain_gl *swapchain_gl; struct wined3d_context_gl *context_gl; struct wined3d_context *context; struct wined3d_device *device; @@ -1219,12 +1218,7 @@ void wined3d_device_gl_delete_opengl_contexts_cs(void *object) context_release(context);
while (device->context_count) - { - if ((swapchain_gl = wined3d_swapchain_gl(device->contexts[0]->swapchain))) - wined3d_swapchain_gl_destroy_contexts(swapchain_gl); - else - wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); - } + wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0]));
if (device_gl->backup_dc) { @@ -1262,7 +1256,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) { WARN("Failed to initialise allocator.\n"); context_release(context); - wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); + wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); return; }
@@ -1272,7 +1266,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) ERR("Failed to allocate shader private data, hr %#x.\n", hr); wined3d_allocator_cleanup(&device_gl->allocator); context_release(context); - wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); + wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); return; }
@@ -1282,7 +1276,7 @@ void wined3d_device_gl_create_primary_opengl_context_cs(void *object) device->shader_backend->shader_free_private(device, NULL); wined3d_allocator_cleanup(&device_gl->allocator); context_release(context); - wined3d_swapchain_gl_context_destroy(wined3d_swapchain_gl(swapchain), context_gl); + wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0])); return; }
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 0fd082fac7b..acf8eab924e 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -23,6 +23,7 @@ #include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d); +WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) { @@ -85,19 +86,9 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain) } }
-static void wined3d_swapchain_gl_destroy_object(void *object) -{ - wined3d_swapchain_gl_destroy_contexts(object); -} - void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) { - struct wined3d_cs *cs = swapchain_gl->s.device->cs; - wined3d_swapchain_cleanup(&swapchain_gl->s); - - wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); - wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT); }
static void wined3d_swapchain_vk_destroy_vulkan_swapchain(struct wined3d_swapchain_vk *swapchain_vk) @@ -583,7 +574,6 @@ static bool swapchain_present_is_partial_copy(struct wined3d_swapchain *swapchai static void swapchain_gl_present(struct wined3d_swapchain *swapchain, const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, uint32_t flags) { - struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain); struct wined3d_texture *back_buffer = swapchain->back_buffers[0]; const struct wined3d_pixel_format *pixel_format; const struct wined3d_gl_info *gl_info; @@ -619,8 +609,11 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain, if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) swapchain_blit(swapchain, context, src_rect, dst_rect);
- if (swapchain_gl->context_count > 1) + if (swapchain->device->context_count > 1) + { + WARN_(d3d_perf)("Multiple contexts, calling glFinish() to enforce ordering.\n"); gl_info->gl_ops.gl.p_glFinish(); + }
/* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */ gl_info->gl_ops.wgl.p_wglSwapBuffers(context_gl->dc); @@ -1688,20 +1681,11 @@ HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, str struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent, void *parent, const struct wined3d_parent_ops *parent_ops) { - HRESULT hr; - TRACE("swapchain_gl %p, device %p, desc %p, state_parent %p, parent %p, parent_ops %p.\n", swapchain_gl, device, desc, state_parent, parent, parent_ops);
- if (FAILED(hr = wined3d_swapchain_init(&swapchain_gl->s, device, desc, state_parent, parent, - parent_ops, &swapchain_gl_ops))) - { - /* Cleanup any context that may have been created for the swapchain. */ - wined3d_cs_destroy_object(device->cs, wined3d_swapchain_gl_destroy_object, swapchain_gl); - wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT); - } - - return hr; + return wined3d_swapchain_init(&swapchain_gl->s, device, desc, state_parent, parent, + parent_ops, &swapchain_gl_ops); }
HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain_vk *swapchain_vk, struct wined3d_device *device, @@ -1792,62 +1776,19 @@ static struct wined3d_context_gl *wined3d_swapchain_gl_create_context(struct win
context_release(&context_gl->c);
- if (!wined3d_array_reserve((void **)&swapchain_gl->contexts, &swapchain_gl->contexts_size, - swapchain_gl->context_count + 1, sizeof(*swapchain_gl->contexts))) - { - ERR("Failed to allocate new context array memory.\n"); - wined3d_context_gl_destroy(context_gl); - return NULL; - } - swapchain_gl->contexts[swapchain_gl->context_count++] = context_gl; - return context_gl; }
-void wined3d_swapchain_gl_context_destroy(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_context_gl *context_gl) -{ - unsigned int i, j; - - TRACE("swapchain_gl %p, context_gl %p.\n", swapchain_gl, context_gl); - - for (i = 0; i < swapchain_gl->context_count; ++i) - { - if (swapchain_gl->contexts[i] == context_gl) - { - wined3d_context_gl_destroy(swapchain_gl->contexts[i]); - for (j = i; j < --swapchain_gl->context_count; ++j) - swapchain_gl->contexts[j] = swapchain_gl->contexts[j + 1]; - return; - } - } - ERR("context_gl %p not found in the swapchain list.\n", context_gl); -} - -void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) -{ - unsigned int i; - - TRACE("swapchain_gl %p.\n", swapchain_gl); - - for (i = 0; i < swapchain_gl->context_count; ++i) - { - wined3d_context_gl_destroy(swapchain_gl->contexts[i]); - } - heap_free(swapchain_gl->contexts); - swapchain_gl->contexts_size = 0; - swapchain_gl->context_count = 0; - swapchain_gl->contexts = NULL; -} - struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) { + struct wined3d_device *device = swapchain_gl->s.device; DWORD tid = GetCurrentThreadId(); unsigned int i;
- for (i = 0; i < swapchain_gl->context_count; ++i) + for (i = 0; i < device->context_count; ++i) { - if (swapchain_gl->contexts[i]->tid == tid) - return swapchain_gl->contexts[i]; + if (wined3d_context_gl(device->contexts[i])->tid == tid) + return wined3d_context_gl(device->contexts[i]); }
/* Create a new context for the thread. */ diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 20194887b7a..f7c9c75364c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -5708,10 +5708,6 @@ HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, struct wined3d_swapchain_gl { struct wined3d_swapchain s; - - struct wined3d_context_gl **contexts; - SIZE_T contexts_size; - SIZE_T context_count; };
static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_swapchain *swapchain) @@ -5720,9 +5716,6 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s }
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; -void wined3d_swapchain_gl_context_destroy(struct wined3d_swapchain_gl *swapchain_gl, - struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN; -void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN; HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
This merge request was approved by Zebediah Figura.
This merge request was approved by Jan Sikorski.