Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/stateblock.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 9e3eb23cc9..a6a6a284b3 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -990,24 +990,6 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) TRACE("Capture done.\n"); }
-static void apply_lights(struct wined3d_device *device, const struct wined3d_state *state) -{ - UINT i; - - for (i = 0; i < LIGHTMAP_SIZE; ++i) - { - struct list *e; - - LIST_FOR_EACH(e, &state->light_map[i]) - { - const struct wined3d_light_info *light = LIST_ENTRY(e, struct wined3d_light_info, entry); - - wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); - wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); - } - } -} - void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) { struct wined3d_stateblock_state *state = &stateblock->device->stateblock_state; @@ -1047,7 +1029,16 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) 1, &stateblock->stateblock_state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); }
- apply_lights(device, &stateblock->state); + for (i = 0; i < ARRAY_SIZE(stateblock->state.light_map); ++i) + { + const struct wined3d_light_info *light; + + LIST_FOR_EACH_ENTRY(light, &stateblock->state.light_map[i], struct wined3d_light_info, entry) + { + wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); + wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); + } + }
if (stateblock->changed.pixelShader) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 8 ++++---- dlls/wined3d/device.c | 14 +++++++------- dlls/wined3d/glsl_shader.c | 8 ++++---- dlls/wined3d/state.c | 4 ++-- dlls/wined3d/stateblock.c | 29 +++++++++++++++-------------- dlls/wined3d/utils.c | 6 +++--- dlls/wined3d/wined3d_private.h | 20 +++++++++++++------- 7 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 5ea25e992a..977c734d09 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -1830,7 +1830,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data)
light_idx = op->light.OriginalIndex;
- if (!(light_info = wined3d_state_get_light(&cs->state, light_idx))) + if (!(light_info = wined3d_state_get_light(&cs->state.light_state, light_idx))) { TRACE("Adding new light.\n"); if (!(light_info = heap_alloc_zero(sizeof(*light_info)))) @@ -1840,7 +1840,7 @@ static void wined3d_cs_exec_set_light(struct wined3d_cs *cs, const void *data) }
hash_idx = LIGHTMAP_HASHFUNC(light_idx); - list_add_head(&cs->state.light_map[hash_idx], &light_info->entry); + list_add_head(&cs->state.light_state.light_map[hash_idx], &light_info->entry); light_info->glIndex = -1; light_info->OriginalIndex = light_idx; } @@ -1877,14 +1877,14 @@ static void wined3d_cs_exec_set_light_enable(struct wined3d_cs *cs, const void * struct wined3d_light_info *light_info; int prev_idx;
- if (!(light_info = wined3d_state_get_light(&cs->state, op->idx))) + if (!(light_info = wined3d_state_get_light(&cs->state.light_state, op->idx))) { ERR("Light doesn't exist.\n"); return; }
prev_idx = light_info->glIndex; - wined3d_state_enable_light(&cs->state, &device->adapter->d3d_info, light_info, op->enable); + wined3d_state_enable_light(&cs->state.light_state, &device->adapter->d3d_info, light_info, op->enable); if (light_info->glIndex != prev_idx) { device_invalidate_state(device, STATE_LIGHT_TYPE); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index de653fa762..1a9b5ab55f 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1608,13 +1608,13 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; }
- if (!(object = wined3d_state_get_light(device->update_state, light_idx))) + if (!(object = wined3d_state_get_light(&device->update_state->light_state, light_idx))) { TRACE("Adding new light\n"); if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY;
- list_add_head(&device->update_state->light_map[hash_idx], &object->entry); + list_add_head(&device->update_state->light_state.light_map[hash_idx], &object->entry); object->glIndex = -1; object->OriginalIndex = light_idx; } @@ -1721,7 +1721,7 @@ HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device,
TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light);
- if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light information requested but light not defined\n"); return WINED3DERR_INVALIDCALL; @@ -1738,19 +1738,19 @@ HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UIN TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable);
/* Special case - enabling an undefined light creates one with a strict set of parameters. */ - if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->update_state->light_state, light_idx))) { TRACE("Light enabled requested but light not defined, so defining one!\n"); wined3d_device_set_light(device, light_idx, &WINED3D_default_light);
- if (!(light_info = wined3d_state_get_light(device->update_state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->update_state->light_state, light_idx))) { FIXME("Adding default lights has failed dismally\n"); return WINED3DERR_INVALIDCALL; } }
- wined3d_state_enable_light(device->update_state, &device->adapter->d3d_info, light_info, enable); + wined3d_state_enable_light(&device->update_state->light_state, &device->adapter->d3d_info, light_info, enable); if (!device->recording) wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable);
@@ -1763,7 +1763,7 @@ HRESULT CDECL wined3d_device_get_light_enable(const struct wined3d_device *devic
TRACE("device %p, light_idx %u, enable %p.\n", device, light_idx, enable);
- if (!(light_info = wined3d_state_get_light(&device->state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light enabled state requested but light not defined.\n"); return WINED3DERR_INVALIDCALL; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 5f1a86608b..9a2ef4557a 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1889,10 +1889,10 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) { - if (!state->lights[i]) + if (!state->light_state.lights[i]) continue;
- switch (state->lights[i]->OriginalParms.type) + switch (state->light_state.lights[i]->OriginalParms.type) { case WINED3D_LIGHT_POINT: ++point_count; @@ -1907,7 +1907,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context ++parallel_point_count; break; default: - FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); + FIXME("Unhandled light type %#x.\n", state->light_state.lights[i]->OriginalParms.type); break; } } @@ -1919,7 +1919,7 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context shader_glsl_ffp_vertex_lightambient_uniform(context, state, prog); for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) { - const struct wined3d_light_info *light_info = state->lights[i]; + const struct wined3d_light_info *light_info = state->light_state.lights[i]; unsigned int idx;
if (!light_info) diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 8708aa09b3..85700722fe 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3811,7 +3811,7 @@ static void transform_view(struct wined3d_context *context, const struct wined3d /* Reset lights. TODO: Call light apply func */ for (k = 0; k < gl_info->limits.lights; ++k) { - if (!(light = state->lights[k])) + if (!(light = state->light_state.lights[k])) continue; if (light->OriginalParms.type == WINED3D_LIGHT_DIRECTIONAL) gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, &light->direction.x); @@ -4142,7 +4142,7 @@ static void light(struct wined3d_context *context, const struct wined3d_state *s { const struct wined3d_gl_info *gl_info = context->gl_info; UINT Index = state_id - STATE_ACTIVELIGHT(0); - const struct wined3d_light_info *lightInfo = state->lights[Index]; + const struct wined3d_light_info *lightInfo = state->light_state.lights[Index];
if (!lightInfo) { diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index a6a6a284b3..7450d5308c 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -395,7 +395,7 @@ void stateblock_init_contained_states(struct wined3d_stateblock *stateblock) } }
-static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct list *light_map) +static void stateblock_init_lights(struct list *dst_map, struct list *src_map) { unsigned int i;
@@ -403,12 +403,12 @@ static void stateblock_init_lights(struct wined3d_stateblock *stateblock, struct { const struct wined3d_light_info *src_light;
- LIST_FOR_EACH_ENTRY(src_light, &light_map[i], struct wined3d_light_info, entry) + LIST_FOR_EACH_ENTRY(src_light, &src_map[i], struct wined3d_light_info, entry) { struct wined3d_light_info *dst_light = heap_alloc(sizeof(*dst_light));
*dst_light = *src_light; - list_add_tail(&stateblock->state.light_map[i], &dst_light->entry); + list_add_tail(&dst_map[i], &dst_light->entry); } } } @@ -581,13 +581,13 @@ void state_cleanup(struct wined3d_state *state)
for (counter = 0; counter < MAX_ACTIVE_LIGHTS; ++counter) { - state->lights[counter] = NULL; + state->light_state.lights[counter] = NULL; }
for (counter = 0; counter < LIGHTMAP_SIZE; ++counter) { struct list *e1, *e2; - LIST_FOR_EACH_SAFE(e1, e2, &state->light_map[counter]) + LIST_FOR_EACH_SAFE(e1, e2, &state->light_state.light_map[counter]) { struct wined3d_light_info *light = LIST_ENTRY(e1, struct wined3d_light_info, entry); list_remove(&light->entry); @@ -612,7 +612,7 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock) return refcount; }
-struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, unsigned int idx) +struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_light_state *state, unsigned int idx) { struct wined3d_light_info *light_info; unsigned int hash_idx; @@ -627,7 +627,7 @@ struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *s return NULL; }
-void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3d_d3d_info *d3d_info, +void wined3d_state_enable_light(struct wined3d_light_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) { unsigned int light_count, i; @@ -672,7 +672,8 @@ void wined3d_state_enable_light(struct wined3d_state *state, const struct wined3 WARN("Too many concurrently active lights.\n"); }
-static void wined3d_state_record_lights(struct wined3d_state *dst_state, const struct wined3d_state *src_state) +static void wined3d_state_record_lights(struct wined3d_light_state *dst_state, + const struct wined3d_light_state *src_state) { const struct wined3d_light_info *src; struct wined3d_light_info *dst; @@ -985,7 +986,7 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->stateblock_state.ps = state->ps; }
- wined3d_state_record_lights(&stateblock->state, src_state); + wined3d_state_record_lights(&stateblock->state.light_state, &src_state->light_state);
TRACE("Capture done.\n"); } @@ -1029,11 +1030,11 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) 1, &stateblock->stateblock_state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); }
- for (i = 0; i < ARRAY_SIZE(stateblock->state.light_map); ++i) + for (i = 0; i < ARRAY_SIZE(stateblock->state.light_state.light_map); ++i) { const struct wined3d_light_info *light;
- LIST_FOR_EACH_ENTRY(light, &stateblock->state.light_map[i], struct wined3d_light_info, entry) + LIST_FOR_EACH_ENTRY(light, &stateblock->state.light_state.light_map[i], struct wined3d_light_info, entry) { wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); @@ -1451,7 +1452,7 @@ void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb,
for (i = 0; i < LIGHTMAP_SIZE; i++) { - list_init(&state->light_map[i]); + list_init(&state->light_state.light_map[i]); }
if (flags & WINED3D_STATE_INIT_DEFAULT) @@ -1514,7 +1515,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, switch (type) { case WINED3D_SBT_ALL: - stateblock_init_lights(stateblock, device->state.light_map); + stateblock_init_lights(stateblock->state.light_state.light_map, device->state.light_state.light_map); stateblock_savedstates_set_all(&stateblock->changed, d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count); break; @@ -1525,7 +1526,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, break;
case WINED3D_SBT_VERTEX_STATE: - stateblock_init_lights(stateblock, device->state.light_map); + stateblock_init_lights(stateblock->state.light_state.light_map, device->state.light_state.light_map); stateblock_savedstates_set_vertex(&stateblock->changed, d3d_info->limits.vs_uniform_count); break; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index aa68799535..f74efa0feb 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -6284,10 +6284,10 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context,
for (i = 0; i < MAX_ACTIVE_LIGHTS; ++i) { - if (!state->lights[i]) + if (!state->light_state.lights[i]) continue;
- switch (state->lights[i]->OriginalParms.type) + switch (state->light_state.lights[i]->OriginalParms.type) { case WINED3D_LIGHT_POINT: ++settings->point_light_count; @@ -6302,7 +6302,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_context *context, ++settings->parallel_point_light_count; break; default: - FIXME("Unhandled light type %#x.\n", state->lights[i]->OriginalParms.type); + FIXME("Unhandled light type %#x.\n", state->light_state.lights[i]->OriginalParms.type); break; } } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 1f034506c7..83270869e9 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2885,6 +2885,16 @@ struct wined3d_stream_state UINT flags; };
+#define LIGHTMAP_SIZE 43 +#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) + +struct wined3d_light_state +{ + /* Light hashmap. Collisions are handled using linked lists. */ + struct list light_map[LIGHTMAP_SIZE]; + const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; +}; + #define WINED3D_STATE_NO_REF 0x00000001 #define WINED3D_STATE_INIT_DEFAULT 0x00000002
@@ -2932,11 +2942,7 @@ struct wined3d_state RECT scissor_rects[WINED3D_MAX_VIEWPORTS]; unsigned int scissor_rect_count;
- /* Light hashmap. Collisions are handled using linked lists. */ -#define LIGHTMAP_SIZE 43 -#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE) - struct list light_map[LIGHTMAP_SIZE]; - const struct wined3d_light_info *lights[MAX_ACTIVE_LIGHTS]; + struct wined3d_light_state light_state;
DWORD render_states[WINEHIGHEST_RENDER_STATE + 1]; struct wined3d_blend_state *blend_state; @@ -3619,9 +3625,9 @@ void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state, 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, +void wined3d_state_enable_light(struct wined3d_light_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN; -struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_state *state, +struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_light_state *state, unsigned int idx) DECLSPEC_HIDDEN; void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 17 +++-------------- dlls/wined3d/stateblock.c | 27 +++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 1a9b5ab55f..691531b22e 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1573,8 +1573,8 @@ void CDECL wined3d_device_multiply_transform(struct wined3d_device *device, HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, UINT light_idx, const struct wined3d_light *light) { - UINT hash_idx = LIGHTMAP_HASHFUNC(light_idx); struct wined3d_light_info *object = NULL; + HRESULT hr; float rho;
TRACE("device %p, light_idx %u, light %p.\n", device, light_idx, light); @@ -1608,16 +1608,8 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; }
- if (!(object = wined3d_state_get_light(&device->update_state->light_state, light_idx))) - { - TRACE("Adding new light\n"); - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; - - list_add_head(&device->update_state->light_state.light_map[hash_idx], &object->entry); - object->glIndex = -1; - object->OriginalIndex = light_idx; - } + if (FAILED(hr = wined3d_state_set_light(&device->update_state->light_state, light_idx, light, &object))) + return hr;
/* Initialize the object. */ TRACE("Light %u setting to type %#x, diffuse %s, specular %s, ambient %s, " @@ -1629,9 +1621,6 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, light->direction.x, light->direction.y, light->direction.z, light->range, light->falloff, light->theta, light->phi);
- /* Save away the information. */ - object->OriginalParms = *light; - switch (light->type) { case WINED3D_LIGHT_POINT: diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 7450d5308c..678c146ccf 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -627,6 +627,33 @@ struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_light_st return NULL; }
+HRESULT wined3d_state_set_light(struct wined3d_light_state *state, DWORD light_idx, + const struct wined3d_light *params, struct wined3d_light_info **light_info) +{ + struct wined3d_light_info *object; + unsigned int hash_idx; + + if (!(object = wined3d_state_get_light(state, light_idx))) + { + TRACE("Adding new light.\n"); + if (!(object = heap_alloc_zero(sizeof(*object)))) + { + ERR("Failed to allocate light info.\n"); + return E_OUTOFMEMORY; + } + + hash_idx = LIGHTMAP_HASHFUNC(light_idx); + list_add_head(&state->light_map[hash_idx], &object->entry); + object->glIndex = -1; + object->OriginalIndex = light_idx; + } + + object->OriginalParms = *params; + + *light_info = object; + return WINED3D_OK; +} + void wined3d_state_enable_light(struct wined3d_light_state *state, const struct wined3d_d3d_info *d3d_info, struct wined3d_light_info *light_info, BOOL enable) { diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 83270869e9..d05944f202 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3629,6 +3629,8 @@ void wined3d_state_enable_light(struct wined3d_light_state *state, const struct struct wined3d_light_info *light_info, BOOL enable) DECLSPEC_HIDDEN; struct wined3d_light_info *wined3d_state_get_light(const struct wined3d_light_state *state, unsigned int idx) DECLSPEC_HIDDEN; +HRESULT wined3d_state_set_light(struct wined3d_light_state *state, DWORD light_idx, + const struct wined3d_light *params, struct wined3d_light_info **light_info) DECLSPEC_HIDDEN; void state_init(struct wined3d_state *state, struct wined3d_fb_state *fb, const struct wined3d_d3d_info *d3d_info, DWORD flags) DECLSPEC_HIDDEN; void state_unbind_resources(struct wined3d_state *state) DECLSPEC_HIDDEN;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/device.c | 32 ++++++++++++++++++++++++-------- dlls/wined3d/stateblock.c | 25 ++++++++++++++++++++----- dlls/wined3d/wined3d_private.h | 2 ++ 3 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 691531b22e..0de43e4475 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1608,7 +1608,12 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, return WINED3DERR_INVALIDCALL; }
- if (FAILED(hr = wined3d_state_set_light(&device->update_state->light_state, light_idx, light, &object))) + if (FAILED(hr = wined3d_state_set_light(&device->update_stateblock_state->light_state, light_idx, light, &object))) + return hr; + if (device->recording) + return WINED3D_OK; + + if (FAILED(hr = wined3d_state_set_light(&device->state.light_state, light_idx, light, &object))) return hr;
/* Initialize the object. */ @@ -1697,8 +1702,7 @@ HRESULT CDECL wined3d_device_set_light(struct wined3d_device *device, FIXME("Unrecognized light type %#x.\n", light->type); }
- if (!device->recording) - wined3d_cs_emit_set_light(device->cs, object); + wined3d_cs_emit_set_light(device->cs, object);
return WINED3D_OK; } @@ -1723,25 +1727,37 @@ HRESULT CDECL wined3d_device_get_light(const struct wined3d_device *device, HRESULT CDECL wined3d_device_set_light_enable(struct wined3d_device *device, UINT light_idx, BOOL enable) { struct wined3d_light_info *light_info; + HRESULT hr;
TRACE("device %p, light_idx %u, enable %#x.\n", device, light_idx, enable);
+ if (!(light_info = wined3d_state_get_light(&device->update_stateblock_state->light_state, light_idx))) + { + if (FAILED(hr = wined3d_state_set_light(&device->update_stateblock_state->light_state, light_idx, + &WINED3D_default_light, &light_info))) + return hr; + } + wined3d_state_enable_light(&device->update_stateblock_state->light_state, + &device->adapter->d3d_info, light_info, enable); + + if (device->recording) + return WINED3D_OK; + /* Special case - enabling an undefined light creates one with a strict set of parameters. */ - if (!(light_info = wined3d_state_get_light(&device->update_state->light_state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->state.light_state, light_idx))) { TRACE("Light enabled requested but light not defined, so defining one!\n"); wined3d_device_set_light(device, light_idx, &WINED3D_default_light);
- if (!(light_info = wined3d_state_get_light(&device->update_state->light_state, light_idx))) + if (!(light_info = wined3d_state_get_light(&device->state.light_state, light_idx))) { FIXME("Adding default lights has failed dismally\n"); return WINED3DERR_INVALIDCALL; } }
- wined3d_state_enable_light(&device->update_state->light_state, &device->adapter->d3d_info, light_info, enable); - if (!device->recording) - wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable); + wined3d_state_enable_light(&device->state.light_state, &device->adapter->d3d_info, light_info, enable); + wined3d_cs_emit_set_light_enable(device->cs, light_idx, enable);
return WINED3D_OK; } diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 678c146ccf..b708f37576 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -1013,7 +1013,7 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock) stateblock->stateblock_state.ps = state->ps; }
- wined3d_state_record_lights(&stateblock->state.light_state, &src_state->light_state); + wined3d_state_record_lights(&stateblock->stateblock_state.light_state, &state->light_state);
TRACE("Capture done.\n"); } @@ -1057,12 +1057,18 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock) 1, &stateblock->stateblock_state.vs_consts_b[stateblock->contained_vs_consts_b[i]]); }
- for (i = 0; i < ARRAY_SIZE(stateblock->state.light_state.light_map); ++i) + for (i = 0; i < ARRAY_SIZE(stateblock->stateblock_state.light_state.light_map); ++i) { const struct wined3d_light_info *light; + struct wined3d_light_info *new_light;
- LIST_FOR_EACH_ENTRY(light, &stateblock->state.light_state.light_map[i], struct wined3d_light_info, entry) + LIST_FOR_EACH_ENTRY(light, &stateblock->stateblock_state.light_state.light_map[i], struct wined3d_light_info, entry) { + if (SUCCEEDED(wined3d_state_set_light(&state->light_state, light->OriginalIndex, + &light->OriginalParms, &new_light))) + { + wined3d_state_enable_light(&state->light_state, &device->adapter->d3d_info, new_light, light->glIndex != -1); + } wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms); wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1); } @@ -1520,6 +1526,13 @@ static void stateblock_state_init_default(struct wined3d_stateblock_state *state void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state, const struct wined3d_device *device, DWORD flags) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(state->light_state.light_map); i++) + { + list_init(&state->light_state.light_map[i]); + } + if (flags & WINED3D_STATE_INIT_DEFAULT) stateblock_state_init_default(state, &device->adapter->d3d_info); } @@ -1542,7 +1555,8 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, switch (type) { case WINED3D_SBT_ALL: - stateblock_init_lights(stateblock->state.light_state.light_map, device->state.light_state.light_map); + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); stateblock_savedstates_set_all(&stateblock->changed, d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count); break; @@ -1553,7 +1567,8 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, break;
case WINED3D_SBT_VERTEX_STATE: - stateblock_init_lights(stateblock->state.light_state.light_map, device->state.light_state.light_map); + stateblock_init_lights(stateblock->stateblock_state.light_state.light_map, + device->stateblock_state.light_state.light_map); stateblock_savedstates_set_vertex(&stateblock->changed, d3d_info->limits.vs_uniform_count); break; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index d05944f202..5de949ed10 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3001,6 +3001,8 @@ struct wined3d_stateblock_state struct wined3d_material material; struct wined3d_viewport viewport; RECT scissor_rect; + + struct wined3d_light_state light_state; };
struct wined3d_device