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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
Reference in New Issue
Block a user