mesa: optimize setting gl_Light state parameters
authorMarek Olšák <marek.olsak@amd.com>
Mon, 28 Sep 2020 04:22:30 +0000 (00:22 -0400)
committerMarge Bot <eric+marge@anholt.net>
Tue, 1 Dec 2020 11:52:10 +0000 (11:52 +0000)
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>

src/mesa/main/light.c
src/mesa/main/mtypes.h
src/mesa/program/prog_statevars.c
src/mesa/program/prog_statevars.h

index 0883832dbd6a8197153175681a7b616155759453..af0ac2e8bcd04d361b17208ebb1d1ac8b7fd9252 100644 (file)
@@ -123,7 +123,7 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
       FLUSH_VERTICES(ctx, _NEW_LIGHT);
       COPY_4V( light->Specular, params );
       break;
-   case GL_POSITION:
+   case GL_POSITION: {
       /* NOTE: position has already been transformed by ModelView! */
       if (TEST_EQ_4V(light->EyePosition, params))
         return;
@@ -133,7 +133,21 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa
         light->_Flags |= LIGHT_POSITIONAL;
       else
         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;
+   }
    case GL_SPOT_DIRECTION:
       /* NOTE: Direction already transformed by inverse ModelView! */
       if (TEST_EQ_3V(light->SpotDirection, params))
index 3def25906273f40331748f840fe3bf329ac3e919..f2527cdc0cfdc2bbd0e9d1a548aa9941c31d4280 100644 (file)
@@ -299,17 +299,27 @@ struct gl_material
  */
 struct gl_light
 {
-   GLfloat Ambient[4];         /**< ambient color */
-   GLfloat Diffuse[4];         /**< diffuse color */
-   GLfloat Specular[4];                /**< specular color */
-   GLfloat EyePosition[4];     /**< position in eye coordinates */
-   GLfloat SpotDirection[4];   /**< spotlight direction in eye coordinates */
-   GLfloat SpotExponent;
-   GLfloat SpotCutoff;         /**< in degrees */
-   GLfloat _CosCutoff;         /**< = MAX(0, cos(SpotCutoff)) */
-   GLfloat ConstantAttenuation;
-   GLfloat LinearAttenuation;
-   GLfloat QuadraticAttenuation;
+   union {
+      struct {
+         /* These must be in the same order as the STATE_* enums,
+          * which should also match the order of gl_LightSource members.
+          */
+         GLfloat Ambient[4];           /**< STATE_AMBIENT */
+         GLfloat Diffuse[4];           /**< STATE_DIFFUSE */
+         GLfloat Specular[4];          /**< STATE_SPECULAR */
+         GLfloat EyePosition[4];       /**< STATE_POSITION in eye coordinates */
+         GLfloat _HalfVector[4];       /**< STATE_HALF_VECTOR */
+         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 */
 
    /**
index f3ebfd22ac4e85089daeace0047ad1baa6db414e..7f32d3a104e0e07e6eca9549404c9f79686ed333 100644 (file)
@@ -126,52 +126,13 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
          /* state[1] is the light number */
          const GLuint ln = (GLuint) state[1];
          /* state[2] is the light attribute */
-         switch (state[2]) {
-         case STATE_AMBIENT:
-            COPY_4V(value, ctx->Light.Light[ln].Ambient);
-            return;
-         case STATE_DIFFUSE:
-            COPY_4V(value, ctx->Light.Light[ln].Diffuse);
-            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;
-         }
+         const unsigned index = state[2] - STATE_AMBIENT;
+         assert(index < 8);
+         if (index != STATE_SPOT_CUTOFF)
+            COPY_4V(value, &ctx->Light.Light[ln].Values[index * 4]);
+         else
+            value[0] = ctx->Light.Light[ln].Values[index * 4];
+         return;
       }
    case STATE_LIGHTMODEL_AMBIENT:
       COPY_4V(value, ctx->Light.Model.Ambient);
index 269ee8966a66e3afdd855f7ece6199434dfca4eb..75048de911f2463d92b1259ceb3a9cab462c3e7e 100644 (file)
@@ -91,18 +91,21 @@ typedef enum gl_state_index_ {
    STATE_PROGRAM_MATRIX_TRANSPOSE,
    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_DIFFUSE,
    STATE_SPECULAR,
-   STATE_EMISSION,
-   STATE_SHININESS,
-   STATE_HALF_VECTOR,
-
    STATE_POSITION,       /**< xyzw = position */
-   STATE_ATTENUATION,    /**< xyz = attenuation, w = spot exponent */
+   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_SHININESS,
+
    STATE_TEXGEN_EYE_S,
    STATE_TEXGEN_EYE_T,
    STATE_TEXGEN_EYE_R,