[PATCH 04/10] wined3d: Make the adapter responsible for shader resource view creation and destruction.

Henri Verbeet hverbeet at codeweavers.com
Sun Aug 11 04:35:11 CDT 2019


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/wined3d/adapter_gl.c      | 48 +++++++++++++++++++++++++
 dlls/wined3d/adapter_vk.c      | 48 +++++++++++++++++++++++++
 dlls/wined3d/directx.c         | 17 +++++++++
 dlls/wined3d/view.c            | 81 +++++++++++++++++++-----------------------
 dlls/wined3d/wined3d_private.h | 23 ++++++++++++
 5 files changed, 172 insertions(+), 45 deletions(-)

diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 7f321d4acba..cc7bc57ea3d 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4835,6 +4835,52 @@ static void adapter_gl_destroy_rendertarget_view(struct wined3d_rendertarget_vie
         wined3d_device_decref(device);
 }
 
+static HRESULT adapter_gl_create_shader_resource_view(const struct wined3d_view_desc *desc,
+        struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_shader_resource_view **view)
+{
+    struct wined3d_shader_resource_view_gl *view_gl;
+    HRESULT hr;
+
+    TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
+            wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
+
+    if (!(view_gl = heap_alloc_zero(sizeof(*view_gl))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_shader_resource_view_gl_init(view_gl, desc, resource, parent, parent_ops)))
+    {
+        WARN("Failed to initialise view, hr %#x.\n", hr);
+        heap_free(view_gl);
+        return hr;
+    }
+
+    TRACE("Created shader resource view %p.\n", view_gl);
+    *view = &view_gl->v;
+
+    return hr;
+}
+
+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;
+
+    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);
+    wined3d_shader_resource_view_cleanup(&view_gl->v);
+    wined3d_view_gl_destroy(device, &view_gl->gl_view, view_gl);
+    if (swapchain_count)
+        wined3d_device_decref(device);
+}
+
 static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
 {
     adapter_gl_destroy,
@@ -4852,6 +4898,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
     adapter_gl_destroy_buffer,
     adapter_gl_create_rendertarget_view,
     adapter_gl_destroy_rendertarget_view,
+    adapter_gl_create_shader_resource_view,
+    adapter_gl_destroy_shader_resource_view,
 };
 
 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 a58efb8b7d8..f739ebfaac4 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -586,6 +586,52 @@ static void adapter_vk_destroy_rendertarget_view(struct wined3d_rendertarget_vie
         wined3d_device_decref(device);
 }
 
+static HRESULT adapter_vk_create_shader_resource_view(const struct wined3d_view_desc *desc,
+        struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_shader_resource_view **view)
+{
+    struct wined3d_shader_resource_view_vk *view_vk;
+    HRESULT hr;
+
+    TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
+            wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
+
+    if (!(view_vk = heap_alloc_zero(sizeof(*view_vk))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = wined3d_shader_resource_view_vk_init(view_vk, desc, resource, parent, parent_ops)))
+    {
+        WARN("Failed to initialise view, hr %#x.\n", hr);
+        heap_free(view_vk);
+        return hr;
+    }
+
+    TRACE("Created shader resource view %p.\n", view_vk);
+    *view = &view_vk->v;
+
+    return hr;
+}
+
+static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resource_view *view)
+{
+    struct wined3d_shader_resource_view_vk *view_vk = wined3d_shader_resource_view_vk(view);
+    struct wined3d_device *device = view_vk->v.resource->device;
+    unsigned int swapchain_count = device->swapchain_count;
+
+    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);
+    wined3d_shader_resource_view_cleanup(&view_vk->v);
+    wined3d_cs_destroy_object(device->cs, heap_free, view_vk);
+    if (swapchain_count)
+        wined3d_device_decref(device);
+}
+
 static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
 {
     adapter_vk_destroy,
@@ -603,6 +649,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
     adapter_vk_destroy_buffer,
     adapter_vk_create_rendertarget_view,
     adapter_vk_destroy_rendertarget_view,
+    adapter_vk_create_shader_resource_view,
+    adapter_vk_destroy_shader_resource_view,
 };
 
 static unsigned int wined3d_get_wine_vk_version(void)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 5a4f7d2471e..9e31c0415c5 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2475,6 +2475,21 @@ static void adapter_no3d_destroy_rendertarget_view(struct wined3d_rendertarget_v
         wined3d_device_decref(device);
 }
 
+static HRESULT adapter_no3d_create_shader_resource_view(const struct wined3d_view_desc *desc,
+        struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_shader_resource_view **view)
+{
+    TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
+            wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
+
+    return E_NOTIMPL;
+}
+
+static void adapter_no3d_destroy_shader_resource_view(struct wined3d_shader_resource_view *view)
+{
+    TRACE("view %p.\n", view);
+}
+
 static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
 {
     adapter_no3d_destroy,
@@ -2492,6 +2507,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
     adapter_no3d_destroy_buffer,
     adapter_no3d_create_rendertarget_view,
     adapter_no3d_destroy_rendertarget_view,
+    adapter_no3d_create_shader_resource_view,
+    adapter_no3d_destroy_shader_resource_view,
 };
 
 static void wined3d_adapter_no3d_init_d3d_info(struct wined3d_adapter *adapter, unsigned int wined3d_creation_flags)
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 8239059279b..ff8043c8682 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -674,23 +674,12 @@ ULONG CDECL wined3d_shader_resource_view_incref(struct wined3d_shader_resource_v
     return refcount;
 }
 
-static void wined3d_shader_resource_view_gl_destroy_object(void *object)
+void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view)
 {
-    struct wined3d_shader_resource_view_gl *view_gl = object;
-
-    if (view_gl->gl_view.name)
-    {
-        const struct wined3d_gl_info *gl_info;
-        struct wined3d_context *context;
-
-        context = context_acquire(view_gl->v.resource->device, NULL, 0);
-        gl_info = wined3d_context_gl(context)->gl_info;
-        gl_info->gl_ops.gl.p_glDeleteTextures(1, &view_gl->gl_view.name);
-        checkGLcall("glDeleteTextures");
-        context_release(context);
-    }
-
-    heap_free(view_gl);
+    /* 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);
 }
 
 ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_view *view)
@@ -700,17 +689,7 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
     TRACE("%p decreasing refcount to %u.\n", view, refcount);
 
     if (!refcount)
-    {
-        struct wined3d_resource *resource = view->resource;
-        struct wined3d_device *device = resource->device;
-
-        /* 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_cs_destroy_object(device->cs, wined3d_shader_resource_view_gl_destroy_object,
-                wined3d_shader_resource_view_gl(view));
-        wined3d_resource_decref(resource);
-    }
+        view->resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
 
     return refcount;
 }
@@ -798,32 +777,44 @@ static HRESULT wined3d_shader_resource_view_init(struct wined3d_shader_resource_
     return WINED3D_OK;
 }
 
-HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc,
-        struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
-        struct wined3d_shader_resource_view **view)
+HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
+        const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+        void *parent, const struct wined3d_parent_ops *parent_ops)
 {
-    struct wined3d_shader_resource_view_gl *object;
     HRESULT hr;
 
-    TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
-            wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
-
-    if (!(object = heap_alloc_zero(sizeof(*object))))
-        return E_OUTOFMEMORY;
+    TRACE("view_gl %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
+            view_gl, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
 
-    if (FAILED(hr = wined3d_shader_resource_view_init(&object->v, desc, resource, parent, parent_ops)))
-    {
-        heap_free(object);
-        WARN("Failed to initialise view, hr %#x.\n", hr);
+    if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
         return hr;
-    }
 
-    wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, object);
+    wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
 
-    TRACE("Created shader resource view %p.\n", object);
-    *view = &object->v;
+    return hr;
+}
 
-    return WINED3D_OK;
+HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk,
+        const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+        void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+    TRACE("view_vk %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
+            view_vk, wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops);
+
+    return wined3d_shader_resource_view_init(&view_vk->v, desc, resource, parent, parent_ops);
+}
+
+HRESULT CDECL wined3d_shader_resource_view_create(const struct wined3d_view_desc *desc,
+        struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+        struct wined3d_shader_resource_view **view)
+{
+    const struct wined3d_adapter_ops *adapter_ops;
+
+    TRACE("desc %s, resource %p, parent %p, parent_ops %p, view %p.\n",
+            wined3d_debug_view_desc(desc, resource), resource, parent, parent_ops, view);
+
+    adapter_ops = resource->device->adapter->adapter_ops;
+    return adapter_ops->adapter_create_shader_resource_view(desc, resource, parent, parent_ops, view);
 }
 
 void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl *view_gl,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e9bb28536c9..6cab6f34966 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2792,6 +2792,10 @@ struct wined3d_adapter_ops
             struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
             struct wined3d_rendertarget_view **view);
     void (*adapter_destroy_rendertarget_view)(struct wined3d_rendertarget_view *view);
+    HRESULT (*adapter_create_shader_resource_view)(const struct wined3d_view_desc *desc,
+            struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+            struct wined3d_shader_resource_view **view);
+    void (*adapter_destroy_shader_resource_view)(struct wined3d_shader_resource_view *view);
 };
 
 /* The adapter structure */
@@ -4217,6 +4221,7 @@ struct wined3d_shader_resource_view
     struct wined3d_view_desc desc;
 };
 
+void wined3d_shader_resource_view_cleanup(struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
 void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *view) DECLSPEC_HIDDEN;
 
 struct wined3d_shader_resource_view_gl
@@ -4233,6 +4238,24 @@ static inline struct wined3d_shader_resource_view_gl *wined3d_shader_resource_vi
 
 void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl *view_gl, unsigned int unit,
         struct wined3d_sampler *sampler, struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
+HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
+        const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+        void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+
+struct wined3d_shader_resource_view_vk
+{
+    struct wined3d_shader_resource_view v;
+};
+
+static inline struct wined3d_shader_resource_view_vk *wined3d_shader_resource_view_vk(
+        struct wined3d_shader_resource_view *view)
+{
+    return CONTAINING_RECORD(view, struct wined3d_shader_resource_view_vk, v);
+}
+
+HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk,
+        const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+        void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
 
 struct wined3d_unordered_access_view
 {
-- 
2.11.0




More information about the wine-devel mailing list