wined3d: Introduce a separate structure for stateblock state and store vertex shader state therein.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-01-27 22:44:52 -06:00 committed by Alexandre Julliard
parent c04c0f2658
commit f2e7906d9c
3 changed files with 60 additions and 15 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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;