From 0e8f2786e9de5e3711184ec975daca8e6f66ba41 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 1 Dec 2014 08:45:43 +0100 Subject: [PATCH] wined3d: Keep a reference to the resource in shader resource views. --- dlls/d3d10core/view.c | 10 +++++++++- dlls/wined3d/view.c | 9 +++++++-- dlls/wined3d/wined3d_private.h | 1 + include/wine/wined3d.h | 4 ++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dlls/d3d10core/view.c b/dlls/d3d10core/view.c index 5c021313ed7..fc2e8cd5342 100644 --- a/dlls/d3d10core/view.c +++ b/dlls/d3d10core/view.c @@ -987,6 +987,7 @@ static const struct ID3D10ShaderResourceViewVtbl d3d10_shader_resource_view_vtbl HRESULT d3d10_shader_resource_view_init(struct d3d10_shader_resource_view *view, struct d3d10_device *device, ID3D10Resource *resource, const D3D10_SHADER_RESOURCE_VIEW_DESC *desc) { + struct wined3d_resource *wined3d_resource; HRESULT hr; view->ID3D10ShaderResourceView_iface.lpVtbl = &d3d10_shader_resource_view_vtbl; @@ -1002,7 +1003,14 @@ HRESULT d3d10_shader_resource_view_init(struct d3d10_shader_resource_view *view, view->desc = *desc; } - if (FAILED(hr = wined3d_shader_resource_view_create(view, &d3d10_null_wined3d_parent_ops, &view->wined3d_view))) + if (!(wined3d_resource = wined3d_resource_from_resource(resource))) + { + ERR("Failed to get wined3d resource for d3d10 resource %p.\n", resource); + return E_FAIL; + } + + if (FAILED(hr = wined3d_shader_resource_view_create(wined3d_resource, + view, &d3d10_null_wined3d_parent_ops, &view->wined3d_view))) { WARN("Failed to create wined3d shader resource view, hr %#x.\n", hr); return hr; diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index 1f8db545c77..9cda64d921f 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -176,7 +176,10 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v if (!refcount) { + /* Call wined3d_object_destroyed() before releasing the resource, + * since releasing the resource may end up destroying the parent. */ view->parent_ops->wined3d_object_destroyed(view->parent); + wined3d_resource_decref(view->resource); HeapFree(GetProcessHeap(), 0, view); } @@ -190,8 +193,8 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader return view->parent; } -HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_shader_resource_view **view) +HRESULT CDECL wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view) { struct wined3d_shader_resource_view *object; @@ -201,6 +204,8 @@ HRESULT CDECL wined3d_shader_resource_view_create(void *parent, const struct win return E_OUTOFMEMORY; object->refcount = 1; + object->resource = resource; + wined3d_resource_incref(resource); object->parent = parent; object->parent_ops = parent_ops; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 740dabcd81c..050383c7143 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2663,6 +2663,7 @@ struct wined3d_shader_resource_view { LONG refcount; + struct wined3d_resource *resource; void *parent; const struct wined3d_parent_ops *parent_ops; }; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 44a2726242c..2362cbcfc1d 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2441,8 +2441,8 @@ ULONG __cdecl wined3d_shader_incref(struct wined3d_shader *shader); HRESULT __cdecl wined3d_shader_set_local_constants_float(struct wined3d_shader *shader, UINT start_idx, const float *src_data, UINT vector4f_count); -HRESULT __cdecl wined3d_shader_resource_view_create(void *parent, const struct wined3d_parent_ops *parent_ops, - struct wined3d_shader_resource_view **view); +HRESULT __cdecl wined3d_shader_resource_view_create(struct wined3d_resource *resource, void *parent, + const struct wined3d_parent_ops *parent_ops, struct wined3d_shader_resource_view **view); ULONG __cdecl wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view); void * __cdecl wined3d_shader_resource_view_get_parent(const struct wined3d_shader_resource_view *view); ULONG __cdecl wined3d_shader_resource_view_incref(struct wined3d_shader_resource_view *view);