Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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 a7e274dd5a..b7071dbcc1 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 9539ae0696..4ead27b1d6 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 7b265f3662..e45ee7be33 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;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 16 ++++++++++------ dlls/wined3d/stateblock.c | 7 ++++--- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index b7071dbcc1..dcbdc3d731 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2493,18 +2493,22 @@ HRESULT CDECL wined3d_device_set_vs_consts_f(struct wined3d_device *device, || count > d3d_info->limits.vs_uniform_count - start_idx) return WINED3DERR_INVALIDCALL;
- memcpy(&device->update_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); + memcpy(&device->update_stateblock_state->vs_consts_f[start_idx], constants, count * sizeof(*constants)); + if (device->recording) + { + memset(&device->recording->changed.vs_consts_f[start_idx], 1, + count * sizeof(*device->recording->changed.vs_consts_f)); + return WINED3D_OK; + } + + memcpy(&device->state.vs_consts_f[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) TRACE("Set vec4 constant %u to %s.\n", start_idx + i, debug_vec4(&constants[i])); }
- if (device->recording) - memset(&device->recording->changed.vs_consts_f[start_idx], 1, - count * sizeof(*device->recording->changed.vs_consts_f)); - else - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants); + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_F, start_idx, count, constants);
return WINED3D_OK; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 4ead27b1d6..f28c29c33f 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -706,9 +706,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_f[i];
- TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&src_state->vs_consts_f[idx])); + TRACE("Setting vs_consts_f[%u] to %s.\n", idx, debug_vec4(&state->vs_consts_f[idx]));
- stateblock->state.vs_consts_f[idx] = src_state->vs_consts_f[idx]; + stateblock->stateblock_state.vs_consts_f[idx] = state->vs_consts_f[idx]; }
/* Vertex shader integer constants. */ @@ -1008,8 +1008,9 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) /* Vertex Shader Constants. */ for (i = 0; i < stateblock->num_contained_vs_consts_f; ++i) { + state->vs_consts_f[i] = stateblock->stateblock_state.vs_consts_f[i]; wined3d_device_set_vs_consts_f(device, stateblock->contained_vs_consts_f[i], - 1, &stateblock->state.vs_consts_f[stateblock->contained_vs_consts_f[i]]); + 1, &stateblock->stateblock_state.vs_consts_f[stateblock->contained_vs_consts_f[i]]); } for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index e45ee7be33..047439d3b0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2971,6 +2971,7 @@ struct wined3d_dummy_textures struct wined3d_stateblock_state { struct wined3d_shader *vs; + struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; };
struct wined3d_device
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 21 +++++++++++---------- dlls/wined3d/stateblock.c | 7 ++++--- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index dcbdc3d731..14cb6204f2 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2445,22 +2445,23 @@ HRESULT CDECL wined3d_device_set_vs_consts_i(struct wined3d_device *device,
if (count > WINED3D_MAX_CONSTS_I - start_idx) count = WINED3D_MAX_CONSTS_I - start_idx; - memcpy(&device->update_state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); + + memcpy(&device->update_stateblock_state->vs_consts_i[start_idx], constants, count * sizeof(*constants)); + if (device->recording) + { + for (i = start_idx; i < count + start_idx; ++i) + device->recording->changed.vertexShaderConstantsI |= (1u << i); + return WINED3D_OK; + } + + memcpy(&device->state.vs_consts_i[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) TRACE("Set ivec4 constant %u to %s.\n", start_idx + i, debug_ivec4(&constants[i])); }
- if (device->recording) - { - for (i = start_idx; i < count + start_idx; ++i) - device->recording->changed.vertexShaderConstantsI |= (1u << i); - } - else - { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants); - } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_I, start_idx, count, constants);
return WINED3D_OK; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index f28c29c33f..dd1e6383f7 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -716,9 +716,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) { unsigned int idx = stateblock->contained_vs_consts_i[i];
- TRACE("Setting vs_consts[%u] to %s.\n", idx, debug_ivec4(&src_state->vs_consts_i[idx])); + TRACE("Setting vs_consts_i[%u] to %s.\n", idx, debug_ivec4(&state->vs_consts_i[idx]));
- stateblock->state.vs_consts_i[idx] = src_state->vs_consts_i[idx]; + stateblock->stateblock_state.vs_consts_i[idx] = state->vs_consts_i[idx]; }
/* Vertex shader boolean constants. */ @@ -1014,8 +1014,9 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) } for (i = 0; i < stateblock->num_contained_vs_consts_i; ++i) { + state->vs_consts_i[i] = stateblock->stateblock_state.vs_consts_i[i]; wined3d_device_set_vs_consts_i(device, stateblock->contained_vs_consts_i[i], - 1, &stateblock->state.vs_consts_i[stateblock->contained_vs_consts_i[i]]); + 1, &stateblock->stateblock_state.vs_consts_i[stateblock->contained_vs_consts_i[i]]); } for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 047439d3b0..fedf2b8a37 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2972,6 +2972,7 @@ struct wined3d_stateblock_state { struct wined3d_shader *vs; struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; + struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; };
struct wined3d_device
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 21 +++++++++++---------- dlls/wined3d/stateblock.c | 7 ++++--- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 14cb6204f2..331def2723 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2396,22 +2396,23 @@ HRESULT CDECL wined3d_device_set_vs_consts_b(struct wined3d_device *device,
if (count > WINED3D_MAX_CONSTS_B - start_idx) count = WINED3D_MAX_CONSTS_B - start_idx; - memcpy(&device->update_state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); + + memcpy(&device->update_stateblock_state->vs_consts_b[start_idx], constants, count * sizeof(*constants)); + if (device->recording) + { + for (i = start_idx; i < count + start_idx; ++i) + device->recording->changed.vertexShaderConstantsB |= (1u << i); + return WINED3D_OK; + } + + memcpy(&device->state.vs_consts_b[start_idx], constants, count * sizeof(*constants)); if (TRACE_ON(d3d)) { for (i = 0; i < count; ++i) TRACE("Set BOOL constant %u to %#x.\n", start_idx + i, constants[i]); }
- if (device->recording) - { - for (i = start_idx; i < count + start_idx; ++i) - device->recording->changed.vertexShaderConstantsB |= (1u << i); - } - else - { - wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants); - } + wined3d_cs_push_constants(device->cs, WINED3D_PUSH_CONSTANTS_VS_B, start_idx, count, constants);
return WINED3D_OK; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index dd1e6383f7..112d8b7aa4 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -727,9 +727,9 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) unsigned int idx = stateblock->contained_vs_consts_b[i];
TRACE("Setting vs_consts_b[%u] to %s.\n", - idx, src_state->vs_consts_b[idx] ? "TRUE" : "FALSE"); + idx, state->vs_consts_b[idx] ? "TRUE" : "FALSE");
- stateblock->state.vs_consts_b[idx] = src_state->vs_consts_b[idx]; + stateblock->stateblock_state.vs_consts_b[idx] = state->vs_consts_b[idx]; }
/* Pixel shader float constants. */ @@ -1020,8 +1020,9 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) } for (i = 0; i < stateblock->num_contained_vs_consts_b; ++i) { + state->vs_consts_b[i] = stateblock->stateblock_state.vs_consts_b[i]; wined3d_device_set_vs_consts_b(device, stateblock->contained_vs_consts_b[i], - 1, &stateblock->state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); + 1, &stateblock->stateblock_state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); }
apply_lights(device, &stateblock->state); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fedf2b8a37..52106f2e59 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2973,6 +2973,7 @@ struct wined3d_stateblock_state struct wined3d_shader *vs; struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; + BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; };
struct wined3d_device
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 15 +++++++++++---- dlls/wined3d/stateblock.c | 28 ++++++++++++++++++++-------- dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 331def2723..28e113ac81 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -2534,21 +2534,28 @@ HRESULT CDECL wined3d_device_get_vs_consts_f(const struct wined3d_device *device
void CDECL wined3d_device_set_pixel_shader(struct wined3d_device *device, struct wined3d_shader *shader) { - struct wined3d_shader *prev = device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL]; + struct wined3d_shader *prev = device->state.shader[WINED3D_SHADER_TYPE_PIXEL];
TRACE("device %p, shader %p.\n", device, shader);
+ if (shader) + wined3d_shader_incref(shader); + if (device->update_stateblock_state->ps) + wined3d_shader_decref(device->update_stateblock_state->ps); + device->update_stateblock_state->ps = shader; if (device->recording) + { device->recording->changed.pixelShader = TRUE; + return; + }
if (shader == prev) return;
if (shader) wined3d_shader_incref(shader); - device->update_state->shader[WINED3D_SHADER_TYPE_PIXEL] = shader; - if (!device->recording) - wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); + device->state.shader[WINED3D_SHADER_TYPE_PIXEL] = shader; + wined3d_cs_emit_set_shader(device->cs, WINED3D_SHADER_TYPE_PIXEL, shader); if (prev) wined3d_shader_decref(prev); } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 112d8b7aa4..2b916a9dd2 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -530,6 +530,12 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) state->vs = NULL; wined3d_shader_decref(shader); } + + if ((shader = state->ps)) + { + state->ps = NULL; + wined3d_shader_decref(shader); + } }
void state_cleanup(struct wined3d_state *state) @@ -953,14 +959,13 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->state.sampler_states[stage][state] = src_state->sampler_states[stage][state]; }
- if (stateblock->changed.pixelShader && stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] - != src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) + if (stateblock->changed.pixelShader && stateblock->stateblock_state.ps != state->ps) { - if (src_state->shader[WINED3D_SHADER_TYPE_PIXEL]) - wined3d_shader_incref(src_state->shader[WINED3D_SHADER_TYPE_PIXEL]); - if (stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]) - wined3d_shader_decref(stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); - stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL] = src_state->shader[WINED3D_SHADER_TYPE_PIXEL]; + if (state->ps) + wined3d_shader_incref(state->ps); + if (stateblock->stateblock_state.ps) + wined3d_shader_decref(stateblock->stateblock_state.ps); + stateblock->stateblock_state.ps = state->ps; }
wined3d_state_record_lights(&stateblock->state, src_state); @@ -1028,7 +1033,14 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) apply_lights(device, &stateblock->state);
if (stateblock->changed.pixelShader) - wined3d_device_set_pixel_shader(device, stateblock->state.shader[WINED3D_SHADER_TYPE_PIXEL]); + { + if (stateblock->stateblock_state.ps) + wined3d_shader_incref(stateblock->stateblock_state.ps); + if (state->ps) + wined3d_shader_decref(state->ps); + state->ps = stateblock->stateblock_state.ps; + wined3d_device_set_pixel_shader(device, stateblock->stateblock_state.ps); + }
/* Pixel Shader Constants. */ for (i = 0; i < stateblock->num_contained_ps_consts_f; ++i) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 52106f2e59..b638d8773c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2974,6 +2974,8 @@ struct wined3d_stateblock_state struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F]; struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I]; BOOL vs_consts_b[WINED3D_MAX_CONSTS_B]; + + struct wined3d_shader *ps; };
struct wined3d_device
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com