/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 7.2
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
#include "main/glheader.h"
+#include "main/bufferobj.h"
#include "main/context.h"
#include "main/imports.h"
#include "main/mtypes.h"
const struct vbo_save_vertex_list *node )
{
struct vbo_context *vbo = vbo_context(ctx);
- GLfloat vertex[VBO_ATTRIB_MAX * 4], *data = vertex;
+ GLfloat vertex[VBO_ATTRIB_MAX * 4];
+ GLfloat *data;
GLuint i, offset;
- if (node->count)
- offset = (node->buffer_offset +
- (node->count-1) * node->vertex_size * sizeof(GLfloat));
- else
- offset = node->buffer_offset;
+ if (node->current_size == 0)
+ return;
- ctx->Driver.GetBufferSubData( ctx, 0, offset,
- node->vertex_size * sizeof(GLfloat),
- data, node->vertex_store->bufferobj );
+ if (node->current_data) {
+ data = node->current_data;
+ }
+ else {
+ data = vertex;
+
+ if (node->count)
+ offset = (node->buffer_offset +
+ (node->count-1) * node->vertex_size * sizeof(GLfloat));
+ else
+ offset = node->buffer_offset;
- data += node->attrsz[0]; /* skip vertex position */
+ ctx->Driver.GetBufferSubData( ctx, 0, offset,
+ node->vertex_size * sizeof(GLfloat),
+ data, node->vertex_store->bufferobj );
+
+ data += node->attrsz[0]; /* skip vertex position */
+ }
for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
if (node->attrsz[i]) {
GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
+ GLfloat tmp[4];
- COPY_CLEAN_4V(current,
- node->attrsz[i],
- data);
+ COPY_CLEAN_4V(tmp,
+ node->attrsz[i],
+ data);
+
+ if (memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0)
+ {
+ memcpy(current, tmp, 4 * sizeof(GLfloat));
- vbo->currval[i].Size = node->attrsz[i];
+ vbo->currval[i].Size = node->attrsz[i];
- data += node->attrsz[i];
+ if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
+ i <= VBO_ATTRIB_LAST_MATERIAL)
+ ctx->NewState |= _NEW_LIGHT;
- if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
- i <= VBO_ATTRIB_LAST_MATERIAL)
- ctx->NewState |= _NEW_LIGHT;
+ ctx->NewState |= _NEW_CURRENT_ATTRIB;
+ }
+
+ data += node->attrsz[i];
}
}
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_save_context *save = &vbo->save;
struct gl_client_array *arrays = save->arrays;
- GLuint data = node->buffer_offset;
+ GLuint buffer_offset = node->buffer_offset;
const GLuint *map;
GLuint attr;
+ GLubyte node_attrsz[VBO_ATTRIB_MAX]; /* copy of node->attrsz[] */
+ GLbitfield varying_inputs = 0x0;
+
+ memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
/* Install the default (ie Current) attributes first, then overlay
* all active ones.
*/
switch (get_program_mode(ctx)) {
case VP_NONE:
- memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0]));
- memcpy(arrays + 16, vbo->mat_currval, MAT_ATTRIB_MAX * sizeof(arrays[0]));
+ for (attr = 0; attr < 16; attr++) {
+ save->inputs[attr] = &vbo->legacy_currval[attr];
+ }
+ for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
+ save->inputs[attr + 16] = &vbo->mat_currval[attr];
+ }
map = vbo->map_vp_none;
break;
case VP_NV:
* occurred. NV vertex programs cannot access material values,
* nor attributes greater than VERT_ATTRIB_TEX7.
*/
- memcpy(arrays, vbo->legacy_currval, 16 * sizeof(arrays[0]));
- memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
+ for (attr = 0; attr < 16; attr++) {
+ save->inputs[attr] = &vbo->legacy_currval[attr];
+ save->inputs[attr + 16] = &vbo->generic_currval[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->Base.InputsRead & VERT_BIT_POS) == 0 &&
+ (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
+ save->inputs[16] = save->inputs[0];
+ node_attrsz[16] = node_attrsz[0];
+ node_attrsz[0] = 0;
+ }
break;
+ default:
+ assert(0);
}
for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
GLuint src = map[attr];
- if (node->attrsz[src]) {
- arrays[attr].Ptr = (const GLubyte *)data;
+ 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].Stride = node->vertex_size * sizeof(GLfloat);
arrays[attr].Type = GL_FLOAT;
+ arrays[attr].Format = GL_RGBA;
arrays[attr].Enabled = 1;
- arrays[attr].BufferObj = node->vertex_store->bufferobj;
+ _mesa_reference_buffer_object(ctx,
+ &arrays[attr].BufferObj,
+ node->vertex_store->bufferobj);
arrays[attr]._MaxElement = node->count; /* ??? */
assert(arrays[attr].BufferObj->Name);
- data += node->attrsz[src] * sizeof(GLfloat);
+ buffer_offset += node->attrsz[src] * sizeof(GLfloat);
+ varying_inputs |= 1<<attr;
}
}
+
+ _mesa_set_varying_vp_inputs( ctx, varying_inputs );
}
static void vbo_save_loopback_vertex_list( GLcontext *ctx,
vbo_bind_vertex_list( ctx, node );
+ /* Again...
+ */
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
vbo_context(ctx)->draw_prims( ctx,
save->inputs,
node->prim,
node->prim_count,
NULL,
+ GL_TRUE,
0, /* Node is a VBO, so this is ok */
node->count - 1);
}