From: Guillaume Charifi Subject: [PATCH 08/10] wined3d: Dispatch compute through the command stream. Message-Id: <20170129134354.28597-8-guillaume.charifi@sfr.fr> Date: Sun, 29 Jan 2017 14:43:39 +0100 In-Reply-To: <20170129134354.28597-1-guillaume.charifi@sfr.fr> References: <20170129134354.28597-1-guillaume.charifi@sfr.fr> Signed-off-by: Guillaume Charifi --- dlls/wined3d/cs.c | 104 +++++++++++++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 2 files changed, 105 insertions(+) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index c030d35..60c4731 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_COMPUTE, 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_compute +{ + enum wined3d_cs_op opcode; + unsigned int count_x; + unsigned int count_y; + unsigned int count_z; +}; + struct wined3d_cs_draw { enum wined3d_cs_op opcode; @@ -416,6 +425,100 @@ void wined3d_cs_emit_clear(struct wined3d_cs *cs, DWORD rect_count, const RECT * cs->ops->submit(cs); } +static void wined3d_cs_exec_dispatch_compute(struct wined3d_cs *cs, const void *data) +{ + struct wined3d_state *state = &cs->device->state; + struct wined3d_shader_sampler_map_entry *entry; + struct wined3d_shader_resource_view *view; + const struct wined3d_cs_dispatch_compute *op = data; + struct wined3d_shader *shader; + unsigned int i, j; + + dispatch_compute(cs->device, state, op->count_x, op->count_y, op->count_z); + + for (i = 0; i < ARRAY_SIZE(state->streams); ++i) + { + if (state->streams[i].buffer) + wined3d_resource_release(&state->streams[i].buffer->resource); + } + for (i = 0; i < ARRAY_SIZE(state->textures); ++i) + { + if (state->textures[i]) + wined3d_resource_release(&state->textures[i]->resource); + } + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + if (!(shader = state->shader[i])) + continue; + + for (j = 0; j < WINED3D_MAX_CBS; ++j) + { + if (state->cb[i][j]) + wined3d_resource_release(&state->cb[i][j]->resource); + } + + for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) + { + entry = &shader->reg_maps.sampler_map.entries[j]; + + if (!(view = state->shader_resource_view[i][entry->resource_idx])) + continue; + + wined3d_resource_release(view->resource); + } + } +} + +void wined3d_cs_emit_dispatch_compute(struct wined3d_cs *cs, UINT thread_group_count_x, UINT thread_group_count_y, UINT thread_group_count_z) +{ + const struct wined3d_state *state = &cs->device->state; + struct wined3d_shader_sampler_map_entry *entry; + struct wined3d_shader_resource_view *view; + struct wined3d_shader *shader; + struct wined3d_cs_dispatch_compute *op; + unsigned int i, j; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_DISPATCH_COMPUTE; + op->count_x = thread_group_count_x; + op->count_y = thread_group_count_y; + op->count_z = thread_group_count_z; + + for (i = 0; i < ARRAY_SIZE(state->streams); ++i) + { + if (state->streams[i].buffer) + wined3d_resource_acquire(&state->streams[i].buffer->resource); + } + for (i = 0; i < ARRAY_SIZE(state->textures); ++i) + { + if (state->textures[i]) + wined3d_resource_acquire(&state->textures[i]->resource); + } + for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i) + { + if (!(shader = state->shader[i])) + continue; + + for (j = 0; j < WINED3D_MAX_CBS; ++j) + { + if (state->cb[i][j]) + wined3d_resource_acquire(&state->cb[i][j]->resource); + } + + for (j = 0; j < shader->reg_maps.sampler_map.count; ++j) + { + entry = &shader->reg_maps.sampler_map.entries[j]; + + if (!(view = state->shader_resource_view[i][entry->resource_idx])) + continue; + + wined3d_resource_acquire(view->resource); + } + } + + cs->ops->submit(cs); +} + static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data) { struct wined3d_state *state = &cs->device->state; @@ -1412,6 +1515,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_COMPUTE */ wined3d_cs_exec_dispatch_compute, /* 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/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d3463e2..0ffbad4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3151,6 +3151,7 @@ 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_compute(struct wined3d_cs *cs, UINT thread_group_count_x, UINT thread_group_count_y, UINT thread_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; -- Guillaume Charifi