diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 29ce04f0dc1..f640c9e26ec 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1032,9 +1032,8 @@ err_out: static void device_free_sampler(struct wine_rb_entry *entry, void *context) { struct wined3d_sampler *sampler = WINE_RB_ENTRY_VALUE(entry, struct wined3d_sampler, entry); - struct wined3d_device *device = context; - wine_rb_remove(&device->samplers, &sampler->desc); + wined3d_sampler_decref(sampler); } HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) @@ -1071,7 +1070,7 @@ HRESULT CDECL wined3d_device_uninit_3d(struct wined3d_device *device) resource->resource_ops->resource_unload(resource); } - wine_rb_for_each_entry(&device->samplers, device_free_sampler, device); + wine_rb_clear(&device->samplers, device_free_sampler, NULL); /* Destroy the depth blt resources, they will be invalid after the reset. Also free shader * private data, it might contain opengl pointers @@ -4632,6 +4631,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, device->exStyle = exStyle; } + wine_rb_clear(&device->samplers, device_free_sampler, NULL); + if (reset_state) { TRACE("Resetting stateblock.\n"); @@ -4677,8 +4678,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, swapchain_update_render_to_fbo(swapchain); swapchain_update_draw_bindings(swapchain); - wine_rb_for_each_entry(&device->samplers, device_free_sampler, device); - if (reset_state && device->d3d_initialized) hr = create_primary_opengl_context(device, swapchain); diff --git a/include/wine/rbtree.h b/include/wine/rbtree.h index 2276e303463..13452d9e458 100644 --- a/include/wine/rbtree.h +++ b/include/wine/rbtree.h @@ -220,12 +220,16 @@ static inline void wine_rb_for_each_entry(struct wine_rb_tree *tree, wine_rb_tra wine_rb_postorder(tree, callback, context); } -static inline void wine_rb_destroy(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context) +static inline void wine_rb_clear(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context) { /* Note that we use postorder here because the callback will likely free the entry. */ if (callback) wine_rb_postorder(tree, callback, context); - tree->root = NULL; +} + +static inline void wine_rb_destroy(struct wine_rb_tree *tree, wine_rb_traverse_func_t *callback, void *context) +{ + wine_rb_clear(tree, callback, context); tree->functions->free(tree->stack.entries); }