vbo: Remove the VBO_SAVE_FALLBACK flag.
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index 47ee355e7254d36175329cc7aec6509e99fc5098..975ba46c8e65b27cfe5a354c2a83abc7126fa536 100644 (file)
@@ -75,7 +75,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/enums.h"
 #include "main/eval.h"
 #include "main/macros.h"
-#include "main/api_validate.h"
+#include "main/draw_validate.h"
 #include "main/api_arrayelt.h"
 #include "main/vtxfmt.h"
 #include "main/dispatch.h"
@@ -492,8 +492,14 @@ update_vao(struct gl_context *ctx,
    _mesa_reference_vao(ctx, vao, NULL);
    *vao = _mesa_new_vao(ctx, ~((GLuint)0));
 
+   /*
+    * assert(stride <= ctx->Const.MaxVertexAttribStride);
+    * MaxVertexAttribStride is not set for drivers that does not
+    * expose GL 44 or GLES 31.
+    */
+
    /* Bind the buffer object at binding point 0 */
-   _mesa_bind_vertex_buffer(ctx, *vao, 0, bo, buffer_offset, stride, false);
+   _mesa_bind_vertex_buffer(ctx, *vao, 0, bo, buffer_offset, stride);
 
    /* Retrieve the mapping from VBO_ATTRIB to VERT_ATTRIB space
     * Note that the position/generic0 aliasing is done in the VAO.
@@ -504,11 +510,12 @@ update_vao(struct gl_context *ctx,
    while (mask) {
       const int vao_attr = u_bit_scan(&mask);
       const GLubyte vbo_attr = vao_to_vbo_map[vao_attr];
+      assert(offset[vbo_attr] <= ctx->Const.MaxVertexAttribRelativeOffset);
 
       _vbo_set_attrib_format(ctx, *vao, vao_attr, buffer_offset,
                              size[vbo_attr], type[vbo_attr], offset[vbo_attr]);
-      _mesa_vertex_attrib_binding(ctx, *vao, vao_attr, 0, false);
-      _mesa_enable_vertex_array_attrib(ctx, *vao, vao_attr, false);
+      _mesa_vertex_attrib_binding(ctx, *vao, vao_attr, 0);
+      _mesa_enable_vertex_array_attrib(ctx, *vao, vao_attr);
    }
    assert(vao_enabled == (*vao)->_Enabled);
    assert((vao_enabled & ~(*vao)->VertexAttribBufferMask) == 0);
@@ -542,11 +549,18 @@ compile_vertex_list(struct gl_context *ctx)
 
    /* Duplicate our template, increment refcounts to the storage structs:
     */
+   GLintptr old_offset = 0;
+   if (save->VAO[0]) {
+      old_offset = save->VAO[0]->BufferBinding[0].Offset
+         + save->VAO[0]->VertexAttrib[VERT_ATTRIB_POS].RelativeOffset;
+   }
    const GLsizei stride = save->vertex_size*sizeof(GLfloat);
    GLintptr buffer_offset =
        (save->buffer_map - save->vertex_store->buffer_map) * sizeof(GLfloat);
+   assert(old_offset <= buffer_offset);
+   const GLintptr offset_diff = buffer_offset - old_offset;
    GLuint start_offset = 0;
-   if (0 < buffer_offset && 0 < stride && buffer_offset % stride == 0) {
+   if (offset_diff > 0 && stride > 0 && offset_diff % stride == 0) {
       /* The vertex size is an exact multiple of the buffer offset.
        * This means that we can use zero-based vertex attribute pointers
        * and specify the start of the primitive with the _mesa_prim::start
@@ -558,8 +572,9 @@ compile_vertex_list(struct gl_context *ctx)
       /* We cannot immediately update the primitives as some methods below
        * still need the uncorrected start vertices
        */
-      start_offset = buffer_offset/stride;
-      buffer_offset = 0;
+      start_offset = offset_diff/stride;
+      assert(old_offset == buffer_offset - offset_diff);
+      buffer_offset = old_offset;
    }
    GLuint offsets[VBO_ATTRIB_MAX];
    for (unsigned i = 0, offset = 0; i < VBO_ATTRIB_MAX; ++i) {
@@ -666,6 +681,9 @@ compile_vertex_list(struct gl_context *ctx)
        */
       free_vertex_store(ctx, save->vertex_store);
       save->vertex_store = NULL;
+      /* When we have a new vbo, we will for sure need a new vao */
+      for (gl_vertex_processing_mode vpm = 0; vpm < VP_MODE_MAX; ++vpm)
+         _mesa_reference_vao(ctx, &save->VAO[vpm], NULL);
 
       /* Allocate and map new store:
        */
@@ -773,9 +791,12 @@ copy_to_current(struct gl_context *ctx)
       const int i = u_bit_scan64(&enabled);
       assert(save->attrsz[i]);
 
-      save->currentsz[i][0] = save->attrsz[i];
-      COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
-                                  save->attrptr[i], save->attrtype[i]);
+      if (save->attrtype[i] == GL_DOUBLE ||
+          save->attrtype[i] == GL_UNSIGNED_INT64_ARB)
+         memcpy(save->current[i], save->attrptr[i], save->attrsz[i] * sizeof(GLfloat));
+      else
+         COPY_CLEAN_4V_TYPE_AS_UNION(save->current[i], save->attrsz[i],
+                                     save->attrptr[i], save->attrtype[i]);
    }
 }
 
@@ -917,11 +938,13 @@ upgrade_vertex(struct gl_context *ctx, GLuint attr, GLuint newsz)
  * get a glTexCoord4f() or glTexCoord1f() call.
  */
 static void
-fixup_vertex(struct gl_context *ctx, GLuint attr, GLuint sz)
+fixup_vertex(struct gl_context *ctx, GLuint attr,
+             GLuint sz, GLenum newType)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
-   if (sz > save->attrsz[attr]) {
+   if (sz > save->attrsz[attr] ||
+       newType != save->attrtype[attr]) {
       /* New size is larger.  Need to flush existing vertices and get
        * an enlarged vertex format.
        */
@@ -976,9 +999,10 @@ reset_vertex(struct gl_context *ctx)
 #define ATTR_UNION(A, N, T, C, V0, V1, V2, V3)                 \
 do {                                                           \
    struct vbo_save_context *save = &vbo_context(ctx)->save;    \
+   int sz = (sizeof(C) / sizeof(GLfloat));                     \
                                                                \
    if (save->active_sz[A] != N)                                        \
-      fixup_vertex(ctx, A, N);                                 \
+      fixup_vertex(ctx, A, N * sz, T);                         \
                                                                \
    {                                                           \
       C *dest = (C *)save->attrptr[A];                          \
@@ -1780,12 +1804,8 @@ vbo_save_EndCallList(struct gl_context *ctx)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
 
-   if (ctx->ListState.CallDepth == 1) {
-      /* This is correct: want to keep only the VBO_SAVE_FALLBACK
-       * flag, if it is set:
-       */
-      save->replay_flags &= VBO_SAVE_FALLBACK;
-   }
+   if (ctx->ListState.CallDepth == 1)
+      save->replay_flags = 0;
 }