mesa: restructure bind_buffer_object for better performance
authorMarek Olšák <marek.olsak@amd.com>
Mon, 22 Aug 2022 05:40:35 +0000 (01:40 -0400)
committerMarge Bot <emma+marge@anholt.net>
Mon, 26 Sep 2022 22:58:16 +0000 (22:58 +0000)
The CPU time spent in _mesa_BindBuffer_no_error decresed from 11.4% to 9.2%.
I explain in the code what is happening here because it's not obvious.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18828>

src/mesa/main/bufferobj.c

index 6cd7dda..60ab857 100644 (file)
@@ -1349,29 +1349,33 @@ bind_buffer_object(struct gl_context *ctx,
                    bool no_error)
 {
    struct gl_buffer_object *oldBufObj;
-   struct gl_buffer_object *newBufObj = NULL;
+   struct gl_buffer_object *newBufObj;
 
    assert(bindTarget);
 
+   /* Fast path that unbinds. It's better when NULL is a literal, so that
+    * the compiler can simplify this code after inlining.
+    */
+   if (buffer == 0) {
+      _mesa_reference_buffer_object(ctx, bindTarget, NULL);
+      return;
+   }
+
    /* Get pointer to old buffer object (to be unbound) */
    oldBufObj = *bindTarget;
-   if ((oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending) ||
-       (!oldBufObj && buffer == 0))
+   GLuint old_name = oldBufObj && !oldBufObj->DeletePending ? oldBufObj->Name : 0;
+   if (old_name == buffer)
       return;   /* rebinding the same buffer object- no change */
 
-   /*
-    * Get pointer to new buffer object (newBufObj)
-    */
-   if (buffer != 0) {
-      /* non-default buffer object */
-      newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
-      if (!_mesa_handle_bind_buffer_gen(ctx, buffer,
-                                        &newBufObj, "glBindBuffer",
-                                        no_error))
-         return;
-   }
+   newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
+   /* Get a new buffer object if it hasn't been created. */
+   if (!handle_bind_buffer_gen(ctx, buffer, &newBufObj, "glBindBuffer",
+                               no_error))
+      return;
 
-   /* bind new buffer */
+   /* At this point, the compiler should deduce that newBufObj is non-NULL if
+    * everything has been inlined, so the compiler should simplify this.
+    */
    _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);
 }