Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 69 ++++++++++++++++-------------------
dlls/wined3d/adapter_vk.c | 77 ++++++++++++++++++---------------------
2 files changed, 68 insertions(+), 78 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 990991e2e3d..8787324571a 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4755,6 +4755,7 @@ struct wined3d_view_gl_destroy_ctx
{
struct wined3d_device *device;
const struct wined3d_gl_view *gl_view;
+ struct wined3d_bo_user *bo_user;
struct wined3d_bo_gl *counter_bo;
void *object;
struct wined3d_view_gl_destroy_ctx *free;
@@ -4787,13 +4788,15 @@ static void wined3d_view_gl_destroy_object(void *object)
checkGLcall("delete resources");
context_release(context);
}
+ if (ctx->bo_user)
+ list_remove(&ctx->bo_user->entry);
heap_free(ctx->object);
heap_free(ctx->free);
}
-static void wined3d_view_gl_destroy(struct wined3d_device *device,
- const struct wined3d_gl_view *gl_view, struct wined3d_bo_gl *counter_bo, void *object)
+static void wined3d_view_gl_destroy(struct wined3d_device *device, const struct wined3d_gl_view *gl_view,
+ struct wined3d_bo_user *bo_user, struct wined3d_bo_gl *counter_bo, void *object)
{
struct wined3d_view_gl_destroy_ctx *ctx, c;
@@ -4801,6 +4804,7 @@ static void wined3d_view_gl_destroy(struct wined3d_device *device,
ctx = &c;
ctx->device = device;
ctx->gl_view = gl_view;
+ ctx->bo_user = bo_user;
ctx->counter_bo = counter_bo;
ctx->object = object;
ctx->free = ctx != &c ? ctx : NULL;
@@ -4813,21 +4817,16 @@ static void wined3d_view_gl_destroy(struct wined3d_device *device,
static void adapter_gl_destroy_rendertarget_view(struct wined3d_rendertarget_view *view)
{
struct wined3d_rendertarget_view_gl *view_gl = wined3d_rendertarget_view_gl(view);
- struct wined3d_device *device = view_gl->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = view_gl->v.resource;
TRACE("view_gl %p.\n", view_gl);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
+ /* Take a reference to the resource, in case releasing the resource
+ * would cause the device to be destroyed. */
+ wined3d_resource_incref(resource);
wined3d_rendertarget_view_cleanup(&view_gl->v);
- wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, NULL, NULL, view_gl);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_gl_create_shader_resource_view(const struct wined3d_view_desc *desc,
@@ -4859,22 +4858,20 @@ static HRESULT adapter_gl_create_shader_resource_view(const struct wined3d_view_
static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resource_view *view)
{
struct wined3d_shader_resource_view_gl *view_gl = wined3d_shader_resource_view_gl(view);
- struct wined3d_device *device = view_gl->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = view_gl->v.resource;
TRACE("view_gl %p.\n", view_gl);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
- list_remove(&view_gl->bo_user.entry);
+ /* Take a reference to the resource. There are two reasons for this:
+ * - Releasing the resource could in turn cause the device to be
+ * destroyed, but we still need the device for
+ * wined3d_view_vk_destroy().
+ * - We shouldn't free buffer resources until after we've removed the
+ * view from its bo_user list. */
+ wined3d_resource_incref(resource);
wined3d_shader_resource_view_cleanup(&view_gl->v);
- wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, &view_gl->bo_user, NULL, view_gl);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_gl_create_unordered_access_view(const struct wined3d_view_desc *desc,
@@ -4906,22 +4903,20 @@ static HRESULT adapter_gl_create_unordered_access_view(const struct wined3d_view
static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_access_view *view)
{
struct wined3d_unordered_access_view_gl *view_gl = wined3d_unordered_access_view_gl(view);
- struct wined3d_device *device = view_gl->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = view_gl->v.resource;
TRACE("view_gl %p.\n", view_gl);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
- list_remove(&view_gl->bo_user.entry);
+ /* Take a reference to the resource. There are two reasons for this:
+ * - Releasing the resource could in turn cause the device to be
+ * destroyed, but we still need the device for
+ * wined3d_view_vk_destroy().
+ * - We shouldn't free buffer resources until after we've removed the
+ * view from its bo_user list. */
+ wined3d_resource_incref(resource);
wined3d_unordered_access_view_cleanup(&view_gl->v);
- wined3d_view_gl_destroy(device, &view_gl->gl_view, &view_gl->counter_bo, view_gl);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_gl_destroy(resource->device, &view_gl->gl_view, &view_gl->bo_user, &view_gl->counter_bo, view_gl);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_gl_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 0abae24fd1f..99d7547b834 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1304,6 +1304,7 @@ struct wined3d_view_vk_destroy_ctx
struct wined3d_device_vk *device_vk;
VkBufferView *vk_buffer_view;
VkImageView *vk_image_view;
+ struct wined3d_bo_user *bo_user;
struct wined3d_bo_vk *vk_counter_bo;
VkBufferView *vk_counter_view;
uint64_t *command_buffer_id;
@@ -1350,6 +1351,8 @@ static void wined3d_view_vk_destroy_object(void *object)
TRACE("Destroyed image view 0x%s.\n", wine_dbgstr_longlong(*ctx->vk_image_view));
}
}
+ if (ctx->bo_user)
+ list_remove(&ctx->bo_user->entry);
if (ctx->vk_counter_bo && ctx->vk_counter_bo->vk_buffer)
wined3d_context_vk_destroy_bo(wined3d_context_vk(context), ctx->vk_counter_bo);
if (ctx->vk_counter_view)
@@ -1374,7 +1377,7 @@ static void wined3d_view_vk_destroy_object(void *object)
}
static void wined3d_view_vk_destroy(struct wined3d_device *device, VkBufferView *vk_buffer_view,
- VkImageView *vk_image_view, struct wined3d_bo_vk *vk_counter_bo,
+ VkImageView *vk_image_view, struct wined3d_bo_user *bo_user, struct wined3d_bo_vk *vk_counter_bo,
VkBufferView *vk_counter_view, uint64_t *command_buffer_id, void *view_vk)
{
struct wined3d_view_vk_destroy_ctx *ctx, c;
@@ -1384,6 +1387,7 @@ static void wined3d_view_vk_destroy(struct wined3d_device *device, VkBufferView
ctx->device_vk = wined3d_device_vk(device);
ctx->vk_buffer_view = vk_buffer_view;
ctx->vk_image_view = vk_image_view;
+ ctx->bo_user = bo_user;
ctx->vk_counter_bo = vk_counter_bo;
ctx->vk_counter_view = vk_counter_view;
ctx->command_buffer_id = command_buffer_id;
@@ -1398,22 +1402,17 @@ static void wined3d_view_vk_destroy(struct wined3d_device *device, VkBufferView
static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_view *view)
{
struct wined3d_rendertarget_view_vk *view_vk = wined3d_rendertarget_view_vk(view);
- struct wined3d_device *device = view_vk->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = view_vk->v.resource;
TRACE("view_vk %p.\n", view_vk);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
+ /* Take a reference to the resource, in case releasing the resource
+ * would cause the device to be destroyed. */
+ wined3d_resource_incref(resource);
wined3d_rendertarget_view_cleanup(&view_vk->v);
- wined3d_view_vk_destroy(device, NULL, &view_vk->vk_image_view,
- NULL, NULL, &view_vk->command_buffer_id, view_vk);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_vk_destroy(resource->device, NULL, &view_vk->vk_image_view,
+ NULL, NULL, NULL, &view_vk->command_buffer_id, view_vk);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_vk_create_shader_resource_view(const struct wined3d_view_desc *desc,
@@ -1445,30 +1444,28 @@ static HRESULT adapter_vk_create_shader_resource_view(const struct wined3d_view_
static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resource_view *view)
{
struct wined3d_shader_resource_view_vk *srv_vk = wined3d_shader_resource_view_vk(view);
- struct wined3d_device *device = srv_vk->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = srv_vk->v.resource;
struct wined3d_view_vk *view_vk = &srv_vk->view_vk;
VkBufferView *vk_buffer_view = NULL;
VkImageView *vk_image_view = NULL;
TRACE("srv_vk %p.\n", srv_vk);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
- if (srv_vk->v.resource->type == WINED3D_RTYPE_BUFFER)
+ /* Take a reference to the resource. There are two reasons for this:
+ * - Releasing the resource could in turn cause the device to be
+ * destroyed, but we still need the device for
+ * wined3d_view_vk_destroy().
+ * - We shouldn't free buffer resources until after we've removed the
+ * view from its bo_user list. */
+ wined3d_resource_incref(resource);
+ if (resource->type == WINED3D_RTYPE_BUFFER)
vk_buffer_view = &view_vk->u.vk_buffer_view;
else
vk_image_view = &view_vk->u.vk_image_info.imageView;
- list_remove(&view_vk->bo_user.entry);
wined3d_shader_resource_view_cleanup(&srv_vk->v);
- wined3d_view_vk_destroy(device, vk_buffer_view, vk_image_view,
- NULL, NULL, &view_vk->command_buffer_id, srv_vk);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_vk_destroy(resource->device, vk_buffer_view, vk_image_view,
+ &view_vk->bo_user, NULL, NULL, &view_vk->command_buffer_id, srv_vk);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_vk_create_unordered_access_view(const struct wined3d_view_desc *desc,
@@ -1500,30 +1497,28 @@ static HRESULT adapter_vk_create_unordered_access_view(const struct wined3d_view
static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_access_view *view)
{
struct wined3d_unordered_access_view_vk *uav_vk = wined3d_unordered_access_view_vk(view);
- struct wined3d_device *device = uav_vk->v.resource->device;
- unsigned int swapchain_count = device->swapchain_count;
+ struct wined3d_resource *resource = uav_vk->v.resource;
struct wined3d_view_vk *view_vk = &uav_vk->view_vk;
VkBufferView *vk_buffer_view = NULL;
VkImageView *vk_image_view = NULL;
TRACE("uav_vk %p.\n", uav_vk);
- /* Take a reference to the device, in case releasing the view's resource
- * would cause the device to be destroyed. However, swapchain resources
- * don't take a reference to the device, and we wouldn't want to increment
- * the refcount on a device that's in the process of being destroyed. */
- if (swapchain_count)
- wined3d_device_incref(device);
- if (uav_vk->v.resource->type == WINED3D_RTYPE_BUFFER)
+ /* Take a reference to the resource. There are two reasons for this:
+ * - Releasing the resource could in turn cause the device to be
+ * destroyed, but we still need the device for
+ * wined3d_view_vk_destroy().
+ * - We shouldn't free buffer resources until after we've removed the
+ * view from its bo_user list. */
+ wined3d_resource_incref(resource);
+ if (resource->type == WINED3D_RTYPE_BUFFER)
vk_buffer_view = &view_vk->u.vk_buffer_view;
else
vk_image_view = &view_vk->u.vk_image_info.imageView;
- list_remove(&view_vk->bo_user.entry);
wined3d_unordered_access_view_cleanup(&uav_vk->v);
- wined3d_view_vk_destroy(device, vk_buffer_view, vk_image_view, &uav_vk->counter_bo,
- &uav_vk->vk_counter_view, &view_vk->command_buffer_id, uav_vk);
- if (swapchain_count)
- wined3d_device_decref(device);
+ wined3d_view_vk_destroy(resource->device, vk_buffer_view, vk_image_view, &view_vk->bo_user,
+ &uav_vk->counter_bo, &uav_vk->vk_counter_view, &view_vk->command_buffer_id, uav_vk);
+ wined3d_resource_decref(resource);
}
static HRESULT adapter_vk_create_sampler(struct wined3d_device *device, const struct wined3d_sampler_desc *desc,
--
2.20.1