diff options
-rw-r--r-- | src/mesa/vbo/vbo_save.h | 1 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_api.c | 14 | ||||
-rw-r--r-- | src/mesa/vbo/vbo_save_draw.c | 94 |
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. */ |