From 1419d7389c20be9a23d9351afac27ebe4c7e5211 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 10 Oct 2013 23:49:46 +0200 Subject: [PATCH] wined3d: Send stream output binding updates through the command stream. --- dlls/wined3d/cs.c | 41 ++++++++++++++++++++++++++++++++++ dlls/wined3d/device.c | 36 +++++++++-------------------- dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index bf682e5d7b..3d9a07c009 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -36,6 +36,7 @@ enum wined3d_cs_op WINED3D_CS_OP_SET_VERTEX_DECLARATION, WINED3D_CS_OP_SET_STREAM_SOURCE, WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ, + WINED3D_CS_OP_SET_STREAM_OUTPUT, WINED3D_CS_OP_SET_INDEX_BUFFER, WINED3D_CS_OP_SET_CONSTANT_BUFFER, WINED3D_CS_OP_SET_TEXTURE, @@ -129,6 +130,14 @@ struct wined3d_cs_set_stream_source_freq UINT flags; }; +struct wined3d_cs_set_stream_output +{ + enum wined3d_cs_op opcode; + UINT stream_idx; + struct wined3d_buffer *buffer; + UINT offset; +}; + struct wined3d_cs_set_index_buffer { enum wined3d_cs_op opcode; @@ -481,6 +490,37 @@ void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_i cs->ops->submit(cs); } +static void wined3d_cs_exec_set_stream_output(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_stream_output *op = data; + struct wined3d_stream_output *stream; + struct wined3d_buffer *prev; + + stream = &cs->state.stream_output[op->stream_idx]; + prev = stream->buffer; + stream->buffer = op->buffer; + stream->offset = op->offset; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); +} + +void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset) +{ + struct wined3d_cs_set_stream_output *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_STREAM_OUTPUT; + op->stream_idx = stream_idx; + op->buffer = buffer; + op->offset = offset; + + cs->ops->submit(cs); +} + static void wined3d_cs_exec_set_index_buffer(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_set_index_buffer *op = data; @@ -786,6 +826,7 @@ static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void /* WINED3D_CS_OP_SET_VERTEX_DECLARATION */ wined3d_cs_exec_set_vertex_declaration, /* WINED3D_CS_OP_SET_STREAM_SOURCE */ wined3d_cs_exec_set_stream_source, /* WINED3D_CS_OP_SET_STREAM_SOURCE_FREQ */ wined3d_cs_exec_set_stream_source_freq, + /* WINED3D_CS_OP_SET_STREAM_OUTPUT */ wined3d_cs_exec_set_stream_output, /* WINED3D_CS_OP_SET_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, /* WINED3D_CS_OP_SET_CONSTANT_BUFFER */ wined3d_cs_exec_set_constant_buffer, /* WINED3D_CS_OP_SET_TEXTURE */ wined3d_cs_exec_set_texture, diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index cafb539302..8a1af6b43b 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1145,6 +1145,7 @@ UINT CDECL wined3d_device_get_available_texture_mem(const struct wined3d_device void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT idx, struct wined3d_buffer *buffer, UINT offset) { + struct wined3d_stream_output *stream; struct wined3d_buffer *prev_buffer; TRACE("device %p, idx %u, buffer %p, offset %u.\n", device, idx, buffer, offset); @@ -1155,32 +1156,17 @@ void CDECL wined3d_device_set_stream_output(struct wined3d_device *device, UINT return; } - prev_buffer = device->update_state->stream_output[idx].buffer; - device->update_state->stream_output[idx].buffer = buffer; - device->update_state->stream_output[idx].offset = offset; + stream = &device->update_state->stream_output[idx]; + prev_buffer = stream->buffer; - if (device->recording) - { - if (buffer) - wined3d_buffer_incref(buffer); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - return; - } - - if (prev_buffer != buffer) - { - if (buffer) - { - InterlockedIncrement(&buffer->resource.bind_count); - wined3d_buffer_incref(buffer); - } - if (prev_buffer) - { - InterlockedDecrement(&prev_buffer->resource.bind_count); - wined3d_buffer_decref(prev_buffer); - } - } + if (buffer) + wined3d_buffer_incref(buffer); + stream->buffer = buffer; + stream->offset = offset; + if (!device->recording) + wined3d_cs_emit_set_stream_output(device->cs, idx, buffer, offset); + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } struct wined3d_buffer * CDECL wined3d_device_get_stream_output(struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7d160eb19b..03c7353541 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2492,6 +2492,8 @@ void wined3d_cs_emit_set_sampler_state(struct wined3d_cs *cs, UINT sampler_idx, void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_shader(struct wined3d_cs *cs, enum wined3d_shader_type type, struct wined3d_shader *shader) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_stream_output(struct wined3d_cs *cs, UINT stream_idx, + struct wined3d_buffer *buffer, UINT offset) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_stream_source(struct wined3d_cs *cs, UINT stream_idx, struct wined3d_buffer *buffer, UINT offset, UINT stride) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_stream_source_freq(struct wined3d_cs *cs, UINT stream_idx,