summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2006-11-15 23:19:52 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2006-11-15 23:19:52 +0000
commit699a33ea77ecd164d7435811258eee96bd37aaa2 (patch)
treefd16030266e9a089dc6042721932ce2bb1bd173d
parent408e01b9394d39ecd7755ca63b36017bbc0521d0 (diff)
Add new _mesa_lookup_parameter_constant() to search for a GLfloat4 constant
in a parameter list. Use it in _mesa_add_named_constant() and _mesa_add_unnamed_constant() to avoid duplication of identical constants.
-rw-r--r--src/mesa/shader/program.c92
-rw-r--r--src/mesa/shader/program.h11
2 files changed, 88 insertions, 15 deletions
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index eabfbc24d7..5c03ad44c2 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -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.
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index 50958394c2..3f84ea8a40 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -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);