Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 20 ++++++++++++++------ dlls/wined3d/stateblock.c | 30 +++++++++++++++++++++++------- dlls/wined3d/wined3d_private.h | 1 + 3 files changed, 38 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 8467acf361..043c89e129 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3500,10 +3500,19 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, return WINED3D_OK; }
+ if (texture) + wined3d_texture_incref(texture); + if (device->update_stateblock_state->textures[stage]) + wined3d_texture_decref(device->update_stateblock_state->textures[stage]); + device->update_stateblock_state->textures[stage] = texture; + if (device->recording) + { device->recording->changed.textures |= 1u << stage; + return WINED3D_OK; + }
- prev = device->update_state->textures[stage]; + prev = device->state.textures[stage]; TRACE("Previous texture %p.\n", prev);
if (texture == prev) @@ -3513,12 +3522,11 @@ HRESULT CDECL wined3d_device_set_texture(struct wined3d_device *device, }
TRACE("Setting new texture to %p.\n", texture); - device->update_state->textures[stage] = texture; + device->state.textures[stage] = texture;
if (texture) wined3d_texture_incref(texture); - if (!device->recording) - wined3d_cs_emit_set_texture(device->cs, stage, texture); + wined3d_cs_emit_set_texture(device->cs, stage, texture); if (prev) wined3d_texture_decref(prev);
@@ -5182,11 +5190,11 @@ void device_resource_released(struct wined3d_device *device, struct wined3d_reso device->state.textures[i] = NULL; }
- if (device->recording && &device->update_state->textures[i]->resource == resource) + if (device->recording && &device->update_stateblock_state->textures[i]->resource == resource) { ERR("Texture resource %p is still in use by recording stateblock %p, stage %u.\n", resource, device->recording, i); - device->update_state->textures[i] = NULL; + device->update_stateblock_state->textures[i] = NULL; } } break; diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 61de76403e..121fcf9f96 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -523,7 +523,9 @@ void state_unbind_resources(struct wined3d_state *state)
void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) { + struct wined3d_texture *texture; struct wined3d_shader *shader; + unsigned int i;
if ((shader = state->vs)) { @@ -536,6 +538,15 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state) state->ps = NULL; wined3d_shader_decref(shader); } + + for (i = 0; i < MAX_COMBINED_SAMPLERS; ++i) + { + if ((texture = state->textures[i])) + { + state->textures[i] = NULL; + wined3d_texture_decref(texture); + } + } }
void state_cleanup(struct wined3d_state *state) @@ -941,13 +952,13 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) if (!(map & 1)) continue;
TRACE("Updating texture %u to %p (was %p).\n", - i, src_state->textures[i], stateblock->state.textures[i]); + i, state->textures[i], stateblock->stateblock_state.textures[i]);
- if (src_state->textures[i]) - wined3d_texture_incref(src_state->textures[i]); - if (stateblock->state.textures[i]) - wined3d_texture_decref(stateblock->state.textures[i]); - stateblock->state.textures[i] = src_state->textures[i]; + if (state->textures[i]) + wined3d_texture_incref(state->textures[i]); + if (stateblock->stateblock_state.textures[i]) + wined3d_texture_decref(stateblock->stateblock_state.textures[i]); + stateblock->stateblock_state.textures[i] = state->textures[i]; }
for (i = 0; i < stateblock->num_contained_sampler_states; ++i) @@ -1149,7 +1160,12 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) if (!(map & 1)) continue;
stage = i < MAX_FRAGMENT_SAMPLERS ? i : WINED3DVERTEXTEXTURESAMPLER0 + i - MAX_FRAGMENT_SAMPLERS; - wined3d_device_set_texture(device, stage, stateblock->state.textures[i]); + if (stateblock->stateblock_state.textures[i]) + wined3d_texture_incref(stateblock->stateblock_state.textures[i]); + if (state->textures[i]) + wined3d_texture_decref(state->textures[i]); + state->textures[i] = stateblock->stateblock_state.textures[i]; + wined3d_device_set_texture(device, stage, stateblock->stateblock_state.textures[i]); }
map = stateblock->changed.clipplane; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bfeb639ef3..269c095ab4 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2982,6 +2982,7 @@ struct wined3d_stateblock_state
DWORD rs[WINEHIGHEST_RENDER_STATE + 1];
+ struct wined3d_texture *textures[MAX_COMBINED_SAMPLERS]; DWORD texture_states[MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1]; };