Zebediah Figura : wined3d: Introduce a separate structure for stateblock state and store vertex shader state therein.
Module: wine Branch: master Commit: f2e7906d9cd17b4cdab28a71cc9ca8ecaaf0c26c URL: https://source.winehq.org/git/wine.git/?a=commit;h=f2e7906d9cd17b4cdab28a71c... Author: Zebediah Figura <z.figura12(a)gmail.com> Date: Sun Jan 27 22:44:52 2019 -0600 wined3d: Introduce a separate structure for stateblock state and store vertex shader state therein. Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/wined3d/device.c | 25 +++++++++++++++++++++---- dlls/wined3d/stateblock.c | 40 +++++++++++++++++++++++++++++----------- dlls/wined3d/wined3d_private.h | 10 ++++++++++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index a7e274d..b7071db 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -486,6 +486,8 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device) { UINT i; + wined3d_stateblock_state_cleanup(&device->stateblock_state); + wined3d_cs_destroy(device->cs); if (device->recording && wined3d_stateblock_decref(device->recording)) @@ -2208,21 +2210,29 @@ struct wined3d_vertex_declaration * CDECL wined3d_device_get_vertex_declaration( void CDECL wined3d_device_set_vertex_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX]; + struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_VERTEX]; TRACE("device %p, shader %p.\n", device, shader); + if (shader) + wined3d_shader_incref(shader); + if (device->update_stateblock_state->vs) + wined3d_shader_decref(device->update_stateblock_state->vs); + device->update_stateblock_state->vs = shader; + if (device->recording) + { device->recording->changed.vertexShader = TRUE; + return; + } if (shader == prev) return; if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_VERTEX] = shader; - if (!device->recording) - wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); + device->state.shader[WINED3D_SHADER_TYPE_VERTEX] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_VERTEX, shader); if (prev) wined3d_shader_decref(prev); } @@ -3552,6 +3562,7 @@ HRESULT CDECL wined3d_device_begin_stateblock(struct wined3d_device *device) device->recording = stateblock; device->update_state = &stateblock->state; + device->update_stateblock_state = &stateblock->stateblock_state; TRACE("Recording stateblock %p.\n", stateblock); @@ -3577,6 +3588,7 @@ HRESULT CDECL wined3d_device_end_stateblock(struct wined3d_device *device, *stateblock = object; device->recording = NULL; device->update_state = &device->state; + device->update_stateblock_state = &device->stateblock_state; TRACE("Returning stateblock %p.\n", *stateblock); @@ -4998,6 +5010,7 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, } wined3d_cs_emit_reset_state(device->cs); state_cleanup(&device->state); + wined3d_stateblock_state_cleanup(&device->stateblock_state); if (device->d3d_initialized) wined3d_device_delete_opengl_contexts(device); @@ -5005,6 +5018,8 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device, memset(&device->state, 0, sizeof(device->state)); state_init(&device->state, &device->fb, &device->adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); device->update_state = &device->state; + memset(&device->stateblock_state, 0, sizeof(device->stateblock_state)); + device->update_stateblock_state = &device->stateblock_state; device_init_swapchain_state(device, swapchain); if (wined3d_settings.logo) @@ -5279,6 +5294,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, state_init(&device->state, &device->fb, &adapter->d3d_info, WINED3D_STATE_INIT_DEFAULT); device->update_state = &device->state; + device->update_stateblock_state = &device->stateblock_state; device->max_frame_latency = 3; @@ -5286,6 +5302,7 @@ HRESULT device_init(struct wined3d_device *device, struct wined3d *wined3d, { WARN("Failed to create command stream.\n"); state_cleanup(&device->state); + wined3d_stateblock_state_cleanup(&device->stateblock_state); hr = E_FAIL; goto err; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 9539ae0..4ead27b 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -521,6 +521,17 @@ void state_unbind_resources(struct wined3d_state *state) } } +void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) +{ + struct wined3d_shader *shader; + + if ((shader = state->vs)) + { + state->vs = NULL; + wined3d_shader_decref(shader); + } +} + void state_cleanup(struct wined3d_state *state) { unsigned int counter; @@ -554,6 +565,7 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) if (!refcount) { state_cleanup(&stateblock->state); + wined3d_stateblock_state_cleanup(&stateblock->stateblock_state); heap_free(stateblock); } @@ -669,6 +681,7 @@ static void wined3d_state_record_lights(struct wined3d_state *dst_state, const s void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { + const struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state; const struct wined3d_state *src_state = &stateblock->device->state; unsigned int i; DWORD map; @@ -677,18 +690,15 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) TRACE("Capturing state %p.\n", src_state); - if (stateblock->changed.vertexShader && stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] - != src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) + if (stateblock->changed.vertexShader && stateblock->stateblock_state.vs != state->vs) { - TRACE("Updating vertex shader from %p to %p\n", - stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX], - src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); + TRACE("Updating vertex shader from %p to %p.\n", stateblock->stateblock_state.vs, state->vs); - if (src_state->shader[WINED3D_SHADER_TYPE_VERTEX]) - wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_VERTEX]); - if (stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]) - wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); - stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX] = src_state->shader[WINED3D_SHADER_TYPE_VERTEX]; + if (state->vs) + wined3d_shader_incref(state->vs); + if (stateblock->stateblock_state.vs) + wined3d_shader_decref(stateblock->stateblock_state.vs); + stateblock->stateblock_state.vs = state->vs; } /* Vertex shader float constants. */ @@ -978,6 +988,7 @@ static void apply_lights(struct wined3d_device *device, const struct wined3d_sta void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) { + struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state; struct wined3d_device *device = stateblock->device; unsigned int i; DWORD map; @@ -985,7 +996,14 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) TRACE("Applying stateblock %p to device %p.\n", stateblock, device); if (stateblock->changed.vertexShader) - wined3d_device_set_vertex_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_VERTEX]); + { + if (stateblock->stateblock_state.vs) + wined3d_shader_incref(stateblock->stateblock_state.vs); + if (state->vs) + wined3d_shader_decref(state->vs); + state->vs = stateblock->stateblock_state.vs; + wined3d_device_set_vertex_shader(device, stateblock->stateblock_state.vs); + } /* Vertex Shader Constants. */ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7b265f3..e45ee7b 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2968,6 +2968,11 @@ struct wined3d_dummy_textures * wined3d_device_create() ignores it. */ #define WINED3DCREATE_MULTITHREADED 0x00000004 +struct wined3d_stateblock_state +{ + struct wined3d_shader *vs; +}; + struct wined3d_device { LONG ref; @@ -3006,6 +3011,8 @@ struct wined3d_device struct wined3d_state state; struct wined3d_state *update_state; struct wined3d_stateblock *recording; + struct wined3d_stateblock_state stateblock_state; + struct wined3d_stateblock_state *update_stateblock_state; /* Internal use fields */ struct wined3d_device_creation_parameters create_parms; @@ -3556,6 +3563,7 @@ struct wined3d_stateblock /* Array indicating whether things have been set or changed */ struct wined3d_saved_states changed; struct wined3d_state state; + struct wined3d_stateblock_state stateblock_state; /* Contained state management */ DWORD contained_render_states[WINEHIGHEST_RENDER_STATE + 1]; @@ -3582,6 +3590,8 @@ struct wined3d_stateblock void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) DECLSPEC_HIDDEN; +void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) DECLSPEC_HIDDEN; + void state_cleanup(struct wined3d_state *state) DECLSPEC_HIDDEN; void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN;
participants (1)
-
Alexandre Julliard