From 24c39103be95d6fab75be663800ef90c180260c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Fri, 4 Aug 2017 19:53:48 +0200 Subject: [PATCH] wined3d: Implement copying UAV counters. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- dlls/wined3d/cs.c | 39 ++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 9 ++++++++ dlls/wined3d/view.c | 21 ++++++++++++++++++ dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 4 ++++ include/wine/wined3d.h | 2 ++ 6 files changed, 76 insertions(+) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index c785b7216bc..307cb577c98 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -70,6 +70,7 @@ enum wined3d_cs_op WINED3D_CS_OP_UPDATE_SUB_RESOURCE, WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION, WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW, + WINED3D_CS_OP_COPY_UAV_COUNTER, WINED3D_CS_OP_STOP, }; @@ -418,6 +419,14 @@ struct wined3d_cs_clear_unordered_access_view struct wined3d_uvec4 clear_value; }; +struct wined3d_cs_copy_uav_counter +{ + enum wined3d_cs_op opcode; + struct wined3d_buffer *buffer; + unsigned int offset; + struct wined3d_unordered_access_view *view; +}; + struct wined3d_cs_stop { enum wined3d_cs_op opcode; @@ -2228,6 +2237,35 @@ void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } +static void wined3d_cs_exec_copy_uav_counter(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_copy_uav_counter *op = data; + struct wined3d_unordered_access_view *view = op->view; + struct wined3d_context *context; + + context = context_acquire(cs->device, NULL, 0); + wined3d_unordered_access_view_copy_counter(view, op->buffer, op->offset, context); + context_release(context); + + wined3d_resource_release(&op->buffer->resource); +} + +void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *uav) +{ + struct wined3d_cs_copy_uav_counter *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_COPY_UAV_COUNTER; + op->buffer = dst_buffer; + op->offset = offset; + op->view = uav; + + wined3d_resource_acquire(&dst_buffer->resource); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + static void wined3d_cs_emit_stop(struct wined3d_cs *cs) { struct wined3d_cs_stop *op; @@ -2285,6 +2323,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_UPDATE_SUB_RESOURCE */ wined3d_cs_exec_update_sub_resource, /* WINED3D_CS_OP_ADD_DIRTY_TEXTURE_REGION */ wined3d_cs_exec_add_dirty_texture_region, /* WINED3D_CS_OP_CLEAR_UNORDERED_ACCESS_VIEW */ wined3d_cs_exec_clear_unordered_access_view, + /* WINED3D_CS_OP_COPY_UAV_COUNTER */ wined3d_cs_exec_copy_uav_counter, }; static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size, enum wined3d_cs_queue_id queue_id) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 3d12e417a43..18e1b010f03 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3959,6 +3959,15 @@ float CDECL wined3d_device_get_npatch_mode(const struct wined3d_device *device) return 0.0f; } +void CDECL wined3d_device_copy_uav_counter(struct wined3d_device *device, + struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav) +{ + TRACE("device %p, dst_buffer %p, offset %u, uav %p.\n", + device, dst_buffer, offset, uav); + + wined3d_cs_emit_copy_uav_counter(device->cs, dst_buffer, offset, uav); +} + void CDECL wined3d_device_copy_resource(struct wined3d_device *device, struct wined3d_resource *dst_resource, struct wined3d_resource *src_resource) { diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c index adb43dd3741..da915ea946a 100644 --- a/dlls/wined3d/view.c +++ b/dlls/wined3d/view.c @@ -898,6 +898,27 @@ void wined3d_unordered_access_view_clear_uint(struct wined3d_unordered_access_vi checkGLcall("clear unordered access view"); } +void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_view *view, + struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context) +{ + struct wined3d_bo_address dst, src; + DWORD dst_location; + + if (!view->counter_bo) + return; + + dst_location = wined3d_buffer_get_memory(buffer, &dst, buffer->locations); + dst.addr += offset; + + src.buffer_object = view->counter_bo; + src.addr = NULL; + + context_copy_bo_address(context, &dst, buffer->buffer_type_hint, + &src, GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint)); + + wined3d_buffer_invalidate_location(buffer, ~dst_location); +} + static void wined3d_unordered_access_view_cs_init(void *object) { struct wined3d_unordered_access_view *view = object; diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 43ec7aa1a41..fa33c5750ef 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -38,6 +38,7 @@ @ cdecl wined3d_device_clear_unordered_access_view_uint(ptr ptr ptr) @ cdecl wined3d_device_copy_resource(ptr ptr ptr) @ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long ptr long ptr) +@ cdecl wined3d_device_copy_uav_counter(ptr ptr long ptr) @ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr) @ cdecl wined3d_device_decref(ptr) @ cdecl wined3d_device_dispatch_compute(ptr long long long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 2270ae0f1c3..7d3e6970586 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3426,6 +3426,8 @@ void wined3d_cs_emit_clear_rendertarget_view(struct wined3d_cs *cs, struct wined const RECT *rect, DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN; void wined3d_cs_emit_clear_unordered_access_view_uint(struct wined3d_cs *cs, struct wined3d_unordered_access_view *view, const struct wined3d_uvec4 *clear_value) DECLSPEC_HIDDEN; +void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buffer *dst_buffer, + unsigned int offset, struct wined3d_unordered_access_view *uav) DECLSPEC_HIDDEN; void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count, @@ -3648,6 +3650,8 @@ struct wined3d_unordered_access_view 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, + struct wined3d_buffer *buffer, unsigned int offset, struct wined3d_context *context) DECLSPEC_HIDDEN; void wined3d_unordered_access_view_invalidate_location(struct wined3d_unordered_access_view *view, DWORD location) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index d176ab13740..f83217b48f8 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2209,6 +2209,8 @@ HRESULT __cdecl wined3d_device_copy_sub_resource_region(struct wined3d_device *d struct wined3d_resource *dst_resource, unsigned int dst_sub_resource_idx, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z, struct wined3d_resource *src_resource, unsigned int src_sub_resource_idx, const struct wined3d_box *src_box); +void __cdecl wined3d_device_copy_uav_counter(struct wined3d_device *device, + struct wined3d_buffer *dst_buffer, unsigned int offset, struct wined3d_unordered_access_view *uav); HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type, HWND focus_window, DWORD behaviour_flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent, struct wined3d_device **device);