diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/shader/prog_parameter.c | 87 |
1 files changed, 57 insertions, 30 deletions
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 676f1722e5a..90118b6294f 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -185,7 +185,6 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, size = 4; /** XXX fix */ return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, size, values, NULL); - } @@ -205,18 +204,44 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, GLuint *swizzleOut) { GLint pos; - GLuint swizzle; ASSERT(size >= 1); ASSERT(size <= 4); - size = 4; /* XXX temporary */ - /* check if we already have this constant */ + if (_mesa_lookup_parameter_constant(paramList, values, - size, &pos, &swizzle)) { + size, &pos, swizzleOut)) { return pos; } - return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, - size, values, NULL); - + + /* Look for empty space in an already unnamed constant parameter + * to add this constant. This will only work for single-element + * constants because we rely on smearing (i.e. .yyyy or .zzzz). + */ + if (size == 1) { + for (pos = 0; pos < paramList->NumParameters; pos++) { + struct gl_program_parameter *p = paramList->Parameters + pos; + if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { + /* ok, found room */ + GLfloat *pVal = paramList->ParameterValues[pos]; + GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */ + pVal[p->Size] = values[0]; + p->Size++; + *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz); + return pos; + } + } + } + + /* add a new parameter to store this constant */ + pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, + size, values, NULL); + if (pos >= 0) { + if (size == 1) + *swizzleOut = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, + SWIZZLE_X, SWIZZLE_X); + else + *swizzleOut = SWIZZLE_NOOP; + } + return pos; } @@ -433,7 +458,7 @@ _mesa_lookup_parameter_index(const 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 list 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 @@ -442,7 +467,7 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, * \return GL_TRUE if found, GL_FALSE if not found */ GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, const GLfloat v[], GLsizei vSize, GLint *posOut, GLuint *swizzleOut) { @@ -451,32 +476,34 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramLis assert(vSize >= 1); assert(vSize <= 4); - if (!paramList) + if (!list) 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 (i = 0; i < list->NumParameters; i++) { + if (list->Parameters[i].Type == PROGRAM_CONSTANT) { + if (vSize == 1) { + /* look for v[0] anywhere within float[4] value */ + GLuint j; + for (j = 0; j < 4; j++) { + if (list->ParameterValues[i][j] == v[0]) { + /* found it */ + *posOut = i; + *swizzleOut = MAKE_SWIZZLE4(j, j, j, j); + return GL_TRUE; + } + } + } + else if (list->Parameters[i].Size >= vSize) { + /* see if we can match this constant */ + GLuint match = 0, j; for (j = 0; j < vSize; j++) { - assert(shift + j < 4); - if (paramList->ParameterValues[i][shift + j] == v[j]) { - matched++; - swizzle[j] = shift + j; - ASSERT(swizzle[j] >= SWIZZLE_X); - ASSERT(swizzle[j] <= SWIZZLE_W); + if (list->ParameterValues[i][j] == v[j]) { + match++; } } - if (matched == vSize) { - /* found! */ + if (match == vSize) { *posOut = i; - *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1], - swizzle[2], swizzle[3]); + *swizzleOut = SWIZZLE_NOOP; return GL_TRUE; } } |