Module: wine Branch: master Commit: 2f66f1288fb598710a7f68a4d918ee2565f6ea56 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2f66f1288fb598710a7f68a4d9...
Author: Józef Kucia jkucia@codeweavers.com Date: Mon Aug 14 23:47:41 2017 +0200
wined3d: Implement indirect compute dispatch.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/cs.c | 46 ++++++++++++++++++++++++++++++++---------- dlls/wined3d/device.c | 8 ++++++++ dlls/wined3d/drawprim.c | 20 +++++++++++++++--- dlls/wined3d/wined3d.spec | 1 + dlls/wined3d/wined3d_private.h | 27 ++++++++++++++++++++++++- include/wine/wined3d.h | 2 ++ 6 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index a76598f..8961dfe 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -112,9 +112,7 @@ struct wined3d_cs_clear struct wined3d_cs_dispatch { enum wined3d_cs_op opcode; - unsigned int group_count_x; - unsigned int group_count_y; - unsigned int group_count_z; + struct wined3d_dispatch_parameters parameters; };
struct wined3d_cs_draw @@ -705,14 +703,23 @@ static void wined3d_cs_exec_dispatch(struct wined3d_cs *cs, const void *data) const struct wined3d_cs_dispatch *op = data; struct wined3d_state *state = &cs->state;
- dispatch_compute(cs->device, state, - op->group_count_x, op->group_count_y, op->group_count_z); + dispatch_compute(cs->device, state, &op->parameters); + + if (op->parameters.indirect) + wined3d_resource_release(&op->parameters.u.indirect.buffer->resource);
release_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE); release_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE], state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); }
+static void acquire_compute_pipeline_resources(const struct wined3d_state *state) +{ + acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE); + acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE], + state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); +} + void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) { @@ -721,13 +728,30 @@ void wined3d_cs_emit_dispatch(struct wined3d_cs *cs,
op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); op->opcode = WINED3D_CS_OP_DISPATCH; - op->group_count_x = group_count_x; - op->group_count_y = group_count_y; - op->group_count_z = group_count_z; + op->parameters.indirect = FALSE; + op->parameters.u.direct.group_count_x = group_count_x; + op->parameters.u.direct.group_count_y = group_count_y; + op->parameters.u.direct.group_count_z = group_count_z;
- acquire_shader_resources(state, 1u << WINED3D_SHADER_TYPE_COMPUTE); - acquire_unordered_access_resources(state->shader[WINED3D_SHADER_TYPE_COMPUTE], - state->unordered_access_view[WINED3D_PIPELINE_COMPUTE]); + acquire_compute_pipeline_resources(state); + + cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); +} + +void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, + struct wined3d_buffer *buffer, unsigned int offset) +{ + const struct wined3d_state *state = &cs->device->state; + struct wined3d_cs_dispatch *op; + + op = cs->ops->require_space(cs, sizeof(*op), WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_DISPATCH; + op->parameters.indirect = TRUE; + op->parameters.u.indirect.buffer = buffer; + op->parameters.u.indirect.offset = offset; + + acquire_compute_pipeline_resources(state); + wined3d_resource_acquire(&buffer->resource);
cs->ops->submit(cs, WINED3D_CS_QUEUE_DEFAULT); } diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 30e7fbe..31955ba 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3652,6 +3652,14 @@ void CDECL wined3d_device_dispatch_compute(struct wined3d_device *device, wined3d_cs_emit_dispatch(device->cs, group_count_x, group_count_y, group_count_z); }
+void CDECL wined3d_device_dispatch_compute_indirect(struct wined3d_device *device, + struct wined3d_buffer *buffer, unsigned int offset) +{ + TRACE("device %p, buffer %p, offset %u.\n", device, buffer, offset); + + wined3d_cs_emit_dispatch_indirect(device->cs, buffer, offset); +} + void CDECL wined3d_device_set_primitive_type(struct wined3d_device *device, enum wined3d_primitive_type primitive_type, unsigned int patch_vertex_count) { diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index e9bce44..235f87b 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -669,7 +669,7 @@ void draw_primitive(struct wined3d_device *device, const struct wined3d_state *s }
void dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, - unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) + const struct wined3d_dispatch_parameters *parameters) { const struct wined3d_gl_info *gl_info; struct wined3d_context *context; @@ -699,8 +699,22 @@ void dispatch_compute(struct wined3d_device *device, const struct wined3d_state return; }
- GL_EXTCALL(glDispatchCompute(group_count_x, group_count_y, group_count_z)); - checkGLcall("glDispatchCompute"); + if (parameters->indirect) + { + const struct wined3d_indirect_dispatch_parameters *indirect = ¶meters->u.indirect; + struct wined3d_buffer *buffer = indirect->buffer; + + wined3d_buffer_load(buffer, context, state); + GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, buffer->buffer_object)); + GL_EXTCALL(glDispatchComputeIndirect((GLintptr)indirect->offset)); + GL_EXTCALL(glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0)); + } + else + { + const struct wined3d_direct_dispatch_parameters *direct = ¶meters->u.direct; + GL_EXTCALL(glDispatchCompute(direct->group_count_x, direct->group_count_y, direct->group_count_z)); + } + checkGLcall("dispatch compute");
GL_EXTCALL(glMemoryBarrier(GL_ALL_BARRIER_BITS)); checkGLcall("glMemoryBarrier"); diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index c0724ab..fb8188e 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -42,6 +42,7 @@ @ cdecl wined3d_device_create(ptr long long ptr long long ptr ptr) @ cdecl wined3d_device_decref(ptr) @ cdecl wined3d_device_dispatch_compute(ptr long long long) +@ cdecl wined3d_device_dispatch_compute_indirect(ptr ptr long) @ cdecl wined3d_device_draw_indexed_primitive(ptr long long) @ cdecl wined3d_device_draw_indexed_primitive_instanced(ptr long long long long) @ cdecl wined3d_device_draw_primitive(ptr long long) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index f8aeb62..74043d0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1479,11 +1479,34 @@ void wined3d_stream_info_from_declaration(struct wined3d_stream_info *stream_inf const struct wined3d_state *state, const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;
+struct wined3d_direct_dispatch_parameters +{ + unsigned int group_count_x; + unsigned int group_count_y; + unsigned int group_count_z; +}; + +struct wined3d_indirect_dispatch_parameters +{ + struct wined3d_buffer *buffer; + unsigned int offset; +}; + +struct wined3d_dispatch_parameters +{ + BOOL indirect; + union + { + struct wined3d_direct_dispatch_parameters direct; + struct wined3d_indirect_dispatch_parameters indirect; + } u; +}; + void draw_primitive(struct wined3d_device *device, const struct wined3d_state *state, 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 dispatch_compute(struct wined3d_device *device, const struct wined3d_state *state, - unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; + const struct wined3d_dispatch_parameters *dispatch_parameters) DECLSPEC_HIDDEN; DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) DECLSPEC_HIDDEN;
#define eps 1e-8f @@ -3430,6 +3453,8 @@ void wined3d_cs_emit_copy_uav_counter(struct wined3d_cs *cs, struct wined3d_buff unsigned int offset, struct wined3d_unordered_access_view *uav) DECLSPEC_HIDDEN; void wined3d_cs_emit_dispatch(struct wined3d_cs *cs, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z) DECLSPEC_HIDDEN; +void wined3d_cs_emit_dispatch_indirect(struct wined3d_cs *cs, + struct wined3d_buffer *buffer, unsigned int offset) DECLSPEC_HIDDEN; void wined3d_cs_emit_draw(struct wined3d_cs *cs, GLenum primitive_type, unsigned int patch_vertex_count, int base_vertex_idx, unsigned int start_idx, unsigned int index_count, unsigned int start_instance, unsigned int instance_count, BOOL indexed) DECLSPEC_HIDDEN; diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index b92ada0..6fa31e7 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -2217,6 +2217,8 @@ HRESULT __cdecl wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, ULONG __cdecl wined3d_device_decref(struct wined3d_device *device); void __cdecl wined3d_device_dispatch_compute(struct wined3d_device *device, unsigned int group_count_x, unsigned int group_count_y, unsigned int group_count_z); +void __cdecl wined3d_device_dispatch_compute_indirect(struct wined3d_device *device, + struct wined3d_buffer *buffer, unsigned int offset); HRESULT __cdecl wined3d_device_draw_indexed_primitive(struct wined3d_device *device, UINT start_idx, UINT index_count); void __cdecl wined3d_device_draw_indexed_primitive_instanced(struct wined3d_device *device, UINT start_idx, UINT index_count, UINT start_instance, UINT instance_count);