aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mesa/vbo/vbo_save.h1
-rw-r--r--src/mesa/vbo/vbo_save_api.c14
-rw-r--r--src/mesa/vbo/vbo_save_draw.c94
3 files changed, 47 insertions, 62 deletions
diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h
index 44dc8c201f8..00f18363b73 100644
--- a/src/mesa/vbo/vbo_save.h
+++ b/src/mesa/vbo/vbo_save.h
@@ -72,7 +72,6 @@ struct vbo_save_vertex_list {
* map/unmap of the VBO when updating GL current data.
*/
fi_type *current_data;
- GLuint current_size;
GLuint buffer_offset; /**< in bytes */
GLuint start_vertex; /**< first vertex used by any primitive */
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index dc248934f7e..db9a3fbdfae 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -595,18 +595,14 @@ compile_vertex_list(struct gl_context *ctx)
node->prim_store->refcount++;
if (node->prims[0].no_current_update) {
- node->current_size = 0;
node->current_data = NULL;
}
else {
- node->current_size = node->vertex_size - node->attrsz[0];
+ GLuint current_size = node->vertex_size - node->attrsz[0];
node->current_data = NULL;
- if (node->current_size) {
- /* If the malloc fails, we just pull the data out of the VBO
- * later instead.
- */
- node->current_data = malloc(node->current_size * sizeof(GLfloat));
+ if (current_size) {
+ node->current_data = malloc(current_size * sizeof(GLfloat));
if (node->current_data) {
const char *buffer = (const char *) save->vertex_store->buffer_map;
unsigned attr_offset = node->attrsz[0] * sizeof(GLfloat);
@@ -618,7 +614,9 @@ compile_vertex_list(struct gl_context *ctx)
memcpy(node->current_data,
buffer + node->buffer_offset + vertex_offset + attr_offset,
- node->current_size * sizeof(GLfloat));
+ current_size * sizeof(GLfloat));
+ } else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "Current value allocation");
}
}
}
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 0358ecd2f90..b8b6b872c0c 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -42,72 +42,60 @@
#include "vbo_private.h"
-/**
- * After playback, copy everything but the position from the
- * last vertex to the saved state
- */
static void
-playback_copy_to_current(struct gl_context *ctx,
- const struct vbo_save_vertex_list *node)
+copy_vao(struct gl_context *ctx, const struct gl_vertex_array_object *vao,
+ GLbitfield mask, GLbitfield state, int shift, fi_type **data)
{
struct vbo_context *vbo = vbo_context(ctx);
- fi_type vertex[VBO_ATTRIB_MAX * 4];
- fi_type *data;
- GLbitfield64 mask;
-
- if (node->current_size == 0)
- return;
-
- if (node->current_data) {
- data = node->current_data;
- }
- else {
- /* Position of last vertex */
- const GLuint pos = node->vertex_count > 0 ? node->vertex_count - 1 : 0;
- /* Offset to last vertex in the vertex buffer */
- const GLuint offset = node->buffer_offset
- + pos * node->vertex_size * sizeof(GLfloat);
-
- data = vertex;
-
- ctx->Driver.GetBufferSubData(ctx, offset,
- node->vertex_size * sizeof(GLfloat),
- data, node->vertex_store->bufferobj);
-
- data += node->attrsz[0]; /* skip vertex position */
- }
- mask = node->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
+ mask &= vao->_Enabled;
while (mask) {
- const int i = u_bit_scan64(&mask);
- fi_type *current = (fi_type *)vbo->currval[i].Ptr;
+ const int i = u_bit_scan(&mask);
+ const struct gl_array_attributes *attrib = &vao->VertexAttrib[i];
+ struct gl_vertex_array *currval = &vbo->currval[shift + i];
+ const GLubyte size = attrib->Size;
+ const GLenum16 type = attrib->Type;
fi_type tmp[4];
- assert(node->attrsz[i]);
- COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
- node->attrsz[i],
- data,
- node->attrtype[i]);
+ COPY_CLEAN_4V_TYPE_AS_UNION(tmp, size, *data, type);
- if (node->attrtype[i] != vbo->currval[i].Type ||
- memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
- memcpy(current, tmp, 4 * sizeof(GLfloat));
+ if (type != currval->Type ||
+ memcmp(currval->Ptr, tmp, 4 * sizeof(GLfloat)) != 0) {
+ memcpy((fi_type*)currval->Ptr, tmp, 4 * sizeof(GLfloat));
- vbo->currval[i].Size = node->attrsz[i];
- vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
- vbo->currval[i].Type = node->attrtype[i];
- vbo->currval[i].Integer =
- vbo_attrtype_to_integer_flag(node->attrtype[i]);
+ currval->Size = size;
+ currval->_ElementSize = size * sizeof(GLfloat);
+ currval->Type = type;
+ currval->Integer = vbo_attrtype_to_integer_flag(type);
+ currval->Doubles = vbo_attrtype_to_double_flag(type);
+ currval->Normalized = GL_FALSE;
+ currval->Format = GL_RGBA;
- if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
- i <= VBO_ATTRIB_LAST_MATERIAL)
- ctx->NewState |= _NEW_LIGHT;
-
- ctx->NewState |= _NEW_CURRENT_ATTRIB;
+ ctx->NewState |= state;
}
- data += node->attrsz[i];
+ *data += size;
}
+}
+
+/**
+ * After playback, copy everything but the position from the
+ * last vertex to the saved state
+ */
+static void
+playback_copy_to_current(struct gl_context *ctx,
+ const struct vbo_save_vertex_list *node)
+{
+ if (!node->current_data)
+ return;
+
+ fi_type *data = node->current_data;
+ /* Copy conventional attribs and generics except pos */
+ copy_vao(ctx, node->VAO[VP_MODE_SHADER], ~VERT_BIT_POS & VERT_BIT_ALL,
+ _NEW_CURRENT_ATTRIB, 0, &data);
+ /* Copy materials */
+ copy_vao(ctx, node->VAO[VP_MODE_FF], VERT_BIT_MAT_ALL,
+ _NEW_CURRENT_ATTRIB | _NEW_LIGHT, VBO_MATERIAL_SHIFT, &data);
/* Colormaterial -- this kindof sucks.
*/