mesa: avoid redundant VBO updates
[mesa.git] / src / mesa / main / varray.c
index ec5e71917613b12fcf8616c09e2cc7f7f56ff770..71ba518f2d1e2056d2ac9536aaee410124010fb1 100644 (file)
@@ -28,7 +28,7 @@
 #include <inttypes.h>  /* for PRId64 macro */
 
 #include "glheader.h"
-#include "util/imports.h"
+
 #include "bufferobj.h"
 #include "context.h"
 #include "enable.h"
@@ -169,7 +169,7 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx,
    if (array->BufferBindingIndex != bindingIndex) {
       const GLbitfield array_bit = VERT_BIT(attribIndex);
 
-      if (_mesa_is_bufferobj(vao->BufferBinding[bindingIndex].BufferObj))
+      if (vao->BufferBinding[bindingIndex].BufferObj)
          vao->VertexAttribBufferMask |= array_bit;
       else
          vao->VertexAttribBufferMask &= ~array_bit;
@@ -204,10 +204,8 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx,
    assert(!vao->SharedAndImmutable);
    struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index];
 
-   assert(vbo != ctx->Shared->NullBufferObj);
-
    if (ctx->Const.VertexBufferOffsetIsInt32 && (int)offset < 0 &&
-       _mesa_is_bufferobj(vbo)) {
+       vbo) {
       /* The offset will be interpreted as a signed int, so make sure
        * the user supplied offset is not negative (driver limitation).
        */
@@ -229,7 +227,7 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx,
       binding->Offset = offset;
       binding->Stride = stride;
 
-      if (!_mesa_is_bufferobj(vbo)) {
+      if (!vbo) {
          vao->VertexAttribBufferMask &= ~binding->_BoundArrays;
       } else {
          vao->VertexAttribBufferMask |= binding->_BoundArrays;
@@ -629,14 +627,21 @@ _mesa_update_array_format(struct gl_context *ctx,
                           GLuint relativeOffset)
 {
    struct gl_array_attributes *const array = &vao->VertexAttrib[attrib];
+   struct gl_vertex_format new_format;
 
    assert(!vao->SharedAndImmutable);
    assert(size <= 4);
 
-   array->RelativeOffset = relativeOffset;
-   _mesa_set_vertex_format(&array->Format, size, type, format,
+   _mesa_set_vertex_format(&new_format, size, type, format,
                            normalized, integer, doubles);
 
+   if ((array->RelativeOffset == relativeOffset) &&
+       !memcmp(&new_format, &array->Format, sizeof(new_format)))
+      return;
+
+   array->RelativeOffset = relativeOffset;
+   array->Format = new_format;
+
    vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
 }
 
@@ -833,7 +838,7 @@ validate_array(struct gl_context *ctx, const char *func,
     *       2.9.6), and the pointer argument is not NULL."
     */
    if (ptr != NULL && vao != ctx->Array.DefaultVAO &&
-       !_mesa_is_bufferobj(obj)) {
+       !obj) {
       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
       return;
    }
@@ -893,17 +898,11 @@ update_array(struct gl_context *ctx,
 
    /* The Stride and Ptr fields are not set by update_array_format() */
    struct gl_array_attributes *array = &vao->VertexAttrib[attrib];
-   array->Stride = stride;
-   /* For updating the pointer we would need to add the vao->NewArrays flag
-    * to the VAO. But but that is done already unconditionally in
-    * _mesa_update_array_format called above.
-    */
-   assert((vao->NewArrays | ~vao->Enabled) & VERT_BIT(attrib));
-   array->Ptr = ptr;
-
-   /* TODO: remove this hack by not using NullBufferObj in callers */
-   if (obj == ctx->Shared->NullBufferObj)
-      obj = NULL;
+   if ((array->Stride != stride) || (array->Ptr != ptr)) {
+      array->Stride = stride;
+      array->Ptr = ptr;
+      vao->NewArrays |= vao->Enabled & VERT_BIT(attrib);
+   }
 
    /* Update the vertex buffer binding */
    GLsizei effectiveStride = stride != 0 ?
@@ -2753,6 +2752,7 @@ static void
 primitive_restart_index(struct gl_context *ctx, GLuint index)
 {
    ctx->Array.RestartIndex = index;
+   _mesa_update_derived_primitive_restart_state(ctx);
 }
 
 
@@ -3171,13 +3171,11 @@ vertex_array_vertex_buffers(struct gl_context *ctx,
          else if (binding->BufferObj && binding->BufferObj->Name == buffers[i])
             vbo = binding->BufferObj;
          else {
-            vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func);
-            if (!vbo)
+            bool error;
+            vbo = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, func,
+                                                    &error);
+            if (error)
                continue;
-
-            /* TODO: remove this hack */
-            if (vbo == ctx->Shared->NullBufferObj)
-               vbo = NULL;
          }
       } else {
          vbo = NULL;
@@ -3800,7 +3798,7 @@ _mesa_print_arrays(struct gl_context *ctx)
               array->Ptr, _mesa_enum_to_string(array->Format.Type),
               array->Format.Size,
               array->Format._ElementSize, binding->Stride, bo ? bo->Name : 0,
-              (unsigned long) bo ? bo->Size : 0);
+              (unsigned long)(bo ? bo->Size : 0));
    }
 }