mesa: Use _mesa_array_element in dlist save.
[mesa.git] / src / mesa / vbo / vbo_save_api.c
index 9dd9c7d7d22e3c3f971832147f290c0d09761408..6122727bae9bf84453eb5bad34ee646270bf23ae 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"
@@ -426,7 +426,7 @@ compare_vao(gl_vertex_processing_mode mode,
       return false;
 
    /* If the enabled arrays are not the same we are not equal. */
-   if (vao_enabled != vao->_Enabled)
+   if (vao_enabled != vao->Enabled)
       return false;
 
    /* Check the buffer binding at 0 */
@@ -450,15 +450,14 @@ compare_vao(gl_vertex_processing_mode mode,
       const struct gl_array_attributes *attrib = &vao->VertexAttrib[attr];
       if (attrib->RelativeOffset + vao->BufferBinding[0].Offset != off)
          return false;
-      if (attrib->Type != tp)
+      if (attrib->Format.Type != tp)
          return false;
-      if (attrib->Size != size[vbo_attr])
+      if (attrib->Format.Size != size[vbo_attr])
          return false;
-      assert(attrib->Format == GL_RGBA);
-      assert(attrib->Enabled == GL_TRUE);
-      assert(attrib->Normalized == GL_FALSE);
-      assert(attrib->Integer == vbo_attrtype_to_integer_flag(tp));
-      assert(attrib->Doubles == vbo_attrtype_to_double_flag(tp));
+      assert(attrib->Format.Format == GL_RGBA);
+      assert(attrib->Format.Normalized == GL_FALSE);
+      assert(attrib->Format.Integer == vbo_attrtype_to_integer_flag(tp));
+      assert(attrib->Format.Doubles == vbo_attrtype_to_double_flag(tp));
       assert(attrib->BufferBindingIndex == 0);
    }
 
@@ -492,8 +491,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,13 +509,14 @@ 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);
    }
-   assert(vao_enabled == (*vao)->_Enabled);
+   _mesa_enable_vertex_array_attribs(ctx, *vao, vao_enabled);
+   assert(vao_enabled == (*vao)->Enabled);
    assert((vao_enabled & ~(*vao)->VertexAttribBufferMask) == 0);
 
    /* Finalize and freeze the VAO */
@@ -595,7 +601,7 @@ compile_vertex_list(struct gl_context *ctx)
 
    node->prim_store->refcount++;
 
-   if (node->prims[0].no_current_update) {
+   if (save->no_current_update) {
       node->current_data = NULL;
    }
    else {
@@ -713,8 +719,6 @@ wrap_buffers(struct gl_context *ctx)
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    GLint i = save->prim_count - 1;
    GLenum mode;
-   GLboolean weak;
-   GLboolean no_current_update;
 
    assert(i < (GLint) save->prim_max);
    assert(i >= 0);
@@ -723,8 +727,6 @@ wrap_buffers(struct gl_context *ctx)
     */
    save->prims[i].count = (save->vert_count - save->prims[i].start);
    mode = save->prims[i].mode;
-   weak = save->prims[i].weak;
-   no_current_update = save->prims[i].no_current_update;
 
    /* store the copied vertices, and allocate a new list.
     */
@@ -733,8 +735,6 @@ wrap_buffers(struct gl_context *ctx)
    /* Restart interrupted primitive
     */
    save->prims[0].mode = mode;
-   save->prims[0].weak = weak;
-   save->prims[0].no_current_update = no_current_update;
    save->prims[0].begin = 0;
    save->prims[0].end = 0;
    save->prims[0].pad = 0;
@@ -784,9 +784,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]);
    }
 }
 
@@ -928,11 +931,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.
        */
@@ -987,9 +992,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];                          \
@@ -1186,7 +1192,8 @@ _save_CallLists(GLsizei n, GLenum type, const GLvoid * v)
  * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of.
  */
 void
-vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
+vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode,
+                     bool no_current_update)
 {
    struct vbo_save_context *save = &vbo_context(ctx)->save;
    const GLuint i = save->prim_count++;
@@ -1195,9 +1202,6 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
    save->prims[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
    save->prims[i].begin = 1;
    save->prims[i].end = 0;
-   save->prims[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
-   save->prims[i].no_current_update =
-      (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
    save->prims[i].pad = 0;
    save->prims[i].start = save->vert_count;
    save->prims[i].count = 0;
@@ -1205,6 +1209,8 @@ vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
    save->prims[i].base_instance = 0;
    save->prims[i].is_indirect = 0;
 
+   save->no_current_update = no_current_update;
+
    if (save->out_of_memory) {
       _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
    }
@@ -1270,10 +1276,11 @@ _save_PrimitiveRestartNV(void)
    } else {
       /* get current primitive mode */
       GLenum curPrim = save->prims[save->prim_count - 1].mode;
+      bool no_current_update = save->no_current_update;
 
       /* restart primitive */
       CALL_End(GET_DISPATCH(), ());
-      vbo_save_NotifyBegin(ctx, curPrim);
+      vbo_save_NotifyBegin(ctx, curPrim, no_current_update);
    }
 }
 
@@ -1287,7 +1294,7 @@ static void GLAPIENTRY
 _save_OBE_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
 {
    GET_CURRENT_CONTEXT(ctx);
-   vbo_save_NotifyBegin(ctx, GL_QUADS | VBO_SAVE_PRIM_WEAK);
+   vbo_save_NotifyBegin(ctx, GL_QUADS, false);
    CALL_Vertex2f(GET_DISPATCH(), (x1, y1));
    CALL_Vertex2f(GET_DISPATCH(), (x2, y1));
    CALL_Vertex2f(GET_DISPATCH(), (x2, y2));
@@ -1320,11 +1327,10 @@ _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count)
 
    _ae_map_vbos(ctx);
 
-   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK
-                              | VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
+   vbo_save_NotifyBegin(ctx, mode, true);
 
    for (i = 0; i < count; i++)
-      CALL_ArrayElement(GET_DISPATCH(), (start + i));
+      _mesa_array_element(ctx, GET_DISPATCH(), start + i);
    CALL_End(GET_DISPATCH(), ());
 
    _ae_unmap_vbos(ctx);
@@ -1365,6 +1371,21 @@ _save_OBE_MultiDrawArrays(GLenum mode, const GLint *first,
 }
 
 
+static void
+array_element(struct gl_context *ctx, struct _glapi_table *disp, GLuint elt)
+{
+   /* If PrimitiveRestart is enabled and the index is the RestartIndex
+    * then we call PrimitiveRestartNV and return.
+    */
+   if (ctx->Array.PrimitiveRestart && elt == ctx->Array.RestartIndex) {
+      CALL_PrimitiveRestartNV(disp, ());
+      return;
+   }
+
+   _mesa_array_element(ctx, disp, elt);
+}
+
+
 /* Could do better by copying the arrays and element list intact and
  * then emitting an indexed prim at runtime.
  */
@@ -1404,21 +1425,20 @@ _save_OBE_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
       indices =
          ADD_POINTERS(indexbuf->Mappings[MAP_INTERNAL].Pointer, indices);
 
-   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
-                              VBO_SAVE_PRIM_NO_CURRENT_UPDATE));
+   vbo_save_NotifyBegin(ctx, mode, true);
 
    switch (type) {
    case GL_UNSIGNED_BYTE:
       for (i = 0; i < count; i++)
-         CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLubyte *) indices)[i]));
+         array_element(ctx, GET_DISPATCH(), (basevertex + ((GLubyte *) indices)[i]));
       break;
    case GL_UNSIGNED_SHORT:
       for (i = 0; i < count; i++)
-         CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLushort *) indices)[i]));
+         array_element(ctx, GET_DISPATCH(), (basevertex + ((GLushort *) indices)[i]));
       break;
    case GL_UNSIGNED_INT:
       for (i = 0; i < count; i++)
-         CALL_ArrayElement(GET_DISPATCH(), (basevertex + ((GLuint *) indices)[i]));
+         array_element(ctx, GET_DISPATCH(), (basevertex + ((GLuint *) indices)[i]));
       break;
    default:
       _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");
@@ -1791,12 +1811,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;
 }
 
 
@@ -1835,10 +1851,9 @@ vbo_print_vertex_list(struct gl_context *ctx, void *data, FILE *f)
 
    for (i = 0; i < node->prim_count; i++) {
       struct _mesa_prim *prim = &node->prims[i];
-      fprintf(f, "   prim %d: %s%s %d..%d %s %s\n",
+      fprintf(f, "   prim %d: %s %d..%d %s %s\n",
              i,
              _mesa_lookup_prim_by_nr(prim->mode),
-             prim->weak ? " (weak)" : "",
              prim->start,
              prim->start + prim->count,
              (prim->begin) ? "BEGIN" : "(wrap)",