From: Elizabeth Figura zfigura@codeweavers.com
As is done in the GLSL backend.
Eventually we will stop manually calculating light counts in each individual place, and instead retrieve that from a stored struct wined3d_ffp_vs_settings. --- dlls/wined3d/glsl_shader.c | 48 +++++++++---------------------- dlls/wined3d/stateblock.c | 59 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 36 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index cad4bb0f9e6..ecc9dcd2ef5 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1768,11 +1768,11 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
if (update_mask & WINED3D_SHADER_CONST_FFP_LIGHTS) { - unsigned int point_idx, spot_idx, directional_idx, parallel_point_idx; const struct wined3d_ffp_vs_constants *constants; DWORD point_count = 0; DWORD spot_count = 0; DWORD directional_count = 0; + DWORD parallel_point_count = 0;
constants = wined3d_buffer_load_sysmem(context->device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP], context);
@@ -1793,49 +1793,29 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, ++directional_count; break; case WINED3D_LIGHT_PARALLELPOINT: + ++parallel_point_count; break; default: FIXME("Unhandled light type %#x.\n", state->light_state.lights[i]->OriginalParms.type); break; } } - point_idx = 0; - spot_idx = point_idx + point_count; - directional_idx = spot_idx + spot_count; - parallel_point_idx = directional_idx + directional_count;
GL_EXTCALL(glUniform3fv(prog->vs.light_ambient_location, 1, &constants->light.ambient.r)); checkGLcall("glUniform3fv");
- for (i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) - { - const struct wined3d_light_info *light_info = state->light_state.lights[i]; - unsigned int idx; - - if (!light_info) - continue; - - switch (light_info->OriginalParms.type) - { - case WINED3D_LIGHT_POINT: - idx = point_idx++; - break; - case WINED3D_LIGHT_SPOT: - idx = spot_idx++; - break; - case WINED3D_LIGHT_DIRECTIONAL: - idx = directional_idx++; - break; - case WINED3D_LIGHT_PARALLELPOINT: - idx = parallel_point_idx++; - break; - default: - FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); - continue; - } - shader_glsl_ffp_vertex_light_uniform(context_gl, state, idx, - light_info->OriginalParms.type, &constants->light.lights[i], prog); - } + for (i = 0; i < point_count; ++i) + shader_glsl_ffp_vertex_light_uniform(context_gl, state, i, + WINED3D_LIGHT_POINT, &constants->light.lights[i], prog); + for (; i < point_count + spot_count; ++i) + shader_glsl_ffp_vertex_light_uniform(context_gl, state, i, + WINED3D_LIGHT_SPOT, &constants->light.lights[i], prog); + for (; i < point_count + spot_count + directional_count; ++i) + shader_glsl_ffp_vertex_light_uniform(context_gl, state, i, + WINED3D_LIGHT_DIRECTIONAL, &constants->light.lights[i], prog); + for (; i < point_count + spot_count + directional_count + parallel_point_count; ++i) + shader_glsl_ffp_vertex_light_uniform(context_gl, state, i, + WINED3D_LIGHT_PARALLELPOINT, &constants->light.lights[i], prog); }
if (update_mask & WINED3D_SHADER_CONST_PS_F) diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 05ce6067d16..244d31e5d81 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -3346,6 +3346,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
if (changed->lights) { + unsigned int point_idx, spot_idx, directional_idx, parallel_point_idx; + unsigned int point_count = 0, spot_count = 0, directional_count = 0; struct wined3d_ffp_light_constants constants; struct wined3d_light_info *light, *cursor;
@@ -3358,11 +3360,64 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, }
wined3d_color_from_d3dcolor(&constants.ambient, state->rs[WINED3D_RS_AMBIENT]); + + for (unsigned int i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) + { + if (!state->light_state->lights[i]) + continue; + + switch (state->light_state->lights[i]->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + ++point_count; + break; + case WINED3D_LIGHT_SPOT: + ++spot_count; + break; + case WINED3D_LIGHT_DIRECTIONAL: + ++directional_count; + break; + case WINED3D_LIGHT_PARALLELPOINT: + break; + default: + FIXME("Unhandled light type %#x.\n", state->light_state->lights[i]->OriginalParms.type); + break; + } + } + point_idx = 0; + spot_idx = point_idx + point_count; + directional_idx = spot_idx + spot_count; + parallel_point_idx = directional_idx + directional_count; + for (unsigned int i = 0; i < WINED3D_MAX_ACTIVE_LIGHTS; ++i) { - if (state->light_state->lights[i]) - constants.lights[i] = state->light_state->lights[i]->constants; + const struct wined3d_light_info *light_info = state->light_state->lights[i]; + unsigned int idx; + + if (!light_info) + continue; + + switch (light_info->OriginalParms.type) + { + case WINED3D_LIGHT_POINT: + idx = point_idx++; + break; + case WINED3D_LIGHT_SPOT: + idx = spot_idx++; + break; + case WINED3D_LIGHT_DIRECTIONAL: + idx = directional_idx++; + break; + case WINED3D_LIGHT_PARALLELPOINT: + idx = parallel_point_idx++; + break; + default: + FIXME("Unhandled light type %#x.\n", light_info->OriginalParms.type); + continue; + } + constants.lights[idx] = state->light_state->lights[i]->constants; } + wined3d_device_context_push_constants(context, WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_LIGHTS, offsetof(struct wined3d_ffp_vs_constants, light), sizeof(constants), &constants); }