[PATCH 03/10] wined3d: Make the adapter responsible for render target view creation and destruction.
Henri Verbeet
hverbeet at codeweavers.com
Sun Aug 11 04:35:10 CDT 2019
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 96 ++++++++++++++++++++++++++++++++++++++++++
dlls/wined3d/adapter_vk.c | 48 +++++++++++++++++++++
dlls/wined3d/directx.c | 47 +++++++++++++++++++++
dlls/wined3d/view.c | 93 ++++++++++++++++++++--------------------
dlls/wined3d/wined3d_private.h | 28 ++++++++++++
5 files changed, 265 insertions(+), 47 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 471eb42e862..7f321d4acba 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4741,6 +4741,100 @@ static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
+static HRESULT adapter_gl_create_rendertarget_view(const struct wined3d_view_desc *desc,
+ struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_view **view)
+{
+ struct wined3d_rendertarget_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_rendertarget_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 render target view %p.\n", view_gl);
+ *view = &view_gl->v;
+
+ return hr;
+}
+
+struct wined3d_view_gl_destroy_ctx
+{
+ struct wined3d_device *device;
+ const struct wined3d_gl_view *gl_view;
+ void *object;
+ struct wined3d_view_gl_destroy_ctx *free;
+};
+
+static void wined3d_view_gl_destroy_object(void *object)
+{
+ struct wined3d_view_gl_destroy_ctx *ctx = object;
+ const struct wined3d_gl_info *gl_info;
+ struct wined3d_context *context;
+ struct wined3d_device *device;
+
+ device = ctx->device;
+
+ if (ctx->gl_view->name)
+ {
+ context = context_acquire(device, NULL, 0);
+ gl_info = wined3d_context_gl(context)->gl_info;
+ context_gl_resource_released(device, ctx->gl_view->name, FALSE);
+ gl_info->gl_ops.gl.p_glDeleteTextures(1, &ctx->gl_view->name);
+ checkGLcall("delete resources");
+ context_release(context);
+ }
+
+ 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, void *object)
+{
+ struct wined3d_view_gl_destroy_ctx *ctx, c;
+
+ if (!(ctx = heap_alloc(sizeof(*ctx))))
+ ctx = &c;
+ ctx->device = device;
+ ctx->gl_view = gl_view;
+ ctx->object = object;
+ ctx->free = ctx != &c ? ctx : NULL;
+
+ wined3d_cs_destroy_object(device->cs, wined3d_view_gl_destroy_object, ctx);
+ if (!ctx->free)
+ device->cs->ops->finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
+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;
+
+ 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_rendertarget_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,
@@ -4756,6 +4850,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
adapter_gl_destroy_swapchain,
adapter_gl_create_buffer,
adapter_gl_destroy_buffer,
+ adapter_gl_create_rendertarget_view,
+ adapter_gl_destroy_rendertarget_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 73a16177f41..a58efb8b7d8 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -540,6 +540,52 @@ static void adapter_vk_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
+static HRESULT adapter_vk_create_rendertarget_view(const struct wined3d_view_desc *desc,
+ struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_view **view)
+{
+ struct wined3d_rendertarget_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_rendertarget_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 render target view %p.\n", view_vk);
+ *view = &view_vk->v;
+
+ return hr;
+}
+
+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;
+
+ 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_rendertarget_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,
@@ -555,6 +601,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
adapter_vk_destroy_swapchain,
adapter_vk_create_buffer,
adapter_vk_destroy_buffer,
+ adapter_vk_create_rendertarget_view,
+ adapter_vk_destroy_rendertarget_view,
};
static unsigned int wined3d_get_wine_vk_version(void)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 7cc2490390a..5a4f7d2471e 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2430,6 +2430,51 @@ static void adapter_no3d_destroy_buffer(struct wined3d_buffer *buffer)
wined3d_device_decref(device);
}
+static HRESULT adapter_no3d_create_rendertarget_view(const struct wined3d_view_desc *desc,
+ struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_view **view)
+{
+ struct wined3d_rendertarget_view *view_no3d;
+ 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_no3d = heap_alloc_zero(sizeof(*view_no3d))))
+ return E_OUTOFMEMORY;
+
+ if (FAILED(hr = wined3d_rendertarget_view_no3d_init(view_no3d, desc, resource, parent, parent_ops)))
+ {
+ WARN("Failed to initialise view, hr %#x.\n", hr);
+ heap_free(view_no3d);
+ return hr;
+ }
+
+ TRACE("Created render target view %p.\n", view_no3d);
+ *view = view_no3d;
+
+ return hr;
+}
+
+static void adapter_no3d_destroy_rendertarget_view(struct wined3d_rendertarget_view *view)
+{
+ struct wined3d_device *device = view->resource->device;
+ unsigned int swapchain_count = device->swapchain_count;
+
+ TRACE("view %p.\n", view);
+
+ /* 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_rendertarget_view_cleanup(view);
+ wined3d_cs_destroy_object(device->cs, heap_free, view);
+ if (swapchain_count)
+ wined3d_device_decref(device);
+}
+
static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
{
adapter_no3d_destroy,
@@ -2445,6 +2490,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
adapter_no3d_destroy_swapchain,
adapter_no3d_create_buffer,
adapter_no3d_destroy_buffer,
+ adapter_no3d_create_rendertarget_view,
+ adapter_no3d_destroy_rendertarget_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 5ab7965d0f4..8239059279b 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -345,25 +345,12 @@ ULONG CDECL wined3d_rendertarget_view_incref(struct wined3d_rendertarget_view *v
return refcount;
}
-static void wined3d_rendertarget_view_gl_destroy_object(void *object)
+void wined3d_rendertarget_view_cleanup(struct wined3d_rendertarget_view *view)
{
- struct wined3d_rendertarget_view_gl *view_gl = object;
- struct wined3d_device *device = view_gl->v.resource->device;
-
- if (view_gl->gl_view.name)
- {
- const struct wined3d_gl_info *gl_info;
- struct wined3d_context *context;
-
- context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- context_gl_resource_released(device, view_gl->gl_view.name, FALSE);
- 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_rendertarget_view_decref(struct wined3d_rendertarget_view *view)
@@ -373,17 +360,7 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *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_rendertarget_view_gl_destroy_object,
- wined3d_rendertarget_view_gl(view));
- wined3d_resource_decref(resource);
- }
+ view->resource->device->adapter->adapter_ops->adapter_destroy_rendertarget_view(view);
return refcount;
}
@@ -619,34 +596,56 @@ static HRESULT wined3d_rendertarget_view_init(struct wined3d_rendertarget_view *
return WINED3D_OK;
}
-HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
- struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
- struct wined3d_rendertarget_view **view)
+HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d,
+ const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
{
- struct wined3d_rendertarget_view_gl *object;
- HRESULT hr;
+ TRACE("view_no3d %p, desc %s, resource %p, parent %p, parent_ops %p.\n",
+ view_no3d, wined3d_debug_view_desc(desc, resource), resource, parent, parent_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);
+ return wined3d_rendertarget_view_init(view_no3d, desc, resource, parent, parent_ops);
+}
- if (!(object = heap_alloc_zero(sizeof(*object))))
- return E_OUTOFMEMORY;
+HRESULT wined3d_rendertarget_view_gl_init(struct wined3d_rendertarget_view_gl *view_gl,
+ const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+ HRESULT hr;
- if (FAILED(hr = wined3d_rendertarget_view_init(&object->v, desc, resource, parent, parent_ops)))
- {
- heap_free(object);
- WARN("Failed to initialise view, hr %#x.\n", hr);
- return hr;
- }
+ 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);
- wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_gl_cs_init, object);
+ if (FAILED(hr = wined3d_rendertarget_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
+ return hr;
- TRACE("Created render target view %p.\n", object);
- *view = &object->v;
+ wined3d_cs_init_object(resource->device->cs, wined3d_render_target_view_gl_cs_init, view_gl);
return hr;
}
+HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_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_rendertarget_view_init(&view_vk->v, desc, resource, parent, parent_ops);
+}
+
+HRESULT CDECL wined3d_rendertarget_view_create(const struct wined3d_view_desc *desc,
+ struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_rendertarget_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_rendertarget_view(desc, resource, parent, parent_ops, view);
+}
+
HRESULT CDECL wined3d_rendertarget_view_create_from_sub_resource(struct wined3d_texture *texture,
unsigned int sub_resource_idx, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_rendertarget_view **view)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 18fed2eda19..e9bb28536c9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2788,6 +2788,10 @@ struct wined3d_adapter_ops
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_buffer **buffer);
void (*adapter_destroy_buffer)(struct wined3d_buffer *buffer);
+ HRESULT (*adapter_create_rendertarget_view)(const struct wined3d_view_desc *desc,
+ 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);
};
/* The adapter structure */
@@ -4153,6 +4157,7 @@ struct wined3d_rendertarget_view
struct wined3d_view_desc desc;
};
+void wined3d_rendertarget_view_cleanup(struct wined3d_rendertarget_view *view) DECLSPEC_HIDDEN;
void wined3d_rendertarget_view_get_drawable_size(const struct wined3d_rendertarget_view *view,
const struct wined3d_context *context, unsigned int *width, unsigned int *height) DECLSPEC_HIDDEN;
void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_view *view,
@@ -4164,6 +4169,10 @@ void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view
void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view,
DWORD location) DECLSPEC_HIDDEN;
+HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d,
+ const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
+ void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+
struct wined3d_rendertarget_view_gl
{
struct wined3d_rendertarget_view v;
@@ -4176,6 +4185,25 @@ static inline struct wined3d_rendertarget_view_gl *wined3d_rendertarget_view_gl(
return CONTAINING_RECORD(view, struct wined3d_rendertarget_view_gl, v);
}
+HRESULT wined3d_rendertarget_view_gl_init(struct wined3d_rendertarget_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_rendertarget_view_vk
+{
+ struct wined3d_rendertarget_view v;
+};
+
+static inline struct wined3d_rendertarget_view_vk *wined3d_rendertarget_view_vk(
+ struct wined3d_rendertarget_view *view)
+{
+ return CONTAINING_RECORD(view, struct wined3d_rendertarget_view_vk, v);
+}
+
+HRESULT wined3d_rendertarget_view_vk_init(struct wined3d_rendertarget_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_shader_resource_view
{
LONG refcount;
--
2.11.0
More information about the wine-devel
mailing list