[PATCH 6/8] wined3d: Introduce wined3d_device_dispatch_compute().

Józef Kucia jkucia at codeweavers.com
Thu Feb 2 05:43:40 CST 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

Compute pipeline UAVs will be introduced later in the patch series.

---
 dlls/wined3d/context.c         |  6 ++++++
 dlls/wined3d/cs.c              | 36 +++++++++++++++++++++++++++++++++++
 dlls/wined3d/device.c          |  9 +++++++++
 dlls/wined3d/drawprim.c        | 43 ++++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/wined3d.spec      |  1 +
 dlls/wined3d/wined3d_private.h |  6 ++++++
 include/wine/wined3d.h         |  2 ++
 7 files changed, 103 insertions(+)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index fdf684e..238ae31 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3564,6 +3564,12 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
     return TRUE;
 }
 
+void context_apply_compute_state(struct wined3d_context *context,
+        const struct wined3d_device *device, const struct wined3d_state *state)
+{
+    FIXME("Implement applying compute state.\n");
+}
+
 static void context_setup_target(struct wined3d_context *context,
         struct wined3d_texture *texture, unsigned int sub_resource_idx)
 {
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index d2c334f..220ddee 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -28,6 +28,7 @@ enum wined3d_cs_op
 {
     WINED3D_CS_OP_PRESENT,
     WINED3D_CS_OP_CLEAR,
+    WINED3D_CS_OP_DISPATCH,
     WINED3D_CS_OP_DRAW,
     WINED3D_CS_OP_SET_PREDICATION,
     WINED3D_CS_OP_SET_VIEWPORT,
@@ -83,6 +84,14 @@ struct wined3d_cs_clear
     RECT rects[1];
 };
 
+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_cs_draw
 {
     enum wined3d_cs_op opcode;
@@ -482,6 +491,32 @@ static void release_shader_resources(const struct wined3d_state *state, unsigned
     }
 }
 
+static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_dispatch *op = data;
+
+    dispatch_compute(cs->device, &cs->device->state,
+            op->group_count_x, op->group_count_y, op->group_count_z);
+
+    release_shader_resources(&cs->device->state, 1u << WINED3D_SHADER_TYPE_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)
+{
+    struct wined3d_cs_dispatch *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    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;
+
+    acquire_shader_resources(&cs->device->state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
+
+    cs->ops->submit(cs);
+}
+
 static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
 {
     struct wined3d_state *state = &cs->device->state;
@@ -1462,6 +1497,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
 {
     /* WINED3D_CS_OP_PRESENT                    */ wined3d_cs_exec_present,
     /* WINED3D_CS_OP_CLEAR                      */ wined3d_cs_exec_clear,
+    /* WINED3D_CS_OP_DISPATCH                   */ wined3d_cs_exec_dispatch,
     /* WINED3D_CS_OP_DRAW                       */ wined3d_cs_exec_draw,
     /* WINED3D_CS_OP_SET_PREDICATION            */ wined3d_cs_exec_set_predication,
     /* WINED3D_CS_OP_SET_VIEWPORT               */ wined3d_cs_exec_set_viewport,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index acf4307..edf7d7e 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -3482,6 +3482,15 @@ struct wined3d_query * CDECL wined3d_device_get_predication(struct wined3d_devic
     return device->state.predicate;
 }
 
+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)
+{
+    TRACE("device %p, group_count_x %u, group_count_y %u, group_count_z %u.\n",
+            device, group_count_x, group_count_y, group_count_z);
+
+    wined3d_cs_emit_dispatch(device->cs, group_count_x, group_count_y, group_count_z);
+}
+
 void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device,
         enum wined3d_primitive_type primitive_type)
 {
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index a3d88b9..4980413 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -580,3 +580,46 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s
 
     TRACE("Done all gl drawing.\n");
 }
+
+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_gl_info *gl_info;
+    struct wined3d_context *context;
+
+    context = context_acquire(device, NULL);
+    if (!context->valid)
+    {
+        context_release(context);
+        WARN("Invalid context, skipping dispatch.\n");
+        return;
+    }
+    gl_info = context->gl_info;
+
+    if (!gl_info->supported[ARB_COMPUTE_SHADER])
+    {
+        context_release(context);
+        FIXME("OpenGL implementation does not support compute shaders.\n");
+        return;
+    }
+
+    context_apply_compute_state(context, device, state);
+
+    if (!state->shader[WINED3D_SHADER_TYPE_COMPUTE])
+    {
+        context_release(context);
+        WARN("No compute shader bound, skipping dispatch.\n");
+        return;
+    }
+
+    GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z));
+    checkGLcall("glDispatchCompute");
+
+    GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS));
+    checkGLcall("glMemoryBarrier");
+
+    if (wined3d_settings.strict_draw_ordering)
+        gl_info->gl_ops.gl.p_glFlush(); /* Flush to ensure ordering across contexts. */
+
+    context_release(context);
+}
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 3e87ca2..57e1efb 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -39,6 +39,7 @@
 @ cdecl wined3d_device_copy_sub_resource_region(ptr ptr long long long long 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)
 @ 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 71a7784..02dd8b5 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1343,6 +1343,8 @@ struct wined3d_stream_info
 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;
 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
 
 #define eps 1e-8f
@@ -1783,6 +1785,8 @@ void context_alloc_occlusion_query(struct wined3d_context *context,
 void context_apply_blit_state(struct wined3d_context *context, const struct wined3d_device *device) DECLSPEC_HIDDEN;
 BOOL context_apply_clear_state(struct wined3d_context *context, const struct wined3d_state *state,
         UINT rt_count, const struct wined3d_fb_state *fb) DECLSPEC_HIDDEN;
+void context_apply_compute_state(struct wined3d_context *context,
+        const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN;
 BOOL context_apply_draw_state(struct wined3d_context *context,
         const struct wined3d_device *device, const struct wined3d_state *state) DECLSPEC_HIDDEN;
 void context_apply_fbo_state_blit(struct wined3d_context *context, GLenum target,
@@ -3133,6 +3137,8 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT *
         DWORD flags, const struct wined3d_color *color, float depth, DWORD stencil) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_destroy_object(struct wined3d_cs *cs,
         void (*callback)(void *object), void *object) 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, 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 wined3d_cs_emit_preload_resource(struct wined3d_cs *cs, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 42a125d..8b8305b 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2129,6 +2129,8 @@ 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);
 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);
 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);
-- 
2.10.2




More information about the wine-patches mailing list