* we take up with our state tokens or constants. Note that
* this is _not_ the same as the number of param registers
* we eventually use */
+ GLuint swizzle; /**< swizzle to access this variable */
struct var_cache *next;
};
(**va).param_binding_begin = ~0;
(**va).param_binding_length = ~0;
(**va).alias_binding = NULL;
+ (**va).swizzle = SWIZZLE_XYZW;
(**va).next = NULL;
}
}
* This picks out a constant value from the parsed array. The constant vector is r
* returned in the *values array, which should be of length 4.
*
- * \param values - The 4 component vector with the constant value in it
+ * \param values - return the vector constant values.
+ * \param size - returns the number elements in valuesOut [1..4]
*/
static GLvoid
-parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Program,
- GLboolean use)
+parse_constant(const GLubyte ** inst, GLfloat *values, GLint *size,
+ struct arb_program *Program,
+ GLboolean use)
{
GLuint components, i;
-
switch (*(*inst)++) {
case CONSTANT_SCALAR:
if (use == GL_TRUE) {
values[1] =
values[2] = values[3] = parse_signed_float (inst, Program);
}
-
+ *size = 1;
break;
case CONSTANT_VECTOR:
values[0] = values[1] = values[2] = 0;
for (i = 0; i < components; i++) {
values[i] = parse_signed_float (inst, Program);
}
+ *size = 4;
break;
+ default:
+ _mesa_problem(NULL, "unexpected case in parse_constant()");
+ values[0] = 0.0F;
+ *size = 0;
}
}
GLint idx;
GLuint err = 0;
gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
- GLfloat const_values[4];
GLubyte token = *(*inst)++;
case PARAM_CONSTANT:
/* parsing something like {1.0, 2.0, 3.0, 4.0} */
- parse_constant (inst, const_values, Program, use);
- idx = _mesa_add_named_constant(Program->Base.Parameters,
- (char *) param_var->name,
- const_values, 4);
- if (param_var->param_binding_begin == ~0U)
- param_var->param_binding_begin = idx;
- param_var->param_binding_type = PROGRAM_STATE_VAR;
- /* Note: when we reference this parameter in an instruction later,
- * we'll check if it's really a constant/immediate and set the
- * instruction register type appropriately.
- */
- param_var->param_binding_length++;
+ {
+ GLfloat const_values[4];
+ GLint size;
+ parse_constant(inst, const_values, &size, Program, use);
+ if (param_var->name[0] == ' ') {
+ /* this is an unnamed constant */
+ idx = _mesa_add_unnamed_constant(Program->Base.Parameters,
+ const_values, size,
+ ¶m_var->swizzle);
+ }
+ else {
+ /* named parameter/constant */
+ idx = _mesa_add_named_constant(Program->Base.Parameters,
+ (char *) param_var->name,
+ const_values, size);
+ }
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+ /* Note: when we reference this parameter in an instruction later,
+ * we'll check if it's really a constant/immediate and set the
+ * instruction register type appropriately.
+ */
+ param_var->param_binding_length++;
+ }
break;
default:
return;
}
}
+
+ if (len == 1)
+ swizzle[1] = swizzle[2] = swizzle[3] = swizzle[0];
}
parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
struct var_cache **vc_head,
struct arb_program *Program,
- gl_register_file * File, GLint * Index,
+ gl_register_file * File, GLint * Index, GLuint *swizzle,
GLboolean *IsRelOffset )
{
struct var_cache *src;
*IsRelOffset = 0;
+ *swizzle = SWIZZLE_XYZW; /* default */
+
/* And the binding for the src */
switch (*(*inst)++) {
case REGISTER_ATTRIB:
}
*Index = src->param_binding_begin + offset;
+ *swizzle = src->swizzle;
break;
case ARRAY_INDEX_RELATIVE:
/* And store it properly */
*Index = src->param_binding_begin + rel_off;
*IsRelOffset = 1;
+ *swizzle = src->swizzle;
}
break;
}
*File = (gl_register_file) src->param_binding_type;
*Index = src->param_binding_begin;
+ *swizzle = src->swizzle;
break;
}
break;
}
+static GLuint
+swizzle_swizzle(GLuint baseSwizzle, const GLubyte swizzle[4])
+{
+ GLuint i, swz, s[4];
+ for (i = 0; i < 4; i++) {
+ GLuint c = swizzle[i];
+ if (c <= SWIZZLE_W)
+ s[i] = GET_SWZ(baseSwizzle, c);
+ else
+ s[i] = c;
+ }
+ swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
+ return swz;
+}
+
/**
* Parse vertex/fragment program vector source register.
*/
GLubyte negateMask;
GLubyte swizzle[4];
GLboolean isRelOffset;
+ GLuint baseSwizzle;
/* Grab the sign */
negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
/* And the src reg */
- if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
+ if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
+ &isRelOffset))
return 1;
/* finally, the swizzle */
reg->File = file;
reg->Index = index;
- reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
+ reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
reg->Negate = negateMask;
reg->RelAddr = isRelOffset;
return 0;
GLubyte negateMask;
GLubyte swizzle[4];
GLboolean isRelOffset;
+ GLuint baseSwizzle;
/* Grab the sign */
negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
/* And the src reg */
- if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
+ if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
+ &isRelOffset))
return 1;
/* finally, the swizzle */
reg->File = file;
reg->Index = index;
- reg->Swizzle = (swizzle[0] << 0);
+ reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
reg->Negate = negateMask;
reg->RelAddr = isRelOffset;
return 0;
GLubyte negateMask;
gl_register_file file;
GLint index;
+ GLuint baseSwizzle;
- if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel))
+ if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
+ &baseSwizzle, &rel))
return 1;
parse_extended_swizzle_mask(inst, swizzle, &negateMask);
fp->SrcReg[0].File = file;
GLboolean relAddr;
gl_register_file file;
GLint index;
+ GLuint baseSwizzle;
if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
return 1;
- if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr))
+ if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
+ &baseSwizzle, &relAddr))
return 1;
parse_extended_swizzle_mask (inst, swizzle, &negateMask);
vp->SrcReg[0].File = file;