Add new _mesa_lookup_parameter_constant() to search for a GLfloat4 constant
authorBrian Paul <brian.paul@tungstengraphics.com>
Wed, 15 Nov 2006 23:19:52 +0000 (23:19 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Wed, 15 Nov 2006 23:19:52 +0000 (23:19 +0000)
in a parameter list.
Use it in _mesa_add_named_constant() and _mesa_add_unnamed_constant() to
avoid duplication of identical constants.

src/mesa/shader/program.c
src/mesa/shader/program.h

index eabfbc2..5c03ad4 100644 (file)
@@ -430,14 +430,20 @@ _mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
  * This will be used when the program contains something like this:
  *    PARAM myVals = { 0, 1, 2, 3 };
  *
- * \param paramList - the parameter list
- * \param values - four float values
- * \return index of the new parameter.
+ * \param paramList  the parameter list
+ * \param name  the name for the constant
+ * \param values  four float values
+ * \return index/position of the new parameter in the parameter list
  */
 GLint
 _mesa_add_named_constant(struct gl_program_parameter_list *paramList,
                          const char *name, const GLfloat values[4])
 {
+   GLuint pos, swizzle;
+   /* check if we already have this constant */
+   if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
+      return pos;
+   }
    return add_parameter(paramList, name, values, PROGRAM_CONSTANT);
 }
 
@@ -447,14 +453,19 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList,
  * This will be used when the program contains something like this:
  *    MOV r, { 0, 1, 2, 3 };
  *
- * \param paramList - the parameter list
- * \param values - four float values
- * \return index of the new parameter.
+ * \param paramList  the parameter list
+ * \param values  four float values
+ * \return index/position of the new parameter in the parameter list.
  */
 GLint
 _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
                            const GLfloat values[4])
 {
+   GLuint pos, swizzle;
+   /* check if we already have this constant */
+   if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) {
+      return pos;
+   }
    return add_parameter(paramList, NULL, values, PROGRAM_CONSTANT);
 }
 
@@ -464,8 +475,8 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
  * This will be used when the program contains something like this:
  *    PARAM ambient = state.material.front.ambient;
  *
- * \param paramList - the parameter list
- * \param state     - an array of 6 state tokens
+ * \param paramList  the parameter list
+ * \param state  an array of 6 state tokens
  * \return index of the new parameter.
  */
 GLint
@@ -500,7 +511,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
  * \return pointer to the float[4] values.
  */
 GLfloat *
-_mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList,
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
                              GLsizei nameLen, const char *name)
 {
    GLuint i;
@@ -530,11 +541,15 @@ _mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList,
 
 
 /**
- * Lookup a parameter index by name in the given parameter list.
+ * Given a program parameter name, find its position in the list of parameters.
+ * \param paramList  the parameter list to search
+ * \param nameLen  length of name (in chars).
+ *                 If length is negative, assume that name is null-terminated.
+ * \param name  the name to search for
  * \return index of parameter in the list.
  */
 GLint
-_mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList,
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
                              GLsizei nameLen, const char *name)
 {
    GLint i;
@@ -564,6 +579,61 @@ _mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList,
 
 
 /**
+ * Look for a float vector in the given parameter list.  The float vector
+ * may be of length 1, 2, 3 or 4.
+ * \param paramList  the parameter list to search
+ * \param v  the float vector to search for
+ * \param size  number of element in v
+ * \param posOut  returns the position of the constant, if found
+ * \param swizzleOut  returns a swizzle mask describing location of the
+ *                    vector elements if found
+ * \return GL_TRUE if found, GL_FALSE if not found
+ */
+GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList,
+                                const GLfloat v[], GLsizei vSize,
+                                GLuint *posOut, GLuint *swizzleOut)
+{
+   GLuint i;
+
+   assert(vSize >= 1);
+   assert(vSize <= 4);
+
+   if (!paramList)
+      return -1;
+
+   for (i = 0; i < paramList->NumParameters; i++) {
+      if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) {
+         const GLint maxShift = 4 - vSize;
+         GLint shift, j;
+         for (shift = 0; shift <= maxShift; shift++) {
+            GLint matched = 0;
+            GLuint swizzle[4];
+            swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0;
+            /* XXX we could do out-of-order swizzle matches too, someday */
+            for (j = 0; j < vSize; j++) {
+               assert(shift + j < 4);
+               if (paramList->ParameterValues[i][shift + j] == v[j]) {
+                  matched++;
+                  swizzle[j] = shift + j;
+               }
+            }
+            if (matched == vSize) {
+               /* found! */
+               *posOut = i;
+               *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+                                           swizzle[2], swizzle[3]);
+               return GL_TRUE;
+            }
+         }
+      }
+   }
+
+   return GL_FALSE;
+}
+
+
+/**
  * Use the list of tokens in the state[] array to find global GL state
  * and return it in <value>.  Usually, four values are returned in <value>
  * but matrix queries may return as many as 16 values.
index 5095839..3f84ea8 100644 (file)
@@ -249,19 +249,22 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList,
                           const GLint *stateTokens);
 
 extern GLfloat *
-_mesa_lookup_parameter_value(struct gl_program_parameter_list *paramList,
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
                              GLsizei nameLen, const char *name);
 
 extern GLint
-_mesa_lookup_parameter_index(struct gl_program_parameter_list *paramList,
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
                              GLsizei nameLen, const char *name);
 
+extern GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList,
+                                const GLfloat v[], GLsizei vSize,
+                                GLuint *posOut, GLuint *swizzleOut);
+
 extern void
 _mesa_load_state_parameters(GLcontext *ctx,
                             struct gl_program_parameter_list *paramList);
 
-
-
 extern void
 _mesa_print_instruction(const struct prog_instruction *inst);