/**
- * Helper for update_arrays().
- * \return min(current min, array->_MaxElement).
+ * Helper for _mesa_update_array_object_max_element().
+ * \return min(arrayObj->VertexAttrib[*]._MaxElement).
*/
static GLuint
-update_min(GLuint min, struct gl_client_array *array)
+compute_max_element(struct gl_array_object *arrayObj, GLbitfield64 enabled)
{
- assert(array->Enabled);
- _mesa_update_array_max_element(array);
- return MIN2(min, array->_MaxElement);
+ GLuint min = ~((GLuint)0);
+
+ while (enabled) {
+ struct gl_client_array *client_array;
+ GLint attrib = ffsll(enabled) - 1;
+ enabled ^= BITFIELD64_BIT(attrib);
+
+ client_array = &arrayObj->VertexAttrib[attrib];
+ assert(client_array->Enabled);
+ _mesa_update_array_max_element(client_array);
+ min = MIN2(min, client_array->_MaxElement);
+ }
+
+ return min;
}
_mesa_update_array_object_max_element(struct gl_context *ctx,
struct gl_array_object *arrayObj)
{
- GLbitfield64 enabled = arrayObj->_Enabled;
- GLuint min = ~0u;
-
- while (enabled) {
- GLint attrib = ffsll(enabled) - 1;
- enabled &= ~BITFIELD64_BIT(attrib);
- min = update_min(min, &arrayObj->VertexAttrib[attrib]);
+ GLbitfield64 enabled;
+
+ if (!ctx->VertexProgram._Current ||
+ ctx->VertexProgram._Current == ctx->VertexProgram._TnlProgram) {
+ enabled = _mesa_array_object_get_enabled_ff(arrayObj);
+ } else if (ctx->VertexProgram._Current->IsNVProgram) {
+ enabled = _mesa_array_object_get_enabled_nv(arrayObj);
+ } else {
+ enabled = _mesa_array_object_get_enabled_arb(arrayObj);
}
/* _MaxElement is one past the last legal array element */
- arrayObj->_MaxElement = min;
+ arrayObj->_MaxElement = compute_max_element(arrayObj, enabled);
}
}
-/**
- * Helper for update_arrays().
- * \return min(current min, array->_MaxElement).
- */
-static GLuint
-update_min(GLuint min, struct gl_client_array *array)
-{
- _mesa_update_array_max_element(array);
- return MIN2(min, array->_MaxElement);
-}
-
-
-/**
- * Update ctx->Array._MaxElement (the max legal index into all enabled arrays).
- * Need to do this upon new array state or new buffer object state.
- */
-static void
-update_arrays( struct gl_context *ctx )
-{
- struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
- GLuint i, min = ~0;
-
- /* find min of _MaxElement values for all enabled arrays.
- * Note that the generic arrays always take precedence over
- * the legacy arrays.
- */
-
- /* 0 */
- if (ctx->VertexProgram._Current
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
- }
-
- /* 1 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC1]);
- }
- /* no conventional vertex weight array */
-
- /* 2 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC2]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
- }
-
- /* 3 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC3]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
- }
-
- /* 4 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC4]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1]);
- }
-
- /* 5 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC5]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_FOG]);
- }
-
- /* 6 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC6]);
- }
- else if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]);
- }
-
- /* 7 */
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC7]);
- }
-
- /* 8..15 */
- for (i = 0; i < VERT_ATTRIB_TEX_MAX; i++) {
- if (ctx->VertexProgram._Enabled
- && arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC8 + i]);
- }
- else if (i < ctx->Const.MaxTextureCoordUnits
- && arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]);
- }
- }
-
- /* 16..31 */
- if (ctx->VertexProgram._Current) {
- for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
- if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
- }
- }
- }
-
- if (arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
- min = update_min(min, &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG]);
- }
-
- /* _MaxElement is one past the last legal array element */
- arrayObj->_MaxElement = min;
-}
-
-
/**
* Update the following fields:
* ctx->VertexProgram._Enabled
}
if (new_state & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT))
- update_arrays( ctx );
+ _mesa_update_array_object_max_element(ctx, ctx->Array.ArrayObj);
out:
new_prog_state |= update_program_constants(ctx);