mesa: optimize setting gl_Light state parameters

The order of enums is a preparation for a future commit, but if you are
guessing that I just want to copy all light params into a constant buffer
with one memcpy, you are right.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6946>
This commit is contained in:
Marek Olšák
2020-09-28 00:22:30 -04:00
committed by Marge Bot
parent cc4afb2101
commit 51ce2f6c8d
4 changed files with 52 additions and 64 deletions

View File

@@ -123,7 +123,7 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
FLUSH_VERTICES(ctx, _NEW_LIGHT); FLUSH_VERTICES(ctx, _NEW_LIGHT);
COPY_4V( light->Specular, params ); COPY_4V( light->Specular, params );
break; break;
case GL_POSITION: case GL_POSITION: {
/* NOTE: position has already been transformed by ModelView! */ /* NOTE: position has already been transformed by ModelView! */
if (TEST_EQ_4V(light->EyePosition, params)) if (TEST_EQ_4V(light->EyePosition, params))
return; return;
@@ -133,7 +133,21 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
light->_Flags |= LIGHT_POSITIONAL; light->_Flags |= LIGHT_POSITIONAL;
else else
light->_Flags &= ~LIGHT_POSITIONAL; light->_Flags &= ~LIGHT_POSITIONAL;
static const GLfloat eye_z[] = {0, 0, 1};
GLfloat p[3];
/* Compute infinite half angle vector:
* halfVector = normalize(normalize(lightPos) + (0, 0, 1))
* light.EyePosition.w should be 0 for infinite lights.
*/
COPY_3V(p, params);
NORMALIZE_3FV(p);
ADD_3V(p, p, eye_z);
NORMALIZE_3FV(p);
COPY_3V(light->_HalfVector, p);
light->_HalfVector[3] = 1.0;
break; break;
}
case GL_SPOT_DIRECTION: case GL_SPOT_DIRECTION:
/* NOTE: Direction already transformed by inverse ModelView! */ /* NOTE: Direction already transformed by inverse ModelView! */
if (TEST_EQ_3V(light->SpotDirection, params)) if (TEST_EQ_3V(light->SpotDirection, params))

View File

@@ -299,17 +299,27 @@ struct gl_material
*/ */
struct gl_light struct gl_light
{ {
GLfloat Ambient[4]; /**< ambient color */ union {
GLfloat Diffuse[4]; /**< diffuse color */ struct {
GLfloat Specular[4]; /**< specular color */ /* These must be in the same order as the STATE_* enums,
GLfloat EyePosition[4]; /**< position in eye coordinates */ * which should also match the order of gl_LightSource members.
GLfloat SpotDirection[4]; /**< spotlight direction in eye coordinates */ */
GLfloat SpotExponent; GLfloat Ambient[4]; /**< STATE_AMBIENT */
GLfloat SpotCutoff; /**< in degrees */ GLfloat Diffuse[4]; /**< STATE_DIFFUSE */
GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */ GLfloat Specular[4]; /**< STATE_SPECULAR */
GLfloat ConstantAttenuation; GLfloat EyePosition[4]; /**< STATE_POSITION in eye coordinates */
GLfloat LinearAttenuation; GLfloat _HalfVector[4]; /**< STATE_HALF_VECTOR */
GLfloat QuadraticAttenuation; GLfloat SpotDirection[3]; /**< STATE_SPOT_DIRECTION in eye coordinates */
GLfloat _CosCutoff; /**< = MAX(0, cos(SpotCutoff)) */
GLfloat ConstantAttenuation; /**< STATE_ATTENUATION */
GLfloat LinearAttenuation;
GLfloat QuadraticAttenuation;
GLfloat SpotExponent;
GLfloat SpotCutoff; /**< STATE_SPOT_CUTOFF in degrees */
};
GLfloat Values[29];
};
GLboolean Enabled; /**< On/off flag */ GLboolean Enabled; /**< On/off flag */
/** /**

View File

@@ -126,52 +126,13 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
/* state[1] is the light number */ /* state[1] is the light number */
const GLuint ln = (GLuint) state[1]; const GLuint ln = (GLuint) state[1];
/* state[2] is the light attribute */ /* state[2] is the light attribute */
switch (state[2]) { const unsigned index = state[2] - STATE_AMBIENT;
case STATE_AMBIENT: assert(index < 8);
COPY_4V(value, ctx->Light.Light[ln].Ambient); if (index != STATE_SPOT_CUTOFF)
return; COPY_4V(value, &ctx->Light.Light[ln].Values[index * 4]);
case STATE_DIFFUSE: else
COPY_4V(value, ctx->Light.Light[ln].Diffuse); value[0] = ctx->Light.Light[ln].Values[index * 4];
return; return;
case STATE_SPECULAR:
COPY_4V(value, ctx->Light.Light[ln].Specular);
return;
case STATE_POSITION:
COPY_4V(value, ctx->Light.Light[ln].EyePosition);
return;
case STATE_ATTENUATION:
value[0] = ctx->Light.Light[ln].ConstantAttenuation;
value[1] = ctx->Light.Light[ln].LinearAttenuation;
value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
value[3] = ctx->Light.Light[ln].SpotExponent;
return;
case STATE_SPOT_DIRECTION:
COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
value[3] = ctx->Light.Light[ln]._CosCutoff;
return;
case STATE_SPOT_CUTOFF:
value[0] = ctx->Light.Light[ln].SpotCutoff;
return;
case STATE_HALF_VECTOR:
{
static const GLfloat eye_z[] = {0, 0, 1};
GLfloat p[3];
/* Compute infinite half angle vector:
* halfVector = normalize(normalize(lightPos) + (0, 0, 1))
* light.EyePosition.w should be 0 for infinite lights.
*/
COPY_3V(p, ctx->Light.Light[ln].EyePosition);
NORMALIZE_3FV(p);
ADD_3V(p, p, eye_z);
NORMALIZE_3FV(p);
COPY_3V(value, p);
value[3] = 1.0;
}
return;
default:
unreachable("Invalid light state in fetch_state");
return;
}
} }
case STATE_LIGHTMODEL_AMBIENT: case STATE_LIGHTMODEL_AMBIENT:
COPY_4V(value, ctx->Light.Model.Ambient); COPY_4V(value, ctx->Light.Model.Ambient);

View File

@@ -91,17 +91,20 @@ typedef enum gl_state_index_ {
STATE_PROGRAM_MATRIX_TRANSPOSE, STATE_PROGRAM_MATRIX_TRANSPOSE,
STATE_PROGRAM_MATRIX_INVTRANS, STATE_PROGRAM_MATRIX_INVTRANS,
/* These 8 enums must be in the same order as the gl_light union members,
* which should also match the order of gl_LightSource members.
*/
STATE_AMBIENT, STATE_AMBIENT,
STATE_DIFFUSE, STATE_DIFFUSE,
STATE_SPECULAR, STATE_SPECULAR,
STATE_POSITION, /**< xyzw = position */
STATE_HALF_VECTOR,
STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */
STATE_SPOT_CUTOFF, /**< x = cutoff, yzw = undefined */
STATE_EMISSION, STATE_EMISSION,
STATE_SHININESS, STATE_SHININESS,
STATE_HALF_VECTOR,
STATE_POSITION, /**< xyzw = position */
STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */
STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
STATE_SPOT_CUTOFF, /**< x = cutoff, yzw = undefined */
STATE_TEXGEN_EYE_S, STATE_TEXGEN_EYE_S,
STATE_TEXGEN_EYE_T, STATE_TEXGEN_EYE_T,