From: Józef Kucia Subject: [PATCH 6/9] wined3d: Introduce wined3d_unordered_access_view. Message-Id: <1466761565-15145-6-git-send-email-jkucia@codeweavers.com> Date: Fri, 24 Jun 2016 11:46:02 +0200 In-Reply-To: <1466761565-15145-1-git-send-email-jkucia@codeweavers.com> References: <1466761565-15145-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- dlls/wined3d/view.c | 106 +++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d.spec | 5 ++ dlls/wined3d/wined3d_private.h | 11 +++++ include/wine/wined3d.h | 28 +++++++++++ 4 files changed, 150 insertions(+) diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index e9e62d1..e39f6f8 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -415,3 +415,109 @@ void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view texture = wined3d_texture_from_resource(view->resource); wined3d_texture_bind(texture, context, FALSE); } + +ULONG CDECL wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view *view) +{ + ULONG refcount = InterlockedIncrement(&view->refcount); + + TRACE("%p increasing refcount to %u.\n", view, refcount); + + return refcount; +} + +static void wined3d_unordered_access_view_destroy_object(void *object) +{ + HeapFree(GetProcessHeap(), 0, object); +} + +ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view) +{ + ULONG refcount = InterlockedDecrement(&view->refcount); + + TRACE("%p decreasing refcount to %u.\n", view, refcount); + + if (!refcount) + { + struct wined3d_device *device = view->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_resource_decref(view->resource); + wined3d_cs_emit_destroy_object(device->cs, wined3d_unordered_access_view_destroy_object, view); + } + + return refcount; +} + +void * CDECL wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view *view) +{ + TRACE("view %p.\n", view); + + return view->parent; +} + +static HRESULT wined3d_unordered_access_view_init(struct wined3d_unordered_access_view *view, + const struct wined3d_unordered_access_view_desc *desc, struct wined3d_resource *resource, + void *parent, const struct wined3d_parent_ops *parent_ops) +{ + const struct wined3d_gl_info *gl_info = &resource->device->adapter->gl_info; + + view->refcount = 1; + view->parent = parent; + view->parent_ops = parent_ops; + + view->format = wined3d_get_format(gl_info, desc->format_id); + + if (wined3d_format_is_typeless(view->format)) + { + WARN("Trying to create view for typeless format %s.\n", debug_d3dformat(view->format->id)); + return E_INVALIDARG; + } + + if (resource->type != WINED3D_RTYPE_BUFFER) + { + struct wined3d_texture *texture = texture_from_resource(resource); + unsigned int depth_or_layer_count; + + if (resource->type == WINED3D_RTYPE_TEXTURE_3D) + depth_or_layer_count = wined3d_texture_get_level_depth(texture, desc->u.texture.level_idx); + else + depth_or_layer_count = texture->layer_count; + + if (desc->u.texture.level_idx >= texture->level_count + || desc->u.texture.layer_idx >= depth_or_layer_count + || !desc->u.texture.layer_count + || desc->u.texture.layer_count > depth_or_layer_count - desc->u.texture.layer_idx) + return E_INVALIDARG; + } + wined3d_resource_incref(view->resource = resource); + + return WINED3D_OK; +} + +HRESULT CDECL wined3d_unordered_access_view_create(const struct wined3d_unordered_access_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 *object; + HRESULT hr; + + TRACE("desc %p, resource %p, parent %p, parent_ops %p, view %p.\n", + desc, resource, parent, parent_ops, view); + + if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = wined3d_unordered_access_view_init(object, desc, resource, parent, parent_ops))) + { + HeapFree(GetProcessHeap(), 0, object); + WARN("Failed to initialise view, hr %#x.\n", hr); + return hr; + } + + TRACE("Created unordered access view %p.\n", object); + *view = object; + + return WINED3D_OK; +} diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 8d1d8dc..87fdb81 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -267,6 +267,11 @@ @ cdecl wined3d_texture_update_desc(ptr long long long long long ptr long) @ cdecl wined3d_texture_update_overlay(ptr long ptr ptr long ptr long) +@ cdecl wined3d_unordered_access_view_create(ptr ptr ptr ptr ptr) +@ cdecl wined3d_unordered_access_view_decref(ptr) +@ cdecl wined3d_unordered_access_view_get_parent(ptr) +@ cdecl wined3d_unordered_access_view_incref(ptr) + @ cdecl wined3d_vertex_declaration_create(ptr ptr long ptr ptr ptr) @ cdecl wined3d_vertex_declaration_create_from_fvf(ptr long ptr ptr ptr) @ cdecl wined3d_vertex_declaration_decref(ptr) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ce094ca..59734e0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3135,6 +3135,17 @@ struct wined3d_shader_resource_view void wined3d_shader_resource_view_bind(struct wined3d_shader_resource_view *view, struct wined3d_context *context) DECLSPEC_HIDDEN; +struct wined3d_unordered_access_view +{ + LONG refcount; + + struct wined3d_resource *resource; + void *parent; + const struct wined3d_parent_ops *parent_ops; + + const struct wined3d_format *format; +}; + struct wined3d_swapchain_ops { void (*swapchain_present)(struct wined3d_swapchain *swapchain, diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 9becd6f..d7bf0f8 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -1969,6 +1969,26 @@ struct wined3d_shader_resource_view_desc } u; }; +struct wined3d_unordered_access_view_desc +{ + enum wined3d_format_id format_id; + unsigned int flags; + union + { + struct + { + unsigned int start_idx; + unsigned int count; + } buffer; + struct + { + unsigned int level_idx; + unsigned int layer_idx; + unsigned int layer_count; + } texture; + } u; +}; + struct wined3d_output_desc { WCHAR device_name[CCHDEVICENAME]; @@ -1996,6 +2016,7 @@ struct wined3d_shader_resource_view; struct wined3d_stateblock; struct wined3d_swapchain; struct wined3d_texture; +struct wined3d_unordered_access_view; struct wined3d_vertex_declaration; struct wined3d_device_parent @@ -2532,6 +2553,13 @@ HRESULT __cdecl wined3d_texture_update_overlay(struct wined3d_texture *texture, const RECT *src_rect, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx, const RECT *dst_rect, DWORD flags); +HRESULT __cdecl wined3d_unordered_access_view_create(const struct wined3d_unordered_access_view_desc *desc, + struct wined3d_resource *resource, void *parent, const struct wined3d_parent_ops *parent_ops, + struct wined3d_unordered_access_view **view); +ULONG __cdecl wined3d_unordered_access_view_decref(struct wined3d_unordered_access_view *view); +void * __cdecl wined3d_unordered_access_view_get_parent(const struct wined3d_unordered_access_view *view); +ULONG __cdecl wined3d_unordered_access_view_incref(struct wined3d_unordered_access_view *view); + HRESULT __cdecl wined3d_vertex_declaration_create(struct wined3d_device *device, const struct wined3d_vertex_element *elements, UINT element_count, void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_vertex_declaration **declaration); -- 2.7.3