mesa: merge STATE_LIGHT_ATTENUATION and STATE_LIGHT_POSITION_* parameters
authorMarek Olšák <marek.olsak@amd.com>
Sun, 13 Dec 2020 04:04:56 +0000 (23:04 -0500)
committerMarge Bot <eric+marge@anholt.net>
Fri, 26 Feb 2021 23:38:02 +0000 (23:38 +0000)
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>

src/mesa/main/ffvertex_prog.c
src/mesa/program/prog_statevars.c
src/mesa/program/prog_statevars.h

index 525b098..ff5cf23 100644 (file)
@@ -1129,6 +1129,22 @@ static void build_lighting( struct tnl_program *p )
       }
    }
 
+   /* Add more variables now that we'll use later, so that they are nicely
+    * sorted in the parameter list.
+    */
+   for (i = 0; i < MAX_LIGHTS; i++) {
+      if (p->state->unit[i].light_enabled) {
+         if (p->state->unit[i].light_eyepos3_is_zero)
+            register_param2(p, STATE_LIGHT_POSITION_NORMALIZED, i);
+         else
+            register_param2(p, STATE_LIGHT_POSITION, i);
+      }
+   }
+   for (i = 0; i < MAX_LIGHTS; i++) {
+      if (p->state->unit[i].light_enabled)
+         register_param3(p, STATE_LIGHT, i, STATE_ATTENUATION);
+   }
+
    for (i = 0; i < MAX_LIGHTS; i++) {
       if (p->state->unit[i].light_enabled) {
         struct ureg half = undef;
index ad53ed1..c30e3c2 100644 (file)
@@ -129,6 +129,16 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
              state[2] * sizeof(float));
       return;
    }
+   case STATE_LIGHT_ATTENUATION_ARRAY: {
+      const unsigned first = state[1];
+      const unsigned num_lights = state[2];
+      for (unsigned i = 0; i < num_lights; i++) {
+         COPY_4V(value,
+                 &ctx->Light.LightSource[first + i].ConstantAttenuation);
+         value += 4;
+      }
+      return;
+   }
    case STATE_LIGHTMODEL_AMBIENT:
       COPY_4V(value, ctx->Light.Model.Ambient);
       return;
@@ -643,6 +653,16 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
       }
       return;
 
+   case STATE_LIGHT_POSITION_ARRAY: {
+      const unsigned first = state[1];
+      const unsigned num_lights = state[2];
+      for (unsigned i = 0; i < num_lights; i++) {
+         COPY_4V(value, ctx->Light.Light[first + i]._Position);
+         value += 4;
+      }
+      return;
+   }
+
    case STATE_LIGHT_POSITION_NORMALIZED:
       {
          const GLuint ln = (GLuint) state[1];
@@ -653,6 +673,19 @@ fetch_state(struct gl_context *ctx, const gl_state_index16 state[],
       }
       return;
 
+   case STATE_LIGHT_POSITION_NORMALIZED_ARRAY: {
+      const unsigned first = state[1];
+      const unsigned num_lights = state[2];
+      for (unsigned i = 0; i < num_lights; i++) {
+         float p[4];
+         COPY_4V(p, ctx->Light.Light[first + i]._Position);
+         NORMALIZE_3FV(p);
+         COPY_4V(value, p);
+         value += 4;
+      }
+      return;
+   }
+
    case STATE_LIGHT_HALF_VECTOR:
       {
          const GLuint ln = (GLuint) state[1];
@@ -785,10 +818,13 @@ _mesa_program_state_flags(const gl_state_index16 state[STATE_LENGTH])
 
    case STATE_LIGHT:
    case STATE_LIGHT_ARRAY:
+   case STATE_LIGHT_ATTENUATION_ARRAY:
    case STATE_LIGHTMODEL_AMBIENT:
    case STATE_LIGHT_SPOT_DIR_NORMALIZED:
    case STATE_LIGHT_POSITION:
+   case STATE_LIGHT_POSITION_ARRAY:
    case STATE_LIGHT_POSITION_NORMALIZED:
+   case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
    case STATE_LIGHT_HALF_VECTOR:
       return _NEW_LIGHT_CONSTANTS;
 
@@ -919,6 +955,9 @@ append_token(char *dst, gl_state_index k)
    case STATE_LIGHT_ARRAY:
       append(dst, "light.array");
       break;
+   case STATE_LIGHT_ATTENUATION_ARRAY:
+      append(dst, "light.attenuation");
+      break;
    case STATE_LIGHTMODEL_AMBIENT:
       append(dst, "lightmodel.ambient");
       break;
@@ -1116,11 +1155,17 @@ append_token(char *dst, gl_state_index k)
       append(dst, "lightSpotDirNormalized");
       break;
    case STATE_LIGHT_POSITION:
-      append(dst, "lightPosition");
+      append(dst, "light.position");
+      break;
+   case STATE_LIGHT_POSITION_ARRAY:
+      append(dst, "light.position.array");
       break;
    case STATE_LIGHT_POSITION_NORMALIZED:
       append(dst, "light.position.normalized");
       break;
+   case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
+      append(dst, "light.position.normalized.array");
+      break;
    case STATE_LIGHT_HALF_VECTOR:
       append(dst, "lightHalfVector");
       break;
@@ -1248,6 +1293,7 @@ _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
       }
       break;
    case STATE_LIGHT_ARRAY:
+   case STATE_LIGHT_ATTENUATION_ARRAY:
    case STATE_FRAGMENT_PROGRAM_ENV_ARRAY:
    case STATE_FRAGMENT_PROGRAM_LOCAL_ARRAY:
    case STATE_VERTEX_PROGRAM_ENV_ARRAY:
@@ -1255,6 +1301,8 @@ _mesa_program_state_string(const gl_state_index16 state[STATE_LENGTH])
    case STATE_LIGHTPROD_ARRAY_FRONT:
    case STATE_LIGHTPROD_ARRAY_BACK:
    case STATE_LIGHTPROD_ARRAY_TWOSIDE:
+   case STATE_LIGHT_POSITION_ARRAY:
+   case STATE_LIGHT_POSITION_NORMALIZED_ARRAY:
       sprintf(tmp, "[%d..%d]", state[1], state[1] + state[2] - 1);
       append(str, tmp);
       break;
@@ -1460,6 +1508,40 @@ _mesa_optimize_state_parameters(struct gl_constants *consts,
                list->Parameters[first_param].ValueOffset;
 
             param_diff = last_param - first_param;
+            break; /* all done */
+         }
+
+         /* We were not able to convert light attributes to STATE_LIGHT_ARRAY.
+          * Another occuring pattern is light attentuation vectors placed back
+          * to back. Find them.
+          */
+         if (list->Parameters[first_param].StateIndexes[2] == STATE_ATTENUATION) {
+            for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
+               if (list->Parameters[i].StateIndexes[0] == STATE_LIGHT &&
+                   /* Consecutive light: */
+                   list->Parameters[i].StateIndexes[1] ==
+                   list->Parameters[i - 1].StateIndexes[1] + 1 &&
+                   /* Same attribute: */
+                   list->Parameters[i].StateIndexes[2] ==
+                   list->Parameters[i - 1].StateIndexes[2]) {
+                  last_param = i;
+                  continue;
+               }
+               break; /* The adjacent state var is incompatible. */
+            }
+            if (last_param > first_param) {
+               param_diff = last_param - first_param;
+
+               /* Convert the state var to STATE_LIGHT_ATTENUATION_ARRAY. */
+               list->Parameters[first_param].StateIndexes[0] =
+                  STATE_LIGHT_ATTENUATION_ARRAY;
+               /* Keep the light index the same. */
+               /* Set the number of lights. */
+               unsigned size = param_diff + 1;
+               list->Parameters[first_param].StateIndexes[2] = size;
+               list->Parameters[first_param].Size = size * 4;
+               break; /* all done */
+            }
          }
          break;
 
