=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Implement applying state for compute pipeline.

Alexandre Julliard julliard at winehq.org
Tue Feb 7 16:02:28 CST 2017


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

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Mon Feb  6 14:12:14 2017 +0100

wined3d: Implement applying state for compute pipeline.

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/context.c         | 45 +++++++++++++++++++++++++++++++++++++-----
 dlls/wined3d/cs.c              | 19 ++++++++++++++----
 dlls/wined3d/device.c          |  8 ++++++++
 dlls/wined3d/wined3d_private.h |  5 +++++
 4 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index c141d70..5ae1bdc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -1405,6 +1405,16 @@ static void context_enter(struct wined3d_context *context)
     }
 }
 
+void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id)
+{
+    DWORD representative = context->state_table[state_id].representative;
+    unsigned int index, shift;
+
+    index = representative / (sizeof(*context->dirty_compute_states) * CHAR_BIT);
+    shift = representative & (sizeof(*context->dirty_compute_states) * CHAR_BIT - 1);
+    context->dirty_compute_states[index] |= (1u << shift);
+}
+
 void context_invalidate_state(struct wined3d_context *context, DWORD state)
 {
     DWORD rep = context->state_table[state].representative;
@@ -3312,7 +3322,8 @@ static void context_preload_textures(struct wined3d_context *context, const stru
     }
 }
 
