mesa/glthread: Call unmarshal_batch directly in glthread_finish
authorBartosz Tomczyk <bartosz.tomczyk86@gmail.com>
Thu, 30 Mar 2017 20:31:09 +0000 (22:31 +0200)
committerTimothy Arceri <tarceri@itsqueeze.com>
Mon, 3 Apr 2017 00:33:31 +0000 (10:33 +1000)
Call it directly when batch queue is empty. This avoids costly thread
synchronisation. This commit improves performance of games that have
previously regressed with mesa_glthread=true.

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/mesa/main/glthread.c

index 06115b916db361a53347b672c9ae1d93601dd4d3..3f07c420d47580b90ae180d3802187267ddf4d68 100644 (file)
@@ -194,16 +194,12 @@ _mesa_glthread_restore_dispatch(struct gl_context *ctx)
    }
 }
 
-void
-_mesa_glthread_flush_batch(struct gl_context *ctx)
+static void
+_mesa_glthread_flush_batch_locked(struct gl_context *ctx)
 {
    struct glthread_state *glthread = ctx->GLThread;
-   struct glthread_batch *batch;
+   struct glthread_batch *batch = glthread->batch;
 
-   if (!glthread)
-      return;
-
-   batch = glthread->batch;
    if (!batch->used)
       return;
 
@@ -223,10 +219,26 @@ _mesa_glthread_flush_batch(struct gl_context *ctx)
       return;
    }
 
-   pthread_mutex_lock(&glthread->mutex);
    *glthread->batch_queue_tail = batch;
    glthread->batch_queue_tail = &batch->next;
    pthread_cond_broadcast(&glthread->new_work);
+}
+
+void
+_mesa_glthread_flush_batch(struct gl_context *ctx)
+{
+   struct glthread_state *glthread = ctx->GLThread;
+   struct glthread_batch *batch;
+
+   if (!glthread)
+      return;
+
+   batch = glthread->batch;
+   if (!batch->used)
+      return;
+
+   pthread_mutex_lock(&glthread->mutex);
+   _mesa_glthread_flush_batch_locked(ctx);
    pthread_mutex_unlock(&glthread->mutex);
 }
 
@@ -252,12 +264,20 @@ _mesa_glthread_finish(struct gl_context *ctx)
    if (pthread_self() == glthread->thread)
       return;
 
-   _mesa_glthread_flush_batch(ctx);
-
    pthread_mutex_lock(&glthread->mutex);
 
-   while (glthread->batch_queue || glthread->busy)
-      pthread_cond_wait(&glthread->work_done, &glthread->mutex);
+   if (!(glthread->batch_queue || glthread->busy)) {
+      if (glthread->batch && glthread->batch->used) {
+         struct _glapi_table *dispatch = _glapi_get_dispatch();
+         glthread_unmarshal_batch(ctx, glthread->batch);
+         _glapi_set_dispatch(dispatch);
+         glthread_allocate_batch(ctx);
+      }
+   } else {
+      _mesa_glthread_flush_batch_locked(ctx);
+      while (glthread->batch_queue || glthread->busy)
+         pthread_cond_wait(&glthread->work_done, &glthread->mutex);
+   }
 
    pthread_mutex_unlock(&glthread->mutex);
 }