fix memory access error in vbo_bind_vertex_list
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index 8ceba2b832b6ad566b5d6a08f060fb4a5528fa47..f62be5c14cf4bb7960354998c52fb164861fa072 100644 (file)
@@ -67,19 +67,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
-#include "glheader.h"
-#include "context.h"
-#include "dlist.h"
-#include "enums.h"
-#include "macros.h"
-#include "api_validate.h"
-#include "api_arrayelt.h"
-#include "vtxfmt.h"
-#include "dispatch.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dlist.h"
+#include "main/enums.h"
+#include "main/macros.h"
+#include "main/api_validate.h"
+#include "main/api_arrayelt.h"
+#include "main/vtxfmt.h"
+#include "glapi/dispatch.h"
 
 #include "vbo_context.h"
 
 
+#ifdef ERROR
+#undef ERROR
+#endif
+
 
 /*
  * NOTE: Old 'parity' issue is gone, but copying can still be
@@ -198,7 +202,7 @@ static GLfloat *map_vertex_store( GLcontext *ctx, struct vbo_save_vertex_store *
    assert(!vertex_store->buffer);
    vertex_store->buffer = (GLfloat *)ctx->Driver.MapBuffer(ctx, 
                                                           GL_ARRAY_BUFFER_ARB, /* not used */
-                                                          GL_STATIC_DRAW_ARB, /* not used */
+                                                          GL_WRITE_ONLY, /* not used */
                                                           vertex_store->bufferobj); 
 
    assert(vertex_store->buffer);
@@ -415,26 +419,14 @@ static void _save_copy_to_current( GLcontext *ctx )
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
    GLuint i;
 
-   for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) {
+   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       if (save->attrsz[i]) {
         save->currentsz[i][0] = save->attrsz[i];
         COPY_CLEAN_4V(save->current[i], 
-                   save->attrsz[i], 
-                   save->attrptr[i]);
+                      save->attrsz[i], 
+                      save->attrptr[i]);
       }
    }
-
-   /* Edgeflag requires special treatment: 
-    *
-    * TODO: change edgeflag to GLfloat in Mesa.
-    */
-   if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) {
-      ctx->ListState.ActiveEdgeFlag = 1;
-      save->CurrentFloatEdgeFlag = 
-        save->attrptr[VBO_ATTRIB_EDGEFLAG][0];
-      ctx->ListState.CurrentEdgeFlag = 
-        (save->CurrentFloatEdgeFlag == 1.0);
-   }
 }
 
 
@@ -443,7 +435,7 @@ static void _save_copy_from_current( GLcontext *ctx )
    struct vbo_save_context *save = &vbo_context(ctx)->save; 
    GLint i;
 
-   for (i = VBO_ATTRIB_POS+1 ; i <= VBO_ATTRIB_INDEX ; i++) 
+   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
       switch (save->attrsz[i]) {
       case 4: save->attrptr[i][3] = save->current[i][3];
       case 3: save->attrptr[i][2] = save->current[i][2];
@@ -451,12 +443,6 @@ static void _save_copy_from_current( GLcontext *ctx )
       case 1: save->attrptr[i][0] = save->current[i][0];
       case 0: break;
       }
-
-   /* Edgeflag requires special treatment:
-    */
-   if (save->attrsz[VBO_ATTRIB_EDGEFLAG]) {
-      save->CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag;
-      save->attrptr[VBO_ATTRIB_EDGEFLAG][0] = save->CurrentFloatEdgeFlag;
    }
 }
 
@@ -527,7 +513,7 @@ static void _save_upgrade_vertex( GLcontext *ctx,
 
       /* Need to note this and fix up at runtime (or loopback):
        */
-      if (save->currentsz[attr][0] == 0) {
+      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
         assert(oldsz == 0);
         save->dangling_attr_ref = GL_TRUE;
       }
@@ -853,10 +839,15 @@ static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei co
    if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
       return;
 
+   _ae_map_vbos( ctx );
+
    vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
+
    for (i = 0; i < count; i++)
        CALL_ArrayElement(GET_DISPATCH(), (start + i));
    CALL_End(GET_DISPATCH(), ());
+
+   _ae_unmap_vbos( ctx );
 }
 
 /* Could do better by copying the arrays and element list intact and
@@ -871,6 +862,11 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
    if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
       return;
 
+   _ae_map_vbos( ctx );
+
+   if (ctx->Array.ElementArrayBufferObj->Name)
+      indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
+
    vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
 
    switch (type) {
@@ -892,6 +888,8 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
    }
 
    CALL_End(GET_DISPATCH(), ());
+
+   _ae_unmap_vbos( ctx );
 }
 
 static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
@@ -1106,23 +1104,19 @@ static void _save_current_init( GLcontext *ctx )
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLint i;
 
-   for (i = 0; i < VBO_ATTRIB_FIRST_MATERIAL; i++) {
-      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[i];
-      save->current[i] = ctx->ListState.CurrentAttrib[i];
+   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
+      const GLuint j = i - VBO_ATTRIB_POS;
+      ASSERT(j < VERT_ATTRIB_MAX);
+      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
+      save->current[i] = ctx->ListState.CurrentAttrib[j];
    }
 
-   for (i = VBO_ATTRIB_FIRST_MATERIAL; i < VBO_ATTRIB_INDEX; i++) {
+   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
       const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
       ASSERT(j < MAT_ATTRIB_MAX);
       save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
       save->current[i] = ctx->ListState.CurrentMaterial[j];
    }
-
-   save->currentsz[VBO_ATTRIB_INDEX] = &ctx->ListState.ActiveIndex;
-   save->current[VBO_ATTRIB_INDEX] = &ctx->ListState.CurrentIndex;
-
-   save->currentsz[VBO_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag;
-   save->current[VBO_ATTRIB_EDGEFLAG] = &save->CurrentFloatEdgeFlag;
 }
 
 /**