- struct vbo_context *vbo = vbo_context(ctx);
- struct vbo_save_context *save = &vbo->save;
- struct gl_vertex_array *arrays = save->arrays;
- GLuint buffer_offset = node->buffer_offset;
- const GLuint *map;
- GLuint attr;
- GLubyte node_attrsz[VBO_ATTRIB_MAX]; /* copy of node->attrsz[] */
- GLenum node_attrtype[VBO_ATTRIB_MAX]; /* copy of node->attrtype[] */
- GLbitfield64 varying_inputs = 0x0;
-
- memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
- memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype));
-
- /* Install the default (ie Current) attributes first, then overlay
- * all active ones.
- */
- switch (get_program_mode(ctx)) {
- case VP_NONE:
- for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
- save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr];
- }
- for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
- save->inputs[VERT_ATTRIB_GENERIC(attr)] =
- &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr];
- }
- map = vbo->map_vp_none;
- break;
- case VP_ARB:
- for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
- save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr];
- }
- for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) {
- save->inputs[VERT_ATTRIB_GENERIC(attr)] =
- &vbo->currval[VBO_ATTRIB_GENERIC0+attr];
- }
- map = vbo->map_vp_arb;
-
- /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
- * In that case we effectively need to route the data from
- * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
- */
- if ((ctx->VertexProgram._Current->info.inputs_read &
- VERT_BIT_POS) == 0 &&
- (ctx->VertexProgram._Current->info.inputs_read &
- VERT_BIT_GENERIC0)) {
- save->inputs[VERT_ATTRIB_GENERIC0] = save->inputs[0];
- node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0];
- node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0];
- node_attrsz[0] = 0;
- }
- break;
- default:
- assert(0);
- }
-
- for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
- const GLuint src = map[attr];
-
- if (node_attrsz[src]) {
- /* override the default array set above */
- save->inputs[attr] = &arrays[attr];
-
- arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset;
- arrays[attr].Size = node_attrsz[src];
- arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
- arrays[attr].Type = node_attrtype[src];
- arrays[attr].Integer =
- vbo_attrtype_to_integer_flag(node_attrtype[src]);
- arrays[attr].Format = GL_RGBA;
- arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
- _mesa_reference_buffer_object(ctx,
- &arrays[attr].BufferObj,
- node->vertex_store->bufferobj);
-
- assert(arrays[attr].BufferObj->Name);
-
- buffer_offset += node_attrsz[src] * sizeof(GLfloat);
- varying_inputs |= VERT_BIT(attr);
- }
- }
-
- _mesa_set_varying_vp_inputs( ctx, varying_inputs );
- ctx->NewDriverState |= ctx->DriverFlags.NewArray;