mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
mesa: use less temporaries in build_lighting
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: 272acbed0e ("mesa: merge STATE_LIGHTPROD parameters")
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14590>
This commit is contained in:
parent
b8c518f0fb
commit
3b4d4c7d84
1 changed files with 44 additions and 12 deletions
|
|
@ -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<<attrib)) {
|
||||
struct ureg light_value =
|
||||
register_param3(p, STATE_LIGHT, light, property);
|
||||
struct ureg material_value = get_material(p, side, property);
|
||||
struct ureg tmp = get_temp(p);
|
||||
emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value);
|
||||
return tmp;
|
||||
*is_state_light = true;
|
||||
return light_value;
|
||||
}
|
||||
else
|
||||
else {
|
||||
*is_state_light = false;
|
||||
return register_param3(p, STATE_LIGHTPROD, light, attrib);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1117,20 +1117,28 @@ static void build_lighting( struct tnl_program *p )
|
|||
*/
|
||||
struct ureg lightprod_front[MAX_LIGHTS][3];
|
||||
struct ureg lightprod_back[MAX_LIGHTS][3];
|
||||
bool lightprod_front_is_state_light[MAX_LIGHTS][3];
|
||||
bool lightprod_back_is_state_light[MAX_LIGHTS][3];
|
||||
|
||||
for (i = 0; i < MAX_LIGHTS; i++) {
|
||||
if (p->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];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue