In _mesa_add_unnamed_constant() and _mesa_lookup_parameter_constant() allow swizzleOut==NULL.

There are times when we don't want to allow swizzling when searching for or
adding vector constants.  Passing NULL for swizzleOut disables swizzling.
This fixes a constant/swizzle bug in link_uniform_vars().
This commit is contained in:
Brian
2007-03-22 09:07:27 -06:00
parent 1936b25ebd
commit 1bf81e3c5d
3 changed files with 61 additions and 43 deletions

View File

@@ -1040,7 +1040,7 @@ Parse_VectorSrc(struct parse_state *parseState,
if (!Parse_ScalarConstant(parseState, values)) if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR; RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, &swizzle); values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP); ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM; srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex; srcReg->Index = paramIndex;
@@ -1053,7 +1053,7 @@ Parse_VectorSrc(struct parse_state *parseState,
if (!Parse_VectorConstant(parseState, values)) if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR; RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, &swizzle); values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP); ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM; srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex; srcReg->Index = paramIndex;
@@ -1145,7 +1145,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
if (!Parse_VectorConstant(parseState, values)) if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR; RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, &swizzle); values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP); ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->File = PROGRAM_NAMED_PARAM; srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex; srcReg->Index = paramIndex;
@@ -1171,7 +1171,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
if (!Parse_ScalarConstant(parseState, values)) if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR; RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
values, 4, &swizzle); values, 4, NULL);
ASSERT(swizzle == SWIZZLE_NOOP); ASSERT(swizzle == SWIZZLE_NOOP);
srcReg->Index = paramIndex; srcReg->Index = paramIndex;
srcReg->File = PROGRAM_NAMED_PARAM; srcReg->File = PROGRAM_NAMED_PARAM;

View File

@@ -192,9 +192,12 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList,
/** /**
* Add a new unnamed constant to the parameter list. * Add a new unnamed constant to the parameter list. This will be used
* This will be used when the program contains something like this: * when a fragment/vertex program contains something like this:
* MOV r, { 0, 1, 2, 3 }; * MOV r, { 0, 1, 2, 3 };
* We'll search the parameter list for an existing instance of the
* constant. If swizzleOut is non-null, we'll try swizzling when
* looking for a match.
* *
* \param paramList the parameter list * \param paramList the parameter list
* \param values four float values * \param values four float values
@@ -219,7 +222,7 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
* to add this constant. This will only work for single-element * to add this constant. This will only work for single-element
* constants because we rely on smearing (i.e. .yyyy or .zzzz). * constants because we rely on smearing (i.e. .yyyy or .zzzz).
*/ */
if (size == 1) { if (size == 1 && swizzleOut) {
for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
struct gl_program_parameter *p = paramList->Parameters + pos; struct gl_program_parameter *p = paramList->Parameters + pos;
if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
@@ -237,10 +240,9 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
/* add a new parameter to store this constant */ /* add a new parameter to store this constant */
pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
size, values, NULL); size, values, NULL);
if (pos >= 0) { if (pos >= 0 && swizzleOut) {
if (size == 1) if (size == 1)
*swizzleOut = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, *swizzleOut = SWIZZLE_XXXX;
SWIZZLE_X, SWIZZLE_X);
else else
*swizzleOut = SWIZZLE_NOOP; *swizzleOut = SWIZZLE_NOOP;
} }
@@ -460,13 +462,14 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
/** /**
* Look for a float vector in the given parameter list. The float vector * Look for a float vector in the given parameter list. The float vector
* may be of length 1, 2, 3 or 4. * may be of length 1, 2, 3 or 4. If swizzleOut is non-null, we'll try
* swizzling to find a match.
* \param list the parameter list to search * \param list the parameter list to search
* \param v the float vector to search for * \param v the float vector to search for
* \param size number of element in v * \param size number of element in v
* \param posOut returns the position of the constant, if found * \param posOut returns the position of the constant, if found
* \param swizzleOut returns a swizzle mask describing location of the * \param swizzleOut returns a swizzle mask describing location of the
* vector elements if found * vector elements if found.
* \return GL_TRUE if found, GL_FALSE if not found * \return GL_TRUE if found, GL_FALSE if not found
*/ */
GLboolean GLboolean
@@ -484,43 +487,58 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
for (i = 0; i < list->NumParameters; i++) { for (i = 0; i < list->NumParameters; i++) {
if (list->Parameters[i].Type == PROGRAM_CONSTANT) { if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
if (vSize == 1) { if (!swizzleOut) {
/* look for v[0] anywhere within float[4] value */ /* swizzle not allowed */
GLuint j; GLuint j, match = 0;
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 (vSize <= list->Parameters[i].Size) {
/* see if we can match this constant (with a swizzle) */
GLuint swz[4];
GLuint match = 0, j, k;
for (j = 0; j < vSize; j++) { for (j = 0; j < vSize; j++) {
if (v[j] == list->ParameterValues[i][j]) { if (v[j] == list->ParameterValues[i][j])
swz[j] = j;
match++; match++;
}
else {
for (k = 0; k < list->Parameters[i].Size; k++) {
if (v[j] == list->ParameterValues[i][k]) {
swz[j] = k;
match++;
break;
}
}
}
} }
if (match == vSize) { if (match == vSize) {
*posOut = i; *posOut = i;
*swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
return GL_TRUE; return GL_TRUE;
} }
} }
else {
/* try matching w/ swizzle */
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 (vSize <= list->Parameters[i].Size) {
/* see if we can match this constant (with a swizzle) */
GLuint swz[4];
GLuint match = 0, j, k;
for (j = 0; j < vSize; j++) {
if (v[j] == list->ParameterValues[i][j]) {
swz[j] = j;
match++;
}
else {
for (k = 0; k < list->Parameters[i].Size; k++) {
if (v[j] == list->ParameterValues[i][k]) {
swz[j] = k;
match++;
break;
}
}
}
}
if (match == vSize) {
*posOut = i;
*swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
return GL_TRUE;
}
}
}
} }
} }

View File

@@ -172,10 +172,10 @@ link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog)
j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name); j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name);
} }
else { else {
GLuint swizzle; /*GLuint swizzle;*/
ASSERT(p->Type == PROGRAM_CONSTANT); ASSERT(p->Type == PROGRAM_CONSTANT);
if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals, if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals,
p->Size, &j, &swizzle)) { p->Size, &j, NULL)) {
assert(j >= 0); assert(j >= 0);
} }
else { else {