[PATCH v2 2/9] wined3d: Implement compute pipeline UAV binding.

Józef Kucia jkucia at codeweavers.com
Thu Feb 9 05:00:29 CST 2017


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

Version 2:
* Fix order of functions.
* Unbind compute unordered access views in state_unbind_resources().

The last patch in the series attempts to merge
WINED3D_CS_OP_SET_COMPUTE_UAV and
WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW.

---
 dlls/wined3d/context.c         | 19 ++++++++++++++-----
 dlls/wined3d/cs.c              | 31 +++++++++++++++++++++++++++++++
 dlls/wined3d/device.c          | 26 ++++++++++++++++++++++++++
 dlls/wined3d/glsl_shader.c     |  3 ++-
 dlls/wined3d/state.c           |  9 +++++++++
 dlls/wined3d/stateblock.c      |  5 +++++
 dlls/wined3d/utils.c           |  2 ++
 dlls/wined3d/wined3d.spec      |  1 +
 dlls/wined3d/wined3d_private.h | 13 ++++++++++---
 include/wine/wined3d.h         |  2 ++
 10 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 61c9367..234cdb5 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -3425,19 +3425,18 @@ static void context_bind_shader_resources(struct wined3d_context *context, const
 }
 
 static void context_bind_unordered_access_views(struct wined3d_context *context,
-        const struct wined3d_state *state)
+        const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views)
 {
     const struct wined3d_gl_info *gl_info = context->gl_info;
     struct wined3d_unordered_access_view *view;
     struct wined3d_texture *texture;
-    struct wined3d_shader *shader;
     GLuint texture_name;
     unsigned int i;
     GLint level;
 
     context->uses_uavs = 0;
 
-    if (!(shader = state->shader[WINED3D_SHADER_TYPE_PIXEL]))
+    if (!shader)
         return;
 
     for (i = 0; i < MAX_UNORDERED_ACCESS_VIEWS; ++i)
@@ -3445,7 +3444,7 @@ static void context_bind_unordered_access_views(struct wined3d_context *context,
         if (!shader->reg_maps.uav_resource_info[i].type)
             continue;
 
-        if (!(view = state->unordered_access_view[i]))
+        if (!(view = views[i]))
         {
             WARN("No unordered access view bound at index %u.\n", i);
             GL_EXTCALL(glBindImageTexture(i, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8));
@@ -3563,8 +3562,10 @@ BOOL context_apply_draw_state(struct wined3d_context *context,
 
     if (context->update_unordered_access_view_bindings)
     {
-        context_bind_unordered_access_views(context, state);
+        context_bind_unordered_access_views(context,
+                state->shader[WINED3D_SHADER_TYPE_PIXEL], state->unordered_access_view);
         context->update_unordered_access_view_bindings = 0;
+        context->update_compute_unordered_access_view_bindings = 1;
     }
 
     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
@@ -3602,6 +3603,14 @@ void context_apply_compute_state(struct wined3d_context *context,
         context->shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE);
     }
 
+    if (context->update_compute_unordered_access_view_bindings)
+    {
+        context_bind_unordered_access_views(context,
+                state->shader[WINED3D_SHADER_TYPE_COMPUTE], state->compute_unordered_access_view);
+        context->update_compute_unordered_access_view_bindings = 0;
+        context->update_unordered_access_view_bindings = 1;
+    }
+
     context->last_was_blit = FALSE;
 }
 
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index b8fcf59..db94942 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -44,6 +44,7 @@ enum wined3d_cs_op
     WINED3D_CS_OP_SET_TEXTURE,
     WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW,
     WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW,
+    WINED3D_CS_OP_SET_COMPUTE_UAV,
     WINED3D_CS_OP_SET_SAMPLER,
     WINED3D_CS_OP_SET_SHADER,
     WINED3D_CS_OP_SET_RASTERIZER_STATE,
@@ -1067,6 +1068,35 @@ void wined3d_cs_emit_set_unordered_access_view(struct wined3d_cs *cs, unsigned i
     cs->ops->submit(cs);
 }
 
+static void wined3d_cs_exec_set_compute_unordered_access_view(struct wined3d_cs *cs, const void *data)
+{
+    const struct wined3d_cs_set_unordered_access_view *op = data;
+    struct wined3d_unordered_access_view *prev;
+
+    prev = cs->state.compute_unordered_access_view[op->view_idx];
+    cs->state.compute_unordered_access_view[op->view_idx] = op->view;
+
+    if (op->view)
+        InterlockedIncrement(&op->view->resource->bind_count);
+    if (prev)
+        InterlockedDecrement(&prev->resource->bind_count);
+
+    device_invalidate_state(cs->device, STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING);
+}
+
+void wined3d_cs_emit_set_compute_unordered_access_view(struct wined3d_cs *cs, unsigned int view_idx,
+        struct wined3d_unordered_access_view *view)
+{
+    struct wined3d_cs_set_unordered_access_view *op;
+
+    op = cs->ops->require_space(cs, sizeof(*op));
+    op->opcode = WINED3D_CS_OP_SET_COMPUTE_UAV;
+    op->view_idx = view_idx;
+    op->view = view;
+
+    cs->ops->submit(cs);
+}
+
 static void wined3d_cs_exec_set_sampler(struct wined3d_cs *cs, const void *data)
 {
     const struct wined3d_cs_set_sampler *op = data;
@@ -1515,6 +1545,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void
     /* WINED3D_CS_OP_SET_TEXTURE                */ wined3d_cs_exec_set_texture,
     /* WINED3D_CS_OP_SET_SHADER_RESOURCE_VIEW   */ wined3d_cs_exec_set_shader_resource_view,
     /* WINED3D_CS_OP_SET_UNORDERED_ACCESS_VIEW  */ wined3d_cs_exec_set_unordered_access_view,
+    /* WINED3D_CS_OP_SET_COMPUTE_UAV            */ wined3d_cs_exec_set_compute_unordered_access_view,
     /* WINED3D_CS_OP_SET_SAMPLER                */ wined3d_cs_exec_set_sampler,
     /* WINED3D_CS_OP_SET_SHADER                 */ wined3d_cs_exec_set_shader,
     /* WINED3D_CS_OP_SET_RASTERIZER_STATE       */ wined3d_cs_exec_set_rasterizer_state,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 03d4069..f71baf6 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -2826,6 +2826,32 @@ void CDECL wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int
     wined3d_device_set_constant_buffer(device, WINED3D_SHADER_TYPE_COMPUTE, idx, buffer);
 }
 
+void CDECL wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
+        struct wined3d_unordered_access_view *uav)
+{
+    struct wined3d_unordered_access_view *prev;
+
+    TRACE("device %p, idx %u, uav %p.\n", device, idx, uav);
+
+    if (idx >= MAX_UNORDERED_ACCESS_VIEWS)
+    {
+        WARN("Invalid UAV index %u.\n", idx);
+        return;
+    }
+
+    prev = device->update_state->compute_unordered_access_view[idx];
+    if (uav == prev)
+        return;
+
+    if (uav)
+        wined3d_unordered_access_view_incref(uav);
+    device->update_state->compute_unordered_access_view[idx] = uav;
+    if (!device->recording)
+        wined3d_cs_emit_set_compute_unordered_access_view(device->cs, idx, uav);
+    if (prev)
+        wined3d_unordered_access_view_decref(prev);
+}
+
 void CDECL wined3d_device_set_unordered_access_view(struct wined3d_device *device,
         unsigned int idx, struct wined3d_unordered_access_view *uav)
 {
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 2663403..f8446ee 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -623,6 +623,7 @@ static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struc
         GLuint program_id, const struct wined3d_shader_reg_maps *reg_maps)
 {
     struct wined3d_string_buffer *name = string_buffer_get(&priv->string_buffers);
+    const char *prefix = shader_glsl_get_prefix(reg_maps->shader_version.type);
     GLint location;
     unsigned int i;
 
@@ -631,7 +632,7 @@ static void shader_glsl_load_images(const struct wined3d_gl_info *gl_info, struc
         if (!reg_maps->uav_resource_info[i].type)
             continue;
 
-        string_buffer_sprintf(name, "ps_image%u", i);
+        string_buffer_sprintf(name, "%s_image%u", prefix, i);
         location = GL_EXTCALL(glGetUniformLocation(program_id, name->buffer));
         if (location == -1)
             continue;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 540a1b3..d448988 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4990,6 +4990,13 @@ static void state_uav_binding(struct wined3d_context *context,
     context->update_unordered_access_view_bindings = 1;
 }
 
+static void state_cs_uav_binding(struct wined3d_context *context,
+        const struct wined3d_state *state, DWORD state_id)
+{
+    TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
+    context->update_compute_unordered_access_view_bindings = 1;
+}
+
 static void state_uav_warn(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
 {
     WARN("ARB_image_load_store is not supported by OpenGL implementation.\n");
@@ -5008,6 +5015,8 @@ const struct StateEntryTemplate misc_state_template[] =
     { STATE_SHADER_RESOURCE_BINDING,                      { STATE_SHADER_RESOURCE_BINDING,                      state_shader_resource_binding}, WINED3D_GL_EXT_NONE    },
     { STATE_UNORDERED_ACCESS_VIEW_BINDING,                { STATE_UNORDERED_ACCESS_VIEW_BINDING,                state_uav_binding   }, ARB_SHADER_IMAGE_LOAD_STORE     },
     { STATE_UNORDERED_ACCESS_VIEW_BINDING,                { STATE_UNORDERED_ACCESS_VIEW_BINDING,                state_uav_warn      }, WINED3D_GL_EXT_NONE             },
+    { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING,        { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING,        state_cs_uav_binding}, ARB_SHADER_IMAGE_LOAD_STORE     },
+    { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING,        { STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING,        state_uav_warn      }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_SRCBLEND),                  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_DESTBLEND),                 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          state_blend         }, WINED3D_GL_EXT_NONE             },
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index fd01752..a15a16d 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -515,6 +515,11 @@ void state_unbind_resources(struct wined3d_state *state)
             state->unordered_access_view[i] = NULL;
             wined3d_unordered_access_view_decref(uav);
         }
+        if ((uav = state->compute_unordered_access_view[i]))
+        {
+            state->compute_unordered_access_view[i] = NULL;
+            wined3d_unordered_access_view_decref(uav);
+        }
     }
 }
 
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 64a6b9d..78babba 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -4387,6 +4387,8 @@ const char *debug_d3dstate(DWORD state)
         return wine_dbg_sprintf("STATE_CONSTANT_BUFFER(%s)", debug_shader_type(state - STATE_CONSTANT_BUFFER(0)));
     if (STATE_IS_SHADER_RESOURCE_BINDING(state))
         return "STATE_SHADER_RESOURCE_BINDING";
