diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index 2ea2d11f6f5..24face21db3 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -919,19 +919,19 @@ static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) static struct ureg get_lightprod( struct tnl_program *p, GLuint light, - GLuint side, GLuint property ) + GLuint side, GLuint property, bool *is_state_light ) { GLuint attrib = material_attrib(side, property); if (p->materials & (1<state->unit[i].light_enabled) { - lightprod_front[i][0] = get_lightprod(p, i, 0, STATE_AMBIENT); + lightprod_front[i][0] = get_lightprod(p, i, 0, STATE_AMBIENT, + &lightprod_front_is_state_light[i][0]); if (twoside) - lightprod_back[i][0] = get_lightprod(p, i, 1, STATE_AMBIENT); + lightprod_back[i][0] = get_lightprod(p, i, 1, STATE_AMBIENT, + &lightprod_back_is_state_light[i][0]); - lightprod_front[i][1] = get_lightprod(p, i, 0, STATE_DIFFUSE); + lightprod_front[i][1] = get_lightprod(p, i, 0, STATE_DIFFUSE, + &lightprod_front_is_state_light[i][1]); if (twoside) - lightprod_back[i][1] = get_lightprod(p, i, 1, STATE_DIFFUSE); + lightprod_back[i][1] = get_lightprod(p, i, 1, STATE_DIFFUSE, + &lightprod_back_is_state_light[i][1]); - lightprod_front[i][2] = get_lightprod(p, i, 0, STATE_SPECULAR); + lightprod_front[i][2] = get_lightprod(p, i, 0, STATE_SPECULAR, + &lightprod_front_is_state_light[i][2]); if (twoside) - lightprod_back[i][2] = get_lightprod(p, i, 1, STATE_SPECULAR); + lightprod_back[i][2] = get_lightprod(p, i, 1, STATE_SPECULAR, + &lightprod_back_is_state_light[i][2]); } } @@ -1217,6 +1225,18 @@ static void build_lighting( struct tnl_program *p ) /* Front face lighting: */ { + /* Transform STATE_LIGHT into STATE_LIGHTPROD if needed. This isn't done in + * get_lightprod to avoid using too many temps. + */ + for (int j = 0; j < 3; j++) { + if (lightprod_front_is_state_light[i][j]) { + struct ureg material_value = get_material(p, 0, STATE_AMBIENT + j); + struct ureg tmp = get_temp(p); + emit_op2(p, OPCODE_MUL, tmp, 0, lightprod_front[i][j], material_value); + lightprod_front[i][j] = tmp; + } + } + struct ureg ambient = lightprod_front[i][0]; struct ureg diffuse = lightprod_front[i][1]; struct ureg specular = lightprod_front[i][2]; @@ -1272,6 +1292,18 @@ static void build_lighting( struct tnl_program *p ) /* Back face lighting: */ if (twoside) { + /* Transform STATE_LIGHT into STATE_LIGHTPROD if needed. This isn't done in + * get_lightprod to avoid using too many temps. + */ + for (int j = 0; j < 3; j++) { + if (lightprod_back_is_state_light[i][j]) { + struct ureg material_value = get_material(p, 1, STATE_AMBIENT + j); + struct ureg tmp = get_temp(p); + emit_op2(p, OPCODE_MUL, tmp, 1, lightprod_back[i][j], material_value); + lightprod_back[i][j] = tmp; + } + } + struct ureg ambient = lightprod_back[i][0]; struct ureg diffuse = lightprod_back[i][1]; struct ureg specular = lightprod_back[i][2];