mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-31 22:50:08 +01:00
mesa: merge STATE_LIGHTPROD parameters
This decreases the CPU time spent in fetch_state. Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com> Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8850>
This commit is contained in:
parent
7df3d58f46
commit
272acbed0e
3 changed files with 193 additions and 6 deletions
|
|
@ -1107,6 +1107,28 @@ static void build_lighting( struct tnl_program *p )
|
|||
return;
|
||||
}
|
||||
|
||||
/* Declare light products first to place them sequentially next to each
|
||||
* other for optimal constant uploads.
|
||||
*/
|
||||
struct ureg lightprod_front[MAX_LIGHTS][3];
|
||||
struct ureg lightprod_back[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);
|
||||
if (twoside)
|
||||
lightprod_back[i][0] = get_lightprod(p, i, 1, STATE_AMBIENT);
|
||||
|
||||
lightprod_front[i][1] = get_lightprod(p, i, 0, STATE_DIFFUSE);
|
||||
if (twoside)
|
||||
lightprod_back[i][1] = get_lightprod(p, i, 1, STATE_DIFFUSE);
|
||||
|
||||
lightprod_front[i][2] = get_lightprod(p, i, 0, STATE_SPECULAR);
|
||||
if (twoside)
|
||||
lightprod_back[i][2] = get_lightprod(p, i, 1, STATE_SPECULAR);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_LIGHTS; i++) {
|
||||
if (p->state->unit[i].light_enabled) {
|
||||
struct ureg half = undef;
|
||||
|
|
@ -1171,9 +1193,9 @@ static void build_lighting( struct tnl_program *p )
|
|||
/* Front face lighting:
|
||||
*/
|
||||
{
|
||||
struct ureg ambient = get_lightprod(p, i, 0, STATE_AMBIENT);
|
||||
struct ureg diffuse = get_lightprod(p, i, 0, STATE_DIFFUSE);
|
||||
struct ureg specular = get_lightprod(p, i, 0, STATE_SPECULAR);
|
||||
struct ureg ambient = lightprod_front[i][0];
|
||||
struct ureg diffuse = lightprod_front[i][1];
|
||||
struct ureg specular = lightprod_front[i][2];
|
||||
struct ureg res0, res1;
|
||||
GLuint mask0, mask1;
|
||||
|
||||
|
|
@ -1226,9 +1248,9 @@ static void build_lighting( struct tnl_program *p )
|
|||
/* Back face lighting:
|
||||
*/
|
||||
if (twoside) {
|
||||
struct ureg ambient = get_lightprod(p, i, 1, STATE_AMBIENT);
|
||||
struct ureg diffuse = get_lightprod(p, i, 1, STATE_DIFFUSE);
|
||||
struct ureg specular = get_lightprod(p, i, 1, STATE_SPECULAR);
|
||||
struct ureg ambient = lightprod_back[i][0];
|
||||
struct ureg diffuse = lightprod_back[i][1];
|
||||
struct ureg specular = lightprod_back[i][2];
|
||||
struct ureg res0, res1;
|
||||
GLuint mask0, mask1;
|
||||
|
||||
|
|
|
|||
|
|
@ -178,6 +178,84 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
|
|||
value[3] = ctx->Light.Material.Attrib[index][3];
|
||||
return;
|
||||
}
|
||||
case STATE_LIGHTPROD_ARRAY_FRONT: {
|
||||
const unsigned first_light = state[1];
|
||||
const unsigned num_lights = state[2];
|
||||
|
||||
for (unsigned i = 0; i < num_lights; i++) {
|
||||
unsigned light = first_light + i;
|
||||
|
||||
for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT;
|
||||
attrib <= MAT_ATTRIB_FRONT_SPECULAR; attrib += 2) {
|
||||
for (int chan = 0; chan < 3; chan++) {
|
||||
/* We want offset to access out of bounds into the following
|
||||
* Diffuse and Specular fields. This is guaranteed to work
|
||||
* because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
|
||||
* on this memory layout.
|
||||
*/
|
||||
unsigned offset = (attrib / 2) * 4 + chan;
|
||||
*value++ =
|
||||
(&ctx->Light.LightSource[light].Ambient[0])[offset] *
|
||||
ctx->Light.Material.Attrib[attrib][chan];
|
||||
}
|
||||
/* [3] = material alpha */
|
||||
*value++ = ctx->Light.Material.Attrib[attrib][3];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case STATE_LIGHTPROD_ARRAY_BACK: {
|
||||
const unsigned first_light = state[1];
|
||||
const unsigned num_lights = state[2];
|
||||
|
||||
for (unsigned i = 0; i < num_lights; i++) {
|
||||
unsigned light = first_light + i;
|
||||
|
||||
for (unsigned attrib = MAT_ATTRIB_BACK_AMBIENT;
|
||||
attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib += 2) {
|
||||
for (int chan = 0; chan < 3; chan++) {
|
||||
/* We want offset to access out of bounds into the following
|
||||
* Diffuse and Specular fields. This is guaranteed to work
|
||||
* because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
|
||||
* on this memory layout.
|
||||
*/
|
||||
unsigned offset = (attrib / 2) * 4 + chan;
|
||||
*value++ =
|
||||
(&ctx->Light.LightSource[light].Ambient[0])[offset] *
|
||||
ctx->Light.Material.Attrib[attrib][chan];
|
||||
}
|
||||
/* [3] = material alpha */
|
||||
*value++ = ctx->Light.Material.Attrib[attrib][3];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case STATE_LIGHTPROD_ARRAY_TWOSIDE: {
|
||||
const unsigned first_light = state[1];
|
||||
const unsigned num_lights = state[2];
|
||||
|
||||
for (unsigned i = 0; i < num_lights; i++) {
|
||||
unsigned light = first_light + i;
|
||||
|
||||
for (unsigned attrib = MAT_ATTRIB_FRONT_AMBIENT;
|
||||
attrib <= MAT_ATTRIB_BACK_SPECULAR; attrib++) {
|
||||
for (int chan = 0; chan < 3; chan++) {
|
||||
/* We want offset to access out of bounds into the following
|
||||
* Diffuse and Specular fields. This is guaranteed to work
|
||||
* because STATE_LIGHT and STATE_LIGHT_ATTRIBS also rely
|
||||
* on this memory layout.
|
||||
*/
|
||||
unsigned offset = (attrib / 2) * 4 + chan;
|
||||
*value++ =
|
||||
(&ctx->Light.LightSource[light].Ambient[0])[offset] *
|
||||
ctx->Light.Material.Attrib[attrib][chan];
|
||||
}
|
||||
/* [3] = material alpha */
|
||||
*value++ = ctx->Light.Material.Attrib[attrib][3];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case STATE_TEXGEN:
|
||||
{
|
||||
/* state[1] is the texture unit */
|
||||
|
|
@ -698,6 +776,9 @@ _mesa_program_state_flags(const gl_state_index16 state[STATE_LENGTH])
|
|||
return _NEW_MATERIAL | _NEW_CURRENT_ATTRIB;
|
||||
|
||||
case STATE_LIGHTPROD:
|
||||
case STATE_LIGHTPROD_ARRAY_FRONT:
|
||||
case STATE_LIGHTPROD_ARRAY_BACK:
|
||||
case STATE_LIGHTPROD_ARRAY_TWOSIDE:
|
||||
case STATE_LIGHTMODEL_SCENECOLOR:
|
||||
/* these can be affected by glColor when colormaterial mode is used */
|
||||
return _NEW_LIGHT_CONSTANTS | _NEW_MATERIAL | _NEW_CURRENT_ATTRIB;
|
||||
|
|
@ -846,6 +927,15 @@ append_token(char *dst, gl_state_index k)
|
|||
case STATE_LIGHTPROD:
|
||||
append(dst, "lightprod");
|
||||
break;
|
||||
case STATE_LIGHTPROD_ARRAY_FRONT:
|
||||
append(dst, "lightprod.array.front");
|
||||
break;
|
||||
case STATE_LIGHTPROD_ARRAY_BACK:
|
||||
append(dst, "lightprod.array.back");
|
||||
break;
|
||||
case STATE_LIGHTPROD_ARRAY_TWOSIDE:
|
||||
append(dst, "lightprod.array.twoside");
|
||||
break;
|
||||
case STATE_TEXGEN:
|
||||
append(dst, "texgen");
|
||||
break;
|
||||
|
|
@ -1162,6 +1252,9 @@ _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
|
|||
case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY:
|
||||
case STATE_VERTEX_PROGRAM_ENV_ARRAY:
|
||||
case STATE_VERTEX_PROGRAM_LOCAL_ARRAY:
|
||||
case STATE_LIGHTPROD_ARRAY_FRONT:
|
||||
case STATE_LIGHTPROD_ARRAY_BACK:
|
||||
case STATE_LIGHTPROD_ARRAY_TWOSIDE:
|
||||
sprintf(tmp, "[%d..%d]", state[1], state[1] + state[2] - 1);
|
||||
append(str, tmp);
|
||||
break;
|
||||
|
|
@ -1409,6 +1502,75 @@ _mesa_optimize_state_parameters(struct gl_constants *consts,
|
|||
list->Parameters[first_param].Size = size * 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_LIGHTPROD: {
|
||||
if (list->Parameters[first_param].Size != 4)
|
||||
break;
|
||||
|
||||
gl_state_index16 state = STATE_NOT_STATE_VAR;
|
||||
unsigned num_lights = 0;
|
||||
|
||||
for (unsigned state_iter = STATE_LIGHTPROD_ARRAY_FRONT;
|
||||
state_iter <= STATE_LIGHTPROD_ARRAY_TWOSIDE; state_iter++) {
|
||||
unsigned num_attribs, base_attrib, attrib_incr;
|
||||
|
||||
if (state_iter == STATE_LIGHTPROD_ARRAY_FRONT) {
|
||||
num_attribs = 3;
|
||||
base_attrib = MAT_ATTRIB_FRONT_AMBIENT;
|
||||
attrib_incr = 2;
|
||||
} else if (state_iter == STATE_LIGHTPROD_ARRAY_BACK) {
|
||||
num_attribs = 3;
|
||||
base_attrib = MAT_ATTRIB_BACK_AMBIENT;
|
||||
attrib_incr = 2;
|
||||
} else if (state_iter == STATE_LIGHTPROD_ARRAY_TWOSIDE) {
|
||||
num_attribs = 6;
|
||||
base_attrib = MAT_ATTRIB_FRONT_AMBIENT;
|
||||
attrib_incr = 1;
|
||||
}
|
||||
|
||||
/* Find all attributes for one light. */
|
||||
while (first_param + (num_lights + 1) * num_attribs <=
|
||||
list->NumParameters &&
|
||||
(state == STATE_NOT_STATE_VAR || state == state_iter)) {
|
||||
unsigned i = 0, base = first_param + num_lights * num_attribs;
|
||||
|
||||
/* Consecutive light indices: */
|
||||
if (list->Parameters[first_param].StateIndexes[1] + num_lights ==
|
||||
list->Parameters[base].StateIndexes[1]) {
|
||||
for (i = 0; i < num_attribs; i++) {
|
||||
if (list->Parameters[base + i].StateIndexes[0] ==
|
||||
STATE_LIGHTPROD &&
|
||||
list->Parameters[base + i].Size == 4 &&
|
||||
/* Equal light indices: */
|
||||
list->Parameters[base + i].StateIndexes[1] ==
|
||||
list->Parameters[base + 0].StateIndexes[1] &&
|
||||
/* Consecutive attributes: */
|
||||
list->Parameters[base + i].StateIndexes[2] ==
|
||||
base_attrib + i * attrib_incr)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == num_attribs) {
|
||||
/* Accept all parameters for merging. */
|
||||
state = state_iter;
|
||||
last_param = base + num_attribs - 1;
|
||||
num_lights++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (last_param > first_param) {
|
||||
param_diff = last_param - first_param;
|
||||
|
||||
list->Parameters[first_param].StateIndexes[0] = state;
|
||||
list->Parameters[first_param].StateIndexes[2] = num_lights;
|
||||
list->Parameters[first_param].Size = (param_diff + 1) * 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (param_diff) {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ typedef enum gl_state_index_ {
|
|||
STATE_LIGHTMODEL_AMBIENT,
|
||||
STATE_LIGHTMODEL_SCENECOLOR,
|
||||
STATE_LIGHTPROD,
|
||||
STATE_LIGHTPROD_ARRAY_FRONT, /* multiple lights, only front faces */
|
||||
STATE_LIGHTPROD_ARRAY_BACK, /* multiple lights, only back faces */
|
||||
STATE_LIGHTPROD_ARRAY_TWOSIDE, /* multiple lights, both sides */
|
||||
|
||||
STATE_TEXGEN,
|
||||
STATE_TEXENV_COLOR,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue