From 3b4d4c7d8418c40000e25ecbda99f6a10d089b8c Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 18 Jan 2022 11:50:37 +0100 Subject: [PATCH] mesa: use less temporaries in build_lighting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preallocating temporaries can cause "out of temporaries" error. Switch to on-demand allocation. Growing temp_in_use would be an alternative, but some drivers support less than 64 temps (see PIPE_SHADER_CAP_MAX_TEMPS) so this wouldn't help them. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5777 Fixes: 272acbed0e2 ("mesa: merge STATE_LIGHTPROD parameters") Reviewed-by: Marek Olšák Part-of: --- src/mesa/main/ffvertex_prog.c | 56 +++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 12 deletions(-) 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];