[PATCH 8/8] wined3d: Implement applying state for compute pipeline.

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


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/wined3d/context.c | 71 +++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 238ae31..69902dc 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3313,7 +3313,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;
@@ -3322,6 +3323,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;
 
@@ -3467,13 +3471,35 @@ static void context_bind_unordered_access_views(struct wined3d_context *context,
     checkGLcall("Bind unordered access views");
 }
 
+static BOOL is_compute_state(DWORD state_id)
+{
+    switch (state_id)
+    {
+        case STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE):
+        case STATE_SHADER(WINED3D_SHADER_TYPE_COMPUTE):
+            return TRUE;
+        default:
+            return FALSE;
+    }
+}
+
+static inline void apply_state(struct wined3d_context *context,
+        const struct StateEntry *state_table, const struct wined3d_state *state,
+        DWORD representative)
+{
+    DWORD idx = representative / (sizeof(*context->isStateDirty) * CHAR_BIT);
+    BYTE shift = representative & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
+    context->isStateDirty[idx] &= ~(1u << shift);
+    state_table[representative].apply(context, state, representative);
+}
+
 /* Context activation is done by the caller. */
 BOOL context_apply_draw_state(struct wined3d_context *context,
         const struct wined3d_device *device, const struct wined3d_state *state)
 {
     const struct StateEntry *state_table = context->state_table;
     const struct wined3d_fb_state *fb = state->fb;
-    unsigned int i;
+    unsigned int i, dirty_idx;
     WORD map;
 
     if (!context_validate_rt_config(context->gl_info->limits.buffers,
@@ -3490,7 +3516,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
@@ -3520,19 +3546,19 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
             wined3d_buffer_load_sysmem(state->index_buffer, context);
     }
 
-    for (i = 0; i < context->numDirtyEntries; ++i)
+    for (i = 0, dirty_idx = 0; i < context->numDirtyEntries; ++i)
     {
         DWORD rep = context->dirtyArray[i];
-        DWORD idx = rep / (sizeof(*context->isStateDirty) * CHAR_BIT);
-        BYTE shift = rep & ((sizeof(*context->isStateDirty) * CHAR_BIT) - 1);
-        context->isStateDirty[idx] &= ~(1u << shift);
-        state_table[rep].apply(context, state, rep);
+        if (!is_compute_state(rep))
+            apply_state(context, state_table, state, rep);
+        else
+            context->dirtyArray[dirty_idx++] = 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)
@@ -3558,7 +3584,7 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
         context_check_fbo_status(context, GL_FRAMEBUFFER);
     }
 
-    context->numDirtyEntries = 0; /* This makes the whole list clean */
+    context->numDirtyEntries = dirty_idx;
     context->last_was_blit = FALSE;
 
     return TRUE;
@@ -3567,7 +3593,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 i, dirty_idx;
+
+    context_load_shader_resources(context, state, 1u << WINED3D_SHADER_TYPE_COMPUTE);
+
+    for (i = 0, dirty_idx = 0; i < context->numDirtyEntries; ++i)
+    {
+        DWORD rep = context->dirtyArray[i];
+        if (is_compute_state(rep))
+            apply_state(context, state_table, state, rep);
+        else
+            context->dirtyArray[dirty_idx++] = rep;
+    }
+
+    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->numDirtyEntries = dirty_idx;
+    context->last_was_blit = FALSE;
 }
 
 static void context_setup_target(struct wined3d_context *context,
-- 
2.10.2




More information about the wine-patches mailing list