-static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state)
+static void context_load_shader_resources(struct wined3d_context *context, const struct wined3d_state *state,
+        unsigned int shader_mask)
 {
     struct wined3d_shader_sampler_map_entry *entry;
     struct wined3d_shader_resource_view *view;
@@ -3321,6 +3332,9 @@ static void context_load_shader_resources(struct wined3d_context *context, const
 
     for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
     {
+        if (!(shader_mask & (1u << i)))
+            continue;
+
         if (!(shader = state->shader[i]))
             continue;
 
@@ -3489,7 +3503,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
      * updating a resource location. */
     context_update_tex_unit_map(context, state);
     context_preload_textures(context, state);
-    context_load_shader_resources(context, state);
+    context_load_shader_resources(context, state, ~(1u << WINED3D_SHADER_TYPE_COMPUTE));
     /* TODO: Right now the dependency on the vertex shader is necessary
      * since context_stream_info_from_declaration depends on the reg_maps of
      * the current VS but maybe it's possible to relax the coupling in some
@@ -3528,10 +3542,10 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
         state_table[rep].apply(context, state, rep);
     }
 
-    if (context->shader_update_mask)
+    if (context->shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE))
     {
         device->shader_backend->shader_select(device->shader_priv, context, state);
-        context->shader_update_mask = 0;
+        context->shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
     }
 
     if (context->constant_update_mask)
@@ -3566,7 +3580,28 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
 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");
+    const struct StateEntry *state_table = context->state_table;
+    unsigned int state_id, i, j;
+
+    context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
+
+    for (i = 0, state_id = 0; i < ARRAY_SIZE(context->dirty_compute_states); ++i)
+    {
+        for (j = 0; j < sizeof(*context->dirty_compute_states) * CHAR_BIT; ++j, ++state_id)
+        {
+            if (context->dirty_compute_states[i] & (1u << j))
+                state_table[state_id].apply(context, state, state_id);
+        }
+    }
+    memset(context->dirty_compute_states, 0, sizeof(*context->dirty_compute_states));
+
+    if (context->shader_update_mask & (1u << WINED3D_SHADER_TYPE_COMPUTE))
+    {
+        device->shader_backend->shader_select_compute(device->shader_priv, context, state);
+        context->shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE);
+    }
+
+    context->last_was_blit = FALSE;
 }
 
 static void context_setup_target(struct wined3d_context *context,
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 220ddee..d575159 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -907,7 +907,10 @@ static void wined3d_cs_exec_set_constant_buffer(struct wined3d_cs *cs, const voi
     if (prev)
         InterlockedDecrement(&prev->resource.bind_count);
 
-    device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
+    if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+        device_invalidate_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
+    else
+        device_invalidate_compute_state(cs->device, STATE_CONSTANT_BUFFER(op->type));
 }
 
 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
@@ -1020,7 +1023,8 @@ static void wined3d_cs_exec_set_shader_resource_view(struct wined3d_cs *cs, cons
     const struct wined3d_cs_set_shader_resource_view *op = data;
 
     cs->state.shader_resource_view[op->type][op->view_idx] = op->view;
-    device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+    if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+        device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
 }
 
 void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, unsigned int view_idx,
@@ -1093,8 +1097,15 @@ static void wined3d_cs_exec_set_shader(struct wined3d_cs *cs, const void *data)
     const struct wined3d_cs_set_shader *op = data;
 
     cs->state.shader[op->type] = op->shader;
-    device_invalidate_state(cs->device, STATE_SHADER(op->type));
-    device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+    if (op->type != WINED3D_SHADER_TYPE_COMPUTE)
+    {
+        device_invalidate_state(cs->device, STATE_SHADER(op->type));
+        device_invalidate_state(cs->device, STATE_SHADER_RESOURCE_BINDING);
+    }
+    else
+    {
+        device_invalidate_compute_state(cs->device, STATE_SHADER(op->type));
+    }
 }
 
 void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 0e969be..71bb929 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5113,6 +5113,14 @@ void device_invalidate_state(const struct wined3d_device *device, DWORD state)
     }
 }
 
+void device_invalidate_compute_state(const struct wined3d_device *device, DWORD state_id)
+{
+    unsigned int i;
+
+    for (i = 0; i < device->context_count; ++i)
+        context_invalidate_compute_state(device->contexts[i], state_id);
+}
+
 LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL unicode,
         UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc)
 {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9b16e14..ead8847 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1427,6 +1427,8 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
 
 #define STATE_HIGHEST (STATE_COLOR_KEY)
 
+#define STATE_COMPUTE_HIGHEST (STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE))
+
 enum fogsource {
     FOGSOURCE_FFP,
     FOGSOURCE_VS,
@@ -1530,6 +1532,7 @@ struct wined3d_context
     DWORD                   dirtyArray[STATE_HIGHEST + 1]; /* Won't get bigger than that, a state is never marked dirty 2 times */
     DWORD                   numDirtyEntries;
     DWORD isStateDirty[STATE_HIGHEST / (sizeof(DWORD) * CHAR_BIT) + 1]; /* Bitmap to find out quickly if a state is dirty */
+    unsigned int dirty_compute_states[STATE_COMPUTE_HIGHEST / (sizeof(unsigned int) * CHAR_BIT) + 1];
 
     struct wined3d_device *device;
     struct wined3d_swapchain *swapchain;
@@ -1811,6 +1814,7 @@ GLenum context_get_offscreen_gl_buffer(const struct wined3d_context *context) DE
 DWORD context_get_tls_idx(void) DECLSPEC_HIDDEN;
 void context_gl_resource_released(struct wined3d_device *device,
         GLuint name, BOOL rb_namespace) DECLSPEC_HIDDEN;
+void context_invalidate_compute_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
 void context_invalidate_state(struct wined3d_context *context, DWORD state_id) DECLSPEC_HIDDEN;
 void context_release(struct wined3d_context *context) DECLSPEC_HIDDEN;
 void context_resource_released(const struct wined3d_device *device,
@@ -2627,6 +2631,7 @@ LRESULT device_process_message(struct wined3d_device *device, HWND window, BOOL
         UINT message, WPARAM wparam, LPARAM lparam, WNDPROC proc) DECLSPEC_HIDDEN;
 void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
 void device_resource_released(struct wined3d_device *device, struct wined3d_resource *resource) DECLSPEC_HIDDEN;
+void device_invalidate_compute_state(const struct wined3d_device *device, DWORD state_id) DECLSPEC_HIDDEN;
 void device_invalidate_state(const struct wined3d_device *device, DWORD state) DECLSPEC_HIDDEN;
 
 static inline BOOL isStateDirty(const struct wined3d_context *context, DWORD state)




More information about the wine-cvs mailing list