@@ -1571,6 +1653,38 @@ _mesa_optimize_state_parameters(struct gl_constants *consts,
          }
          break;
       }
+
+      case STATE_LIGHT_POSITION:
+      case STATE_LIGHT_POSITION_NORMALIZED:
+         if (list->Parameters[first_param].Size != 4)
+            break;
+
+         for (int i = first_param + 1; i < (int)list->NumParameters; i++) {
+            if (list->Parameters[i].StateIndexes[0] ==
+                list->Parameters[i - 1].StateIndexes[0] &&
+                /* Consecutive light: */
+                list->Parameters[i].StateIndexes[1] ==
+                list->Parameters[i - 1].StateIndexes[1] + 1) {
+               last_param = i;
+               continue;
+            }
+            break; /* The adjacent state var is incompatible. */
+         }
+         if (last_param > first_param) {
+            param_diff = last_param - first_param;
+
+            /* Convert the state var to STATE_LIGHT_POSITION_*ARRAY. */
+            STATIC_ASSERT(STATE_LIGHT_POSITION + 1 ==
+                          STATE_LIGHT_POSITION_ARRAY);
+            STATIC_ASSERT(STATE_LIGHT_POSITION_NORMALIZED + 1 ==
+                          STATE_LIGHT_POSITION_NORMALIZED_ARRAY);
+            list->Parameters[first_param].StateIndexes[0]++;
+            /* Keep the light index the same. */
+            unsigned size = param_diff + 1;
+            /* Set the number of lights. */
+            list->Parameters[first_param].StateIndexes[2] = size;
+            list->Parameters[first_param].Size = size * 4;
+         }
       }
 
       if (param_diff) {
index 281696b..4b1c439 100644 (file)
@@ -57,6 +57,7 @@ typedef enum gl_state_index_ {
 
    STATE_LIGHT,         /* One gl_light attribute. */
    STATE_LIGHT_ARRAY, /* Multiple gl_light attributes loaded at once. */
+   STATE_LIGHT_ATTENUATION_ARRAY,
    STATE_LIGHTMODEL_AMBIENT,
    STATE_LIGHTMODEL_SCENECOLOR,
    STATE_LIGHTPROD,
@@ -121,7 +122,9 @@ typedef enum gl_state_index_ {
    STATE_POINT_SIZE_CLAMPED,    /* includes implementation dependent size clamp */
    STATE_LIGHT_SPOT_DIR_NORMALIZED,   /* pre-normalized spot dir */
    STATE_LIGHT_POSITION,              /* object vs eye space */
+   STATE_LIGHT_POSITION_ARRAY,
    STATE_LIGHT_POSITION_NORMALIZED,   /* object vs eye space */
+   STATE_LIGHT_POSITION_NORMALIZED_ARRAY,
    STATE_LIGHT_HALF_VECTOR,           /* object vs eye space */
    STATE_PT_SCALE,              /**< Pixel transfer RGBA scale */
    STATE_PT_BIAS,               /**< Pixel transfer RGBA bias */