diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 5add94dfeeb..0f060b47274 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -35,6 +35,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_INDEX_BUFFER, }; struct wined3d_cs_present @@ -117,6 +118,13 @@ struct wined3d_cs_set_stream_source_freq UINT flags; }; +struct wined3d_cs_set_index_buffer +{ + enum wined3d_cs_op opcode; + struct wined3d_buffer *buffer; + enum wined3d_format_id format_id; +}; + static void wined3d_cs_exec_present(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_present *op = data; @@ -389,6 +397,36 @@ 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_index_buffer(struct wined3d_cs *cs, const void *data) +{ + const struct wined3d_cs_set_index_buffer *op = data; + struct wined3d_buffer *prev; + + prev = cs->state.index_buffer; + cs->state.index_buffer = op->buffer; + cs->state.index_format = op->format_id; + + if (op->buffer) + InterlockedIncrement(&op->buffer->resource.bind_count); + if (prev) + InterlockedDecrement(&prev->resource.bind_count); + + device_invalidate_state(cs->device, STATE_INDEXBUFFER); +} + +void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, + enum wined3d_format_id format_id) +{ + struct wined3d_cs_set_index_buffer *op; + + op = cs->ops->require_space(cs, sizeof(*op)); + op->opcode = WINED3D_CS_OP_SET_INDEX_BUFFER; + op->buffer = buffer; + op->format_id = format_id; + + cs->ops->submit(cs); +} + static void (* const wined3d_cs_op_handlers[])(struct wined3d_cs *cs, const void *data) = { /* WINED3D_CS_OP_PRESENT */ wined3d_cs_exec_present, @@ -401,6 +439,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_INDEX_BUFFER */ wined3d_cs_exec_set_index_buffer, }; static void *wined3d_cs_st_require_space(struct wined3d_cs *cs, size_t size) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 603e5f58a4f..acca498c0aa 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1828,42 +1828,30 @@ void CDECL wined3d_device_get_material(const struct wined3d_device *device, stru void CDECL wined3d_device_set_index_buffer(struct wined3d_device *device, struct wined3d_buffer *buffer, enum wined3d_format_id format_id) { + enum wined3d_format_id prev_format; struct wined3d_buffer *prev_buffer; TRACE("device %p, buffer %p, format %s.\n", device, buffer, debug_d3dformat(format_id)); prev_buffer = device->update_state->index_buffer; + prev_format = device->update_state->index_format; device->update_state->index_buffer = buffer; device->update_state->index_format = format_id; - /* Handle recording of state blocks. */ if (device->recording) - { - TRACE("Recording... not performing anything.\n"); device->recording->changed.indices = TRUE; - if (buffer) - wined3d_buffer_incref(buffer); - if (prev_buffer) - wined3d_buffer_decref(prev_buffer); - return; - } - if (prev_buffer != buffer) - { - device_invalidate_state(device, STATE_INDEXBUFFER); - 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 (prev_buffer == buffer && prev_format == format_id) + return; + + if (buffer) + wined3d_buffer_incref(buffer); + if (!device->recording) + wined3d_cs_emit_set_index_buffer(device->cs, buffer, format_id); + if (prev_buffer) + wined3d_buffer_decref(prev_buffer); } struct wined3d_buffer * CDECL wined3d_device_get_index_buffer(const struct wined3d_device *device, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c7b014e9da8..45ead8875ca 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2487,6 +2487,8 @@ void wined3d_cs_emit_present(struct wined3d_cs *cs, struct wined3d_swapchain *sw const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override, const RGNDATA *dirty_region, DWORD flags) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_depth_stencil(struct wined3d_cs *cs, struct wined3d_surface *depth_stencil) DECLSPEC_HIDDEN; +void wined3d_cs_emit_set_index_buffer(struct wined3d_cs *cs, struct wined3d_buffer *buffer, + enum wined3d_format_id format_id) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_render_target(struct wined3d_cs *cs, UINT render_target_idx, struct wined3d_surface *render_target) DECLSPEC_HIDDEN; void wined3d_cs_emit_set_scissor_rect(struct wined3d_cs *cs, const RECT *rect) DECLSPEC_HIDDEN;