=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Implement indirect compute dispatch.

Alexandre Julliard julliard at winehq.org
Wed Aug 16 09:06:25 CDT 2017


Module: wine
Branch: master
Commit: 2f66f1288fb598710a7f68a4d918ee2565f6ea56
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2f66f1288fb598710a7f68a4d918ee2565f6ea56

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Mon Aug 14 23:47:41 2017 +0200

wined3d: Implement indirect compute dispatch.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/cs.c              | 46 ++++++++++++++++++++++++++++++++----------
 dlls/wined3d/device.c          |  8 ++++++++
 dlls/wined3d/drawprim.c        | 20 +++++++++++++++---
 dlls/wined3d/wined3d.spec      |  1 +
 dlls/wined3d/wined3d_private.h | 27 ++++++++++++++++++++++++-
 include/wine/wined3d.h         |  2 ++
 6 files changed, 89 insertions(+), 15 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index a76598f..8961dfe 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -112,9 +112,7 @@ struct wined3d_cs_clear
 struct wined3d_cs_dispatch
 {
     enum wined3d_cs_op opcode;
-    unsigned int group_count_x;
-    unsigned int group_count_y;
-    unsigned int group_count_z;
+    struct wined3d_dispatch_parameters parameters;
 };
 
 struct wined3d_cs_draw
@@ -705,14 +703,23 @@ static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data)
     const struct wined3d_cs_dispatch *op = data;
     struct wined3d_state *state = &cs->state;
 
-    dispatch_compute(cs->device, state,
-            op->group_count_x, op->group_count_y, op->group_count_z);
+    dispatch_compute(cs->device, state, &op->parameters);
+
+    if (op->parameters.indirect)
+        wined3d_resource_release(&op->parameters.u.indirect.buffer->resource);
 
     release_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
     release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
             state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
 }
 
+static void acquire_compute_pipeline_resources(const struct wined3d_state *state)
+{
+    acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
+    acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
+            state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
+}
+
 void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
         unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z)
 {
@@ -721,13 +728,30 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
 
     op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
     op->opcode = WINED3D_CS_OP_DISPATCH;
-    op->group_count_x = group_count_x;
-    op->group_count_y = group_count_y;
-    op->group_count_z = group_count_z;
+    op->parameters.indirect = FALSE;
+    op->parameters.u.direct.group_count_x = group_count_x;
+    op->parameters.u.direct.group_count_y = group_count_y;
+    op->parameters.u.direct.group_count_z = group_count_z;
 
-    acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
-    acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE],
-            state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]);
+    acquire_compute_pipeline_resources(state);
+
+    cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
+}
+
+void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs,
+        struct wined3d_buffer *buffer, unsigned int offset)
+{
+    const struct wined3d_state *state = &cs->device->state;
+    struct wined3d_cs_dispatch *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT);
+    op->opcode = WINED3D_CS_OP_DISPATCH;
+    op->parameters.indirect = TRUE;
+    op->parameters.u.indirect.buffer = buffer;
+    op->parameters.u.indirect.offset = offset;
+
+    acquire_compute_pipeline_resources(state);
+    wined3d_resource_acquire(&buffer->resource);
 
     cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT);
 }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 30e7fbe..31955ba 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3652,6 +3652,14 @@ void CDECL wined3d_device_dispatch_compute(struct wined3d_device *device,
     wined3d_cs_emit_dispatch(device->cs, group_count_x, group_count_y, group_count_z);
 }
 
+void CDECL wined3d_device_dispatch_compute_indirect(struct wined3d_device *device,
+        struct wined3d_buffer *buffer, unsigned int offset)
+{
+    TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset);
+
+    wined3d_cs_emit_dispatch_indirect(device->cs, buffer, offset);
+}
+
 void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
         enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count)
 {
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index e9bce44..235f87b 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -669,7 +669,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
 }
 
 void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
-        unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z)
+        const struct wined3d_dispatch_parameters *parameters)
 {
     const struct wined3d_gl_info *gl_info;
     struct wined3d_context *context;
@@ -699,8 +699,22 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state
         return;
     }
 
-    GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z));
-    checkGLcall("glDispatchCompute");
+    if (parameters->indirect)
+    {
+        const struct wined3d_indirect_dispatch_parameters *indirect = &parameters->u.indirect;
+        struct wined3d_buffer *buffer = indirect->buffer;
+
+        wined3d_buffer_load(buffer, context, state);
+        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object));
+        GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset));
+        GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0));
+    }
+    else
+    {
+        const struct wined3d_direct_dispatch_parameters *direct = &parameters->u.direct;
+        GL_EXTCALL(glDispatchCompute(direct->group_count_x, direct->group_count_y, direct->group_count_z));
+    }
+    checkGLcall("dispatch compute");
 
     GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
     checkGLcall("glMemoryBarrier");
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index c0724ab..fb8188e 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -42,6 +42,7 @@
 @ 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)
+@ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long)
 @ cdecl wined3d_device_draw_indexed_primitive(ptr long long)
 @ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long)
 @ cdecl wined3d_device_draw_primitive(ptr long long)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f8aeb62..74043d0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1479,11 +1479,34 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf
         const struct wined3d_state *state, const struct wined3d_gl_info *gl_info,
         const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;
 
+struct wined3d_direct_dispatch_parameters
+{
+    unsigned int group_count_x;
+    unsigned int group_count_y;
+    unsigned int group_count_z;
+};
+
+struct wined3d_indirect_dispatch_parameters
+{
+    struct wined3d_buffer *buffer;
+    unsigned int offset;
+};
+
+struct wined3d_dispatch_parameters
+{
+    BOOL indirect;
+    union
+    {
+        struct wined3d_direct_dispatch_parameters direct;
+        struct wined3d_indirect_dispatch_parameters indirect;
+    } u;
+};
+
 void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state,
         int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
         unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
 void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state,
-        unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN;
+        const struct wined3d_dispatch_parameters *dispatch_parameters) DECLSPEC_HIDDEN;
 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
 
 #define eps 1e-8f
@@ -3430,6 +3453,8 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff
         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_dispatch_indirect(struct wined3d_cs *cs,
+        struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count,
         int base_vertex_idx, unsigned int start_idx, unsigned int index_count,
         unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index b92ada0..6fa31e7 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2217,6 +2217,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx,
 ULONG __cdecl wined3d_device_decref(struct wined3d_device *device);
 void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device,
         unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z);
+void __cdecl wined3d_device_dispatch_compute_indirect(struct wined3d_device *device,
+        struct wined3d_buffer *buffer, unsigned int offset);
 HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count);
 void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device,
         UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);




More information about the wine-cvs mailing list