+    if (STATE_IS_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING(state))
+        return "STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING";
     if (STATE_IS_UNORDERED_ACCESS_VIEW_BINDING(state))
         return "STATE_UNORDERED_ACCESS_VIEW_BINDING";
     if (STATE_IS_TRANSFORM(state))
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 57e1efb..af3878e 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -112,6 +112,7 @@
 @ cdecl wined3d_device_set_clip_status(ptr ptr)
 @ cdecl wined3d_device_set_compute_shader(ptr ptr)
 @ cdecl wined3d_device_set_cs_cb(ptr long ptr)
+@ cdecl wined3d_device_set_cs_uav(ptr long ptr)
 @ cdecl wined3d_device_set_cursor_position(ptr long long long)
 @ cdecl wined3d_device_set_cursor_properties(ptr long long ptr long)
 @ cdecl wined3d_device_set_depth_stencil_view(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3a0de2a..acd822e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1440,8 +1440,11 @@ DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
 #define STATE_COMPUTE_CONSTANT_BUFFER (STATE_COMPUTE_SHADER + 1)
 #define STATE_IS_COMPUTE_CONSTANT_BUFFER(a) ((a) == STATE_COMPUTE_CONSTANT_BUFFER)
 
-#define STATE_COMPUTE_HIGHEST (STATE_COMPUTE_CONSTANT_BUFFER)
-#define STATE_HIGHEST (STATE_COMPUTE_CONSTANT_BUFFER)
+#define STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING (STATE_COMPUTE_CONSTANT_BUFFER + 1)
+#define STATE_IS_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING(a) ((a) == STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING)
+
+#define STATE_COMPUTE_HIGHEST (STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING)
+#define STATE_HIGHEST (STATE_COMPUTE_UNORDERED_ACCESS_VIEW_BINDING)
 
 #define STATE_IS_COMPUTE(a) ((a) >= STATE_COMPUTE_OFFSET && (a) <= STATE_COMPUTE_HIGHEST)
 #define STATE_COMPUTE_COUNT (STATE_COMPUTE_HIGHEST - STATE_COMPUTE_OFFSET + 1)
@@ -1591,9 +1594,10 @@ struct wined3d_context
     DWORD hdc_has_format : 1;           /* only meaningful if hdc_is_private */
     DWORD update_shader_resource_bindings : 1;
     DWORD update_unordered_access_view_bindings : 1;
+    DWORD update_compute_unordered_access_view_bindings : 1;
     DWORD uses_uavs : 1;
     DWORD destroy_delayed : 1;
-    DWORD padding : 11;
+    DWORD padding : 10;
     DWORD last_swizzle_map; /* MAX_ATTRIBS, 16 */
     DWORD shader_update_mask;
     DWORD constant_update_mask;
@@ -2512,6 +2516,7 @@ struct wined3d_state
     struct wined3d_sampler *sampler[WINED3D_SHADER_TYPE_COUNT][MAX_SAMPLER_OBJECTS];
     struct wined3d_shader_resource_view *shader_resource_view[WINED3D_SHADER_TYPE_COUNT][MAX_SHADER_RESOURCE_VIEWS];
     struct wined3d_unordered_access_view *unordered_access_view[MAX_UNORDERED_ACCESS_VIEWS];
+    struct wined3d_unordered_access_view *compute_unordered_access_view[MAX_UNORDERED_ACCESS_VIEWS];
 
     BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
     struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
@@ -3179,6 +3184,8 @@ void wined3d_cs_emit_set_clip_plane(struct wined3d_cs *cs, UINT plane_idx,
         const struct wined3d_vec4 *plane) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_color_key(struct wined3d_cs *cs, struct wined3d_texture *texture,
         WORD flags, const struct wined3d_color_key *color_key) DECLSPEC_HIDDEN;
+void wined3d_cs_emit_set_compute_unordered_access_view(struct wined3d_cs *cs, unsigned int view_idx,
+        struct wined3d_unordered_access_view *view) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_constant_buffer(struct wined3d_cs *cs, enum wined3d_shader_type type,
         UINT cb_idx, struct wined3d_buffer *buffer) DECLSPEC_HIDDEN;
 void wined3d_cs_emit_set_depth_stencil_view(struct wined3d_cs *cs,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 7788e90..9eab1c9 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2243,6 +2243,8 @@ HRESULT __cdecl wined3d_device_set_clip_status(struct wined3d_device *device,
         const struct wined3d_clip_status *clip_status);
 void __cdecl wined3d_device_set_compute_shader(struct wined3d_device *device, struct wined3d_shader *shader);
 void __cdecl wined3d_device_set_cs_cb(struct wined3d_device *device, unsigned int idx, struct wined3d_buffer *buffer);
+void __cdecl wined3d_device_set_cs_uav(struct wined3d_device *device, unsigned int idx,
+        struct wined3d_unordered_access_view *uav);
 void __cdecl wined3d_device_set_cursor_position(struct wined3d_device *device,
         int x_screen_space, int y_screen_space, DWORD flags);
 HRESULT __cdecl wined3d_device_set_cursor_properties(struct wined3d_device *device,
-- 
2.10.2




More information about the wine-patches mailing list