wined3d: Make the adapter responsible for unordered access view creation and destruction.

Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Henri Verbeet 2019-08-11 14:05:12 +04:30 committed by Alexandre Julliard
parent a3241fa2a8
commit eeed93464b
5 changed files with 186 additions and 54 deletions

View File

@ -4771,6 +4771,7 @@ struct wined3d_view_gl_destroy_ctx
{
struct wined3d_device *device;
const struct wined3d_gl_view *gl_view;
GLuint counter_bo;
void *object;
struct wined3d_view_gl_destroy_ctx *free;
};
@ -4784,12 +4785,17 @@ static void wined3d_view_gl_destroy_object(void *object)
device = ctx->device;
if (ctx->gl_view->name)
if (ctx->gl_view->name || ctx->counter_bo)
{
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);
if (ctx->gl_view->name)
{
context_gl_resource_released(device, ctx->gl_view->name, FALSE);
gl_info->gl_ops.gl.p_glDeleteTextures(1, &ctx->gl_view->name);
}
if (ctx->counter_bo)
GL_EXTCALL(glDeleteBuffers(1, &ctx->counter_bo));
checkGLcall("delete resources");
context_release(context);
}
@ -4799,7 +4805,7 @@ static void wined3d_view_gl_destroy_object(void *object)
}
static void wined3d_view_gl_destroy(struct wined3d_device *device,
const struct wined3d_gl_view *gl_view, void *object)
const struct wined3d_gl_view *gl_view, GLuint counter_bo, void *object)
{
struct wined3d_view_gl_destroy_ctx *ctx, c;
@ -4807,6 +4813,7 @@ static void wined3d_view_gl_destroy(struct wined3d_device *device,
ctx = &c;
ctx->device = device;
ctx->gl_view = gl_view;
ctx->counter_bo = counter_bo;
ctx->object = object;
ctx->free = ctx != &c ? ctx : NULL;
@ -4830,7 +4837,7 @@ static void adapter_gl_destroy_rendertarget_view(struct wined3d_rendertarget_vie
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);
wined3d_view_gl_destroy(device, &view_gl->gl_view, 0, view_gl);
if (swapchain_count)
wined3d_device_decref(device);
}
@ -4876,7 +4883,53 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour
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);
wined3d_view_gl_destroy(device, &view_gl->gl_view, 0, view_gl);
if (swapchain_count)
wined3d_device_decref(device);
}
static HRESULT adapter_gl_create_unordered_access_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_unordered_access_view **view)
{
struct wined3d_unordered_access_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_unordered_access_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 unordered access view %p.\n", view_gl);
*view = &view_gl->v;
return hr;
}
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;
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_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);
}
@ -4900,6 +4953,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_gl_ops =
adapter_gl_destroy_rendertarget_view,
adapter_gl_create_shader_resource_view,
adapter_gl_destroy_shader_resource_view,
adapter_gl_create_unordered_access_view,
adapter_gl_destroy_unordered_access_view,
};
static BOOL wined3d_adapter_gl_init(struct wined3d_adapter_gl *adapter_gl,

View File

@ -632,6 +632,52 @@ static void adapter_vk_destroy_shader_resource_view(struct wined3d_shader_resour
wined3d_device_decref(device);
}
static HRESULT adapter_vk_create_unordered_access_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_unordered_access_view **view)
{
struct wined3d_unordered_access_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_unordered_access_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 unordered access view %p.\n", view_vk);
*view = &view_vk->v;
return hr;
}
static void adapter_vk_destroy_unordered_access_view(struct wined3d_unordered_access_view *view)
{
struct wined3d_unordered_access_view_vk *view_vk = wined3d_unordered_access_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_unordered_access_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,
@ -651,6 +697,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_vk_ops =
adapter_vk_destroy_rendertarget_view,
adapter_vk_create_shader_resource_view,
adapter_vk_destroy_shader_resource_view,
adapter_vk_create_unordered_access_view,
adapter_vk_destroy_unordered_access_view,
};
static unsigned int wined3d_get_wine_vk_version(void)

View File

@ -2490,6 +2490,21 @@ static void adapter_no3d_destroy_shader_resource_view(struct wined3d_shader_reso
TRACE("view %p.\n", view);
}
static HRESULT adapter_no3d_create_unordered_access_view(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_unordered_access_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_unordered_access_view(struct wined3d_unordered_access_view *view)
{
TRACE("view %p.\n", view);
}
static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
{
adapter_no3d_destroy,
@ -2509,6 +2524,8 @@ static const struct wined3d_adapter_ops wined3d_adapter_no3d_ops =
adapter_no3d_destroy_rendertarget_view,
adapter_no3d_create_shader_resource_view,
adapter_no3d_destroy_shader_resource_view,
adapter_no3d_create_unordered_access_view,
adapter_no3d_destroy_unordered_access_view,
};
static void wined3d_adapter_no3d_init_d3d_info(struct wined3d_adapter *adapter, unsigned int wined3d_creation_flags)

View File

@ -963,26 +963,12 @@ ULONG CDECL wined3d_unordered_access_view_incref(struct wined3d_unordered_access
return refcount;
}
static void wined3d_unordered_access_view_gl_destroy_object(void *object)
void wined3d_unordered_access_view_cleanup(struct wined3d_unordered_access_view *view)
{
struct wined3d_unordered_access_view_gl *view_gl = object;
if (view_gl->gl_view.name || view_gl->counter_bo)
{
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;
if (view_gl->gl_view.name)
gl_info->gl_ops.gl.p_glDeleteTextures(1, &view_gl->gl_view.name);
if (view_gl->counter_bo)
GL_EXTCALL(glDeleteBuffers(1, &view_gl->counter_bo));
checkGLcall("delete resources");
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_unordered_access_view_decref(struct wined3d_unordered_access_view *view)
@ -992,17 +978,7 @@ ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access
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_unordered_access_view_gl_destroy_object,
wined3d_unordered_access_view_gl(view));
wined3d_resource_decref(resource);
}
view->resource->device->adapter->adapter_ops->adapter_destroy_unordered_access_view(view);
return refcount;
}
@ -1167,30 +1143,42 @@ static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_acces
return WINED3D_OK;
}
HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_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;
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_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
return hr;
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
return hr;
}
HRESULT wined3d_unordered_access_view_vk_init(struct wined3d_unordered_access_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_unordered_access_view_init(&view_vk->v, desc, resource, parent, parent_ops);
}
HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_unordered_access_view **view)
{
struct wined3d_unordered_access_view_gl *object;
HRESULT hr;
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);
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
if (FAILED(hr = wined3d_unordered_access_view_init(&object->v, desc, resource, parent, parent_ops)))
{
heap_free(object);
WARN("Failed to initialise view, hr %#x.\n", hr);
return hr;
}
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, object);
TRACE("Created unordered access view %p.\n", object);
*view = &object->v;
return WINED3D_OK;
adapter_ops = resource->device->adapter->adapter_ops;
return adapter_ops->adapter_create_unordered_access_view(desc, resource, parent, parent_ops, view);
}

View File

@ -2796,6 +2796,10 @@ struct wined3d_adapter_ops
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);
HRESULT (*adapter_create_unordered_access_view)(const struct wined3d_view_desc *desc,
struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops,
struct wined3d_unordered_access_view **view);
void (*adapter_destroy_unordered_access_view)(struct wined3d_unordered_access_view *view);
};
/* The adapter structure */
@ -4270,6 +4274,7 @@ struct wined3d_unordered_access_view
struct wined3d_view_desc desc;
};
void wined3d_unordered_access_view_cleanup(struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_view *view,
const struct wined3d_uvec4 *clear_value, struct wined3d_context *context) DECLSPEC_HIDDEN;
void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view,
@ -4292,6 +4297,25 @@ static inline struct wined3d_unordered_access_view_gl *wined3d_unordered_access_
return CONTAINING_RECORD(view, struct wined3d_unordered_access_view_gl, v);
}
HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_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_unordered_access_view_vk
{
struct wined3d_unordered_access_view v;
};
static inline struct wined3d_unordered_access_view_vk *wined3d_unordered_access_view_vk(
struct wined3d_unordered_access_view *view)
{
return CONTAINING_RECORD(view, struct wined3d_unordered_access_view_vk, v);
}
HRESULT wined3d_unordered_access_view_vk_init(struct wined3d_unordered_access_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_swapchain_state
{
struct wined3d_swapchain_desc desc;