From: Józef Kucia Subject: [PATCH 4/6] wined3d: Implement compute pipeline UAV binding. Message-Id: <20170208105418.32621-4-jkucia@codeweavers.com> Date: Wed, 8 Feb 2017 11:54:16 +0100 In-Reply-To: <20170208105418.32621-1-jkucia@codeweavers.com> References: <20170208105418.32621-1-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- 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/utils.c | 2 ++ dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 13 ++++++++++--- include/wine/wined3d.h | 2 ++ 9 files changed, 97 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c index e8cc3fc..5c5b463 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -3424,19 +3424,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) @@ -3444,7 +3443,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)); @@ -3562,8 +3561,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) @@ -3601,6 +3602,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 422f3f1..f2e10a8 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, @@ -1053,6 +1054,35 @@ static void wined3d_cs_exec_set_unordered_access_view(struct wined3d_cs *cs, con device_invalidate_state(cs->device, STATE_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_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_shader_resource_view(struct wined3d_cs *cs, enum wined3d_shader_type type, UINT view_idx, struct wined3d_shader_resource_view *view) { @@ -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/utils.c b/dlls/wined3d/utils.c index 30a80e5..0b470f3 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