Git-Url: 
http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-current.git;a=commitdiff;h=6083cc92515d5ed56d9a0711b8863dff2e27aacb

commit 6083cc92515d5ed56d9a0711b8863dff2e27aacb
Author: crazy <cr...@frugalware.org>
Date:   Sat Oct 14 03:51:44 2017 +0200

mesa-17.2.2-2-x86_64
* relbump
* re-added nouveau_locking patches webengine still broken without
* enabled swr and virgl ( we have all these enabled in kernel so enable here 
too )
* added some comments and FIXME's
* fix typo in GALLIUM setup .. we cannot start with first driver being +=,foo

diff --git a/source/x11/mesa/FrugalBuild b/source/x11/mesa/FrugalBuild
index 1970666..63cb5b7 100644
--- a/source/x11/mesa/FrugalBuild
+++ b/source/x11/mesa/FrugalBuild
@@ -32,9 +32,12 @@ if Fuse WAYLAND_EGL; then
USE_EGL=y
fi

+## NOTE: on major bumps OR when enabling new features _comment_ out last 2 
lines from FB
+##       we want to see whatever we are missing things in splitting. If we go 
and just Frm stuff
+##       we may 1) not notice new libs/files and 2) while 1 we may break 
things.
pkgname=mesa
pkgver=17.2.2
-pkgrel=1
+pkgrel=2
pkgdesc="Mesa is a 3D graphics library"
url="http://mesa3d.sourceforge.net/";
_F_archive_grepv="-rc"
@@ -63,8 +66,14 @@ if Fuse DEVEL; then
_F_scm_want_up2date=yes
Finclude scm
else
-       source=("https://mesa.freedesktop.org/archive/$pkgname-$pkgver.tar.xz";)
-       signatures=("${source[0]}".sig )
+       ## please do NOT remove nouveau patches .. they may need re-diff'ing
+       ## on major bumps  -- crazy --
+       source=(https://mesa.freedesktop.org/archive/$pkgname-$pkgver.tar.xz \
+               nouveau_locking_1.patch \
+               nouveau_locking_2.patch \
+               nouveau_locking_3.patch \
+               swr-fix.patch)
+       signatures=("${source[0]}".sig '' '' '' '')
fi

subpkgs=('libgl' 'mesa-libgl-headers')
@@ -638,13 +647,16 @@ fi

if Fuse GALLIUM; then

-       GALLIUM_DRIVERS+=",i915"
+       GALLIUM_DRIVERS+="i915"
GALLIUM_DRIVERS+=",nouveau"
GALLIUM_DRIVERS+=",r300,r600,radeonsi"
GALLIUM_DRIVERS+=",svga"
GALLIUM_DRIVERS+=",swrast"
+       GALLIUM_DRIVERS+=",swr"
+       GALLIUM_DRIVERS+=",virgl"
Fconfopts+=" --with-gallium-drivers=$GALLIUM_DRIVERS"
Fconfopts+=" --enable-llvm"
+       Fconfopts+=" --with-swr-archs=avx,avx2"
if ! Fuse OSMESA; then
Fconfopts+=" --enable-gallium-osmesa"
fi
@@ -664,12 +676,15 @@ if Fuse VULKAN; then
Fconfopts+=" --with-vulkan-drivers=intel,radeon"
fi

+_Fbuild_no_patch=yes
+
build() {

if Fuse DEVEL; then
Funpack_scm
fi

+       Fpatchall
## Hack for llvm built with cmake..  autoreconf breaks stuff :/
Fsed  "LLVM_SO_NAME=.*" "LLVM_SO_NAME=LLVM" configure

@@ -717,6 +732,10 @@ build() {
if Fuse OPENCL; then
Fsplit lib32-libcl usr/lib32/libMesaOpenCL*
Fsplit lib32-mesa-pipe-drivers usr/lib32/gallium-pipe/
+               ## SWR is special it is a lib since one could
+               ## build 4 backends .. and so we'll have 
libswr$backend_name.so.*
+               ## which gets then loaded at runtime
+               Fsplit lib32-mesa-pipe-drivers usr/lib32/libswr*
fi

if Fuse VULKAN; then
@@ -809,8 +828,15 @@ build() {
Fsplit libgles usr/lib/pkgconfig/gles*.pc
fi

+       ## FIXME: in setup too .. we use Fuse GALLIUM but have all these under
+       ##        Fuse OPENCL ..
if Fuse OPENCL; then
Fsplit mesa-pipe-drivers usr/lib/gallium-pipe/
+               ## SWR is special it is a lib since one could
+               ## build 4 backends .. and so we'll have 
libswr$backend_name.so.*
+               ## which gets then loaded at runtime
+               Fsplit mesa-pipe-drivers usr/lib/libswr*
+
Fsplit libcl usr/lib/libMesaOpenCL*
Fsplit libcl etc/OpenCL
fi
@@ -859,7 +885,8 @@ build() {
fi

# empty dirs
-       Frm usr/{lib,include,i686-frugalware-linux,lib32}/
+       Frm usr/{lib,include,i686-frugalware-linux,lib32,share/vulkan}/
+       Frm etc
}

# optimization OK
diff --git a/source/x11/mesa/nouveau_locking_1.patch 
b/source/x11/mesa/nouveau_locking_1.patch
new file mode 100644
index 0000000..7ed0cd0
--- /dev/null
+++ b/source/x11/mesa/nouveau_locking_1.patch
@@ -0,0 +1,1703 @@
+diff -ur mesa-17.2.1/src/gallium/auxiliary/os/os_thread.h 
mesa-17.2.1-nouvlock-1/src/gallium/auxiliary/os/os_thread.h
+--- mesa-17.2.1/src/gallium/auxiliary/os/os_thread.h   2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/auxiliary/os/os_thread.h        
2017-09-27 12:14:56.113118361 +0200
+@@ -42,6 +42,25 @@
+ #include "util/u_thread.h"
+
+
++/* pipe_mutex
++ */
++typedef mtx_t pipe_mutex;
++
++#define pipe_static_mutex(mutex) \
++   static pipe_mutex mutex = _MTX_INITIALIZER_NP
++
++#define pipe_mutex_init(mutex) \
++   (void) mtx_init(&(mutex), mtx_plain)
++
++#define pipe_mutex_destroy(mutex) \
++   mtx_destroy(&(mutex))
++
++#define pipe_mutex_lock(mutex) \
++   (void) mtx_lock(&(mutex))
++
++#define pipe_mutex_unlock(mutex) \
++   (void) mtx_unlock(&(mutex))
++
+ #define pipe_mutex_assert_locked(mutex) \
+    __pipe_mutex_assert_locked(&(mutex))
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_buffer.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_buffer.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_buffer.c   2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_buffer.c        
2017-09-27 12:14:56.114118346 +0200
+@@ -380,6 +380,7 @@
+                             struct pipe_transfer **ptransfer)
+ {
+    struct nouveau_context *nv = nouveau_context(pipe);
++   struct nouveau_screen *screen = nv->screen;
+    struct nv04_resource *buf = nv04_resource(resource);
+    struct nouveau_transfer *tx = MALLOC_STRUCT(nouveau_transfer);
+    uint8_t *map;
+@@ -424,14 +425,19 @@
+                buf->data = NULL;
+             }
+             nouveau_transfer_staging(nv, tx, false);
++            pipe_mutex_lock(screen->push_mutex);
+             nouveau_transfer_read(nv, tx);
++            pipe_mutex_unlock(screen->push_mutex);
+          } else {
+             /* The buffer is currently idle. Create a staging area for writes,
+              * and make sure that the cached data is up-to-date. */
+             if (usage & PIPE_TRANSFER_WRITE)
+                nouveau_transfer_staging(nv, tx, true);
+-            if (!buf->data)
++            if (!buf->data) {
++               pipe_mutex_lock(screen->push_mutex);
+                nouveau_buffer_cache(nv, buf);
++               pipe_mutex_unlock(screen->push_mutex);
++            }
+          }
+       }
+       return buf->data ? (buf->data + box->x) : tx->map;
+@@ -477,7 +483,9 @@
+                             PIPE_TRANSFER_PERSISTENT))) {
+          /* Discarding was not possible, must sync because
+           * subsequent transfers might use UNSYNCHRONIZED. */
++         pipe_mutex_lock(screen->push_mutex);
+          nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
++         pipe_mutex_unlock(screen->push_mutex);
+       } else
+       if (usage & PIPE_TRANSFER_DISCARD_RANGE) {
+          /* The whole range is being discarded, so it doesn't matter what was
+@@ -486,10 +494,13 @@
+          map = tx->map;
+       } else
+       if (nouveau_buffer_busy(buf, PIPE_TRANSFER_READ)) {
+-         if (usage & PIPE_TRANSFER_DONTBLOCK)
++         if (usage & PIPE_TRANSFER_DONTBLOCK) {
+             map = NULL;
+-         else
++         } else {
++            pipe_mutex_lock(screen->push_mutex);
+             nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
++            pipe_mutex_unlock(screen->push_mutex);
++         }
+       } else {
+          /* It is expected that the returned buffer be a representation of the
+           * data in question, so we must copy it over from the buffer. */
+@@ -513,9 +524,13 @@
+ {
+    struct nouveau_transfer *tx = nouveau_transfer(transfer);
+    struct nv04_resource *buf = nv04_resource(transfer->resource);
++   struct nouveau_screen *screen = nouveau_context(pipe)->screen;
+
+-   if (tx->map)
++   if (tx->map) {
++      pipe_mutex_lock(screen->push_mutex);
+       nouveau_transfer_write(nouveau_context(pipe), tx, box->x, box->width);
++      pipe_mutex_unlock(screen->push_mutex);
++   }
+
+    util_range_add(&buf->valid_buffer_range,
+                   tx->base.box.x + box->x,
+@@ -535,11 +550,15 @@
+    struct nouveau_context *nv = nouveau_context(pipe);
+    struct nouveau_transfer *tx = nouveau_transfer(transfer);
+    struct nv04_resource *buf = nv04_resource(transfer->resource);
++   struct nouveau_screen *screen = nouveau_context(pipe)->screen;
+
+    if (tx->base.usage & PIPE_TRANSFER_WRITE) {
+       if (!(tx->base.usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
+-         if (tx->map)
++         if (tx->map) {
++            pipe_mutex_lock(screen->push_mutex);
+             nouveau_transfer_write(nv, tx, 0, tx->base.box.width);
++            pipe_mutex_unlock(screen->push_mutex);
++         }
+
+          util_range_add(&buf->valid_buffer_range,
+                         tx->base.box.x, tx->base.box.x + tx->base.box.width);
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_fence.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_fence.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_fence.c    2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_fence.c 
2017-09-27 12:14:56.198117111 +0200
+@@ -67,12 +67,14 @@
+
+    ++fence->ref;
+
++   pipe_mutex_lock(screen->fence.list_mutex);
+    if (screen->fence.tail)
+       screen->fence.tail->next = fence;
+    else
+       screen->fence.head = fence;
+
+    screen->fence.tail = fence;
++   pipe_mutex_unlock(screen->fence.list_mutex);
+
+    screen->fence.emit(&screen->base, &fence->sequence);
+
+@@ -86,6 +88,9 @@
+    struct nouveau_fence *it;
+    struct nouveau_screen *screen = fence->screen;
+
++   /* XXX This can race against fence_update. But fence_update can also call
++    * into this, so ... be have to be careful.
++    */
+    if (fence->state == NOUVEAU_FENCE_STATE_EMITTED ||
+        fence->state == NOUVEAU_FENCE_STATE_FLUSHED) {
+       if (fence == screen->fence.head) {
+@@ -119,6 +124,7 @@
+       return;
+    screen->fence.sequence_ack = sequence;
+
++   pipe_mutex_lock(screen->fence.list_mutex);
+    for (fence = screen->fence.head; fence; fence = next) {
+       next = fence->next;
+       sequence = fence->sequence;
+@@ -140,6 +146,7 @@
+          if (fence->state == NOUVEAU_FENCE_STATE_EMITTED)
+             fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
+    }
++   pipe_mutex_unlock(screen->fence.list_mutex);
+ }
+
+ #define NOUVEAU_FENCE_MAX_SPINS (1 << 31)
+@@ -194,18 +201,27 @@
+    uint32_t spins = 0;
+    int64_t start = 0;
+
++   /* Fast-path for the case where the fence is already signaled to avoid
++    * messing around with mutexes and timing.
++    */
++   if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
++      return true;
++
+    if (debug && debug->debug_message)
+       start = os_time_get_nano();
+
+    if (!nouveau_fence_kick(fence))
+       return false;
+
++   pipe_mutex_unlock(screen->push_mutex);
++
+    do {
+       if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
+          if (debug && debug->debug_message)
+             pipe_debug_message(debug, PERF_INFO,
+                                "stalled %.3f ms waiting for fence",
+                                (os_time_get_nano() - start) / 1000000.f);
++         pipe_mutex_lock(screen->push_mutex);
+          return true;
+       }
+       if (!spins)
+@@ -223,6 +239,8 @@
+                 fence->sequence,
+                 screen->fence.sequence_ack, screen->fence.sequence);
+
++   pipe_mutex_lock(screen->push_mutex);
++
+    return false;
+ }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_fence.h 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_fence.h
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_fence.h    2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_fence.h 
2017-09-27 12:14:56.198117111 +0200
+@@ -2,6 +2,7 @@
+ #ifndef __NOUVEAU_FENCE_H__
+ #define __NOUVEAU_FENCE_H__
+
++#include "util/u_atomic.h"
+ #include "util/u_inlines.h"
+ #include "util/list.h"
+
+@@ -46,10 +47,10 @@
+ nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
+ {
+    if (fence)
+-      ++fence->ref;
++      p_atomic_inc(&fence->ref);
+
+    if (*ref) {
+-      if (--(*ref)->ref == 0)
++      if (p_atomic_dec_zero(&(*ref)->ref))
+          nouveau_fence_del(*ref);
+    }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_screen.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_screen.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_screen.c   2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_screen.c        
2017-09-27 12:14:56.198117111 +0200
+@@ -80,10 +80,14 @@
+                             struct pipe_fence_handle *pfence,
+                             uint64_t timeout)
+ {
++   bool ret;
+    if (!timeout)
+       return nouveau_fence_signalled(nouveau_fence(pfence));
+
+-   return nouveau_fence_wait(nouveau_fence(pfence), NULL);
++   pipe_mutex_lock(nouveau_screen(screen)->push_mutex);
++   ret = nouveau_fence_wait(nouveau_fence(pfence), NULL);
++   pipe_mutex_unlock(nouveau_screen(screen)->push_mutex);
++   return ret;
+ }
+
+
+@@ -179,6 +183,9 @@
+    if (nv_dbg)
+       nouveau_mesa_debug = atoi(nv_dbg);
+
++   pipe_mutex_init(screen->push_mutex);
++   pipe_mutex_init(screen->fence.list_mutex);
++
+    /* These must be set before any failure is possible, as the cleanup
+     * paths assume they're responsible for deleting them.
+     */
+@@ -283,6 +290,9 @@
+    nouveau_drm_del(&screen->drm);
+    close(fd);
+
++   pipe_mutex_destroy(screen->push_mutex);
++   pipe_mutex_destroy(screen->fence.list_mutex);
++
+    disk_cache_destroy(screen->disk_shader_cache);
+ }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_screen.h 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_screen.h
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nouveau_screen.h   2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nouveau_screen.h        
2017-09-27 12:14:56.199117096 +0200
+@@ -4,6 +4,7 @@
+ #include "pipe/p_screen.h"
+ #include "util/disk_cache.h"
+ #include "util/u_memory.h"
++#include "os/os_thread.h"
+
+ #ifdef DEBUG
+ # define NOUVEAU_ENABLE_DRIVER_STATISTICS
+@@ -23,6 +24,7 @@
+    struct nouveau_object *channel;
+    struct nouveau_client *client;
+    struct nouveau_pushbuf *pushbuf;
++   pipe_mutex push_mutex;
+
+    int refcount;
+
+@@ -40,6 +42,7 @@
+       struct nouveau_fence *head;
+       struct nouveau_fence *tail;
+       struct nouveau_fence *current;
++      pipe_mutex list_mutex;
+       u32 sequence;
+       u32 sequence_ack;
+       void (*emit)(struct pipe_screen *, u32 *sequence);
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_clear.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_clear.c  2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_clear.c       
2017-09-27 12:14:56.199117096 +0200
+@@ -58,8 +58,11 @@
+    struct pipe_framebuffer_state *fb = &nv30->framebuffer;
+    uint32_t colr = 0, zeta = 0, mode = 0;
+
+-   if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, 
true))
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++   if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, 
true)) {
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
++   }
+
+    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+       colr  = pack_rgba(fb->cbufs[0]->format, color->f);
+@@ -96,6 +99,7 @@
+    PUSH_DATA (push, mode);
+
+    nv30_state_release(nv30);
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ static void
+@@ -126,11 +130,15 @@
+       rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
+    }
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    refn.bo = mt->base.bo;
+    refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
+    if (nouveau_pushbuf_space(push, 32, 1, 0) ||
+-       nouveau_pushbuf_refn (push, &refn, 1))
++       nouveau_pushbuf_refn (push, &refn, 1)) {
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
++   }
+
+    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+    PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
+@@ -155,6 +163,8 @@
+                     NV30_3D_CLEAR_BUFFERS_COLOR_B |
+                     NV30_3D_CLEAR_BUFFERS_COLOR_A);
+
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
++
+    nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
+ }
+
+@@ -191,11 +201,15 @@
+    if (buffers & PIPE_CLEAR_STENCIL)
+       mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    refn.bo = mt->base.bo;
+    refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
+    if (nouveau_pushbuf_space(push, 32, 1, 0) ||
+-       nouveau_pushbuf_refn (push, &refn, 1))
++       nouveau_pushbuf_refn (push, &refn, 1)) {
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
++   }
+
+    BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+    PUSH_DATA (push, 0);
+@@ -221,6 +235,8 @@
+    BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
+    PUSH_DATA (push, mode);
+
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
++
+    nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
+ }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_context.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_context.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_context.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_context.c     
2017-09-27 12:14:56.290115758 +0200
+@@ -198,6 +198,8 @@
+    if (!nv30)
+       return NULL;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    nv30->screen = screen;
+    nv30->base.screen = &screen->base;
+    nv30->base.copy_data = nv30_transfer_copy_data;
+@@ -230,6 +232,7 @@
+    ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);
+    if (ret) {
+       nv30_context_destroy(pipe);
++      pipe_mutex_unlock(screen->base.push_mutex);
+       return NULL;
+    }
+
+@@ -263,10 +266,13 @@
+    nv30->blitter = util_blitter_create(pipe);
+    if (!nv30->blitter) {
+       nv30_context_destroy(pipe);
++      pipe_mutex_unlock(screen->base.push_mutex);
+       return NULL;
+    }
+
+    nouveau_context_init_vdec(&nv30->base);
+
++   pipe_mutex_unlock(screen->base.push_mutex);
++
+    return pipe;
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_miptree.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_miptree.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_miptree.c     
2017-09-27 12:14:56.290115758 +0200
+@@ -130,10 +130,12 @@
+    struct nv30_context *nv30 = nv30_context(pipe);
+    struct nv30_rect src, dst;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
+    if (dstres->target == PIPE_BUFFER && srcres->target == PIPE_BUFFER) {
+       nouveau_copy_buffer(&nv30->base,
+                           nv04_resource(dstres), dstx,
+                           nv04_resource(srcres), src_box->x, src_box->width);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
+    }
+
+@@ -143,6 +145,7 @@
+                        src_box->width, src_box->height, &dst);
+
+    nv30_transfer_rect(nv30, NEAREST, &src, &dst);
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ static void
+@@ -163,6 +166,7 @@
+    y1 = src.y1;
+
+    /* On nv3x we must use sifm which is restricted to 1024x1024 tiles */
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
+    for (y = src.y0; y < y1; y += h) {
+       h = y1 - y;
+       if (h > 1024)
+@@ -193,6 +197,7 @@
+          nv30_transfer_rect(nv30, BILINEAR, &src, &dst);
+       }
+    }
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ void
+@@ -308,8 +313,12 @@
+    tx->tmp.y1     = tx->tmp.h;
+    tx->tmp.z      = 0;
+
+-   if (usage & PIPE_TRANSFER_READ)
++   if (usage & PIPE_TRANSFER_READ) {
++      pipe_mutex_lock(nv30->screen->base.push_mutex);
+       nv30_transfer_rect(nv30, NEAREST, &tx->img, &tx->tmp);
++      PUSH_KICK(nv30->base.pushbuf);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
++   }
+
+    if (tx->tmp.bo->map) {
+       *ptransfer = &tx->base;
+@@ -340,11 +349,13 @@
+    struct nv30_transfer *tx = nv30_transfer(ptx);
+
+    if (ptx->usage & PIPE_TRANSFER_WRITE) {
++      pipe_mutex_lock(nv30->screen->base.push_mutex);
+       nv30_transfer_rect(nv30, NEAREST, &tx->tmp, &tx->img);
+
+       /* Allow the copies above to finish executing before freeing the source 
*/
+       nouveau_fence_work(nv30->screen->base.fence.current,
+                          nouveau_fence_unref_bo, tx->tmp.bo);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+    } else {
+       nouveau_bo_ref(NULL, &tx->tmp.bo);
+    }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_query.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_query.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_query.c  2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_query.c       
2017-09-27 12:14:56.290115758 +0200
+@@ -152,6 +152,7 @@
+    struct nv30_query *q = nv30_query(pq);
+    struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
+    switch (q->type) {
+    case PIPE_QUERY_TIME_ELAPSED:
+       q->qo[0] = nv30_query_object_new(nv30->screen);
+@@ -161,7 +162,7 @@
+       }
+       break;
+    case PIPE_QUERY_TIMESTAMP:
+-      return true;
++      break;
+    default:
+       BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1);
+       PUSH_DATA (push, q->report);
+@@ -172,6 +173,7 @@
+       BEGIN_NV04(push, SUBC_3D(q->enable), 1);
+       PUSH_DATA (push, 1);
+    }
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+    return true;
+ }
+
+@@ -183,6 +185,7 @@
+    struct nv30_query *q = nv30_query(pq);
+    struct nouveau_pushbuf *push = nv30->base.pushbuf;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
+    q->qo[1] = nv30_query_object_new(screen);
+    if (q->qo[1]) {
+       BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
+@@ -194,6 +197,7 @@
+       PUSH_DATA (push, 0);
+    }
+    PUSH_KICK (push);
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+    return true;
+ }
+
+@@ -248,9 +252,11 @@
+    nv30->render_cond_mode = mode;
+    nv30->render_cond_cond = condition;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
+    if (!pq) {
+       BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
+       PUSH_DATA (push, 0x01000000);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
+    }
+
+@@ -262,6 +268,7 @@
+
+    BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
+    PUSH_DATA (push, 0x02000000 | q->qo[1]->hw->start);
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ static void
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_vbo.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv30/nv30_vbo.c    2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv30/nv30_vbo.c 
2017-09-27 12:14:56.291115743 +0200
+@@ -569,6 +569,8 @@
+    if (nv30->vbo_push_hint != !!nv30->vbo_fifo)
+       nv30->dirty |= NV30_NEW_ARRAYS;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    push->user_priv = &nv30->bufctx;
+    if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
+       nv30_update_user_vbufs(nv30);
+@@ -576,10 +578,12 @@
+    nv30_state_validate(nv30, ~0, true);
+    if (nv30->draw_flags) {
+       nv30_render_vbo(pipe, info);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
+    } else
+    if (nv30->vbo_fifo) {
+       nv30_push_vbo(nv30, info);
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
+    }
+
+@@ -636,6 +640,7 @@
+
+    nv30_state_release(nv30);
+    nv30_release_user_vbufs(nv30);
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ void
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_compute.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_compute.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_compute.c     
2017-09-27 12:14:56.291115743 +0200
+@@ -249,9 +249,11 @@
+    struct nv50_program *cp = nv50->compprog;
+    bool ret;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    ret = !nv50_state_validate_cp(nv50, ~0);
+    if (ret) {
+       NOUVEAU_ERR("Failed to launch grid !\n");
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
+    }
+
+@@ -284,6 +286,8 @@
+    BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
+    PUSH_DATA (push, 0);
+
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
++
+    /* bind a compute shader clobbers fragment shader state */
+    nv50->dirty_3d |= NV50_NEW_3D_FRAGPROG;
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_context.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_context.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_context.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_context.c     
2017-09-27 12:14:56.291115743 +0200
+@@ -38,7 +38,9 @@
+    if (fence)
+       nouveau_fence_ref(screen->fence.current, (struct nouveau_fence 
**)fence);
+
++   pipe_mutex_lock(screen->push_mutex);
+    PUSH_KICK(screen->pushbuf);
++   pipe_mutex_unlock(screen->push_mutex);
+
+    nouveau_context_update_frame_stats(nouveau_context(pipe));
+ }
+@@ -48,10 +50,12 @@
+ {
+    struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
+
++   pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
+    BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
+    PUSH_DATA (push, 0);
+    BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
+    PUSH_DATA (push, 0x20);
++   pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
+ }
+
+ static void
+@@ -104,6 +108,7 @@
+       data_words = string_words;
+    else
+       data_words = string_words + !!(len & 3);
++   pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
+    BEGIN_NI04(push, SUBC_3D(NV04_GRAPH_NOP), data_words);
+    if (string_words)
+       PUSH_DATAp(push, str, string_words);
+@@ -112,6 +117,7 @@
+       memcpy(&data, &str[string_words * 4], len & 3);
+       PUSH_DATA (push, data);
+    }
++   pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
+ }
+
+ void
+@@ -282,6 +288,8 @@
+       return NULL;
+    pipe = &nv50->base.pipe;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    if (!nv50_blitctx_create(nv50))
+       goto out_err;
+
+@@ -379,11 +387,14 @@
+
+    util_dynarray_init(&nv50->global_residents, NULL);
+
++   pipe_mutex_unlock(screen->base.push_mutex);
++
+    return pipe;
+
+ out_err:
+    if (pipe->stream_uploader)
+       u_upload_destroy(pipe->stream_uploader);
++   pipe_mutex_unlock(screen->base.push_mutex);
+    if (nv50->bufctx_3d)
+       nouveau_bufctx_del(&nv50->bufctx_3d);
+    if (nv50->bufctx_cp)
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_context.h 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_context.h
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_context.h        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_context.h     
2017-09-27 12:14:56.292115728 +0200
+@@ -221,6 +221,11 @@
+ /* nv50_draw.c */
+ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
+
++/* nv50_query.c */
++void nv50_render_condition(struct pipe_context *pipe,
++                           struct pipe_query *pq,
++                           boolean condition, uint mode);
++
+ /* nv50_shader_state.c */
+ void nv50_vertprog_validate(struct nv50_context *);
+ void nv50_gmtyprog_validate(struct nv50_context *);
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query.c  2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query.c       
2017-09-27 12:14:56.292115728 +0200
+@@ -70,7 +70,7 @@
+    return q->funcs->get_query_result(nv50_context(pipe), q, wait, result);
+ }
+
+-static void
++void
+ nv50_render_condition(struct pipe_context *pipe,
+                       struct pipe_query *pq,
+                       boolean condition, enum pipe_render_cond_flag mode)
+@@ -145,6 +145,16 @@
+ }
+
+ static void
++nv50_render_condition_locked(struct pipe_context *pipe,
++                             struct pipe_query *pq,
++                             boolean condition, uint mode)
++{
++   pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
++   nv50_render_condition(pipe, pq, condition, mode);
++   pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
++}
++
++static void
+ nv50_set_active_query_state(struct pipe_context *pipe, boolean enable)
+ {
+ }
+@@ -160,7 +170,7 @@
+    pipe->end_query = nv50_end_query;
+    pipe->get_query_result = nv50_get_query_result;
+    pipe->set_active_query_state = nv50_set_active_query_state;
+-   pipe->render_condition = nv50_render_condition;
++   pipe->render_condition = nv50_render_condition_locked;
+    nv50->cond_condmode = NV50_3D_COND_MODE_ALWAYS;
+ }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c       
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c    
2017-09-27 12:14:56.292115728 +0200
+@@ -129,6 +129,7 @@
+ {
+    struct nouveau_pushbuf *push = nv50->base.pushbuf;
+    struct nv50_hw_query *hq = nv50_hw_query(q);
++   bool ret = true;
+
+    if (hq->funcs && hq->funcs->begin_query)
+       return hq->funcs->begin_query(nv50, hq);
+@@ -154,6 +155,7 @@
+    if (!hq->is64bit)
+       hq->data[0] = hq->sequence++; /* the previously used one */
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    switch (q->type) {
+    case PIPE_QUERY_OCCLUSION_COUNTER:
+    case PIPE_QUERY_OCCLUSION_PREDICATE:
+@@ -193,10 +195,13 @@
+       break;
+    default:
+       assert(0);
+-      return false;
++      ret = false;
++      break;
+    }
+-   hq->state = NV50_HW_QUERY_STATE_ACTIVE;
+-   return true;
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
++   if (ret)
++      hq->state = NV50_HW_QUERY_STATE_ACTIVE;
++   return ret;
+ }
+
+ static void
+@@ -212,6 +217,7 @@
+
+    hq->state = NV50_HW_QUERY_STATE_ENDED;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    switch (q->type) {
+    case PIPE_QUERY_OCCLUSION_COUNTER:
+    case PIPE_QUERY_OCCLUSION_PREDICATE:
+@@ -264,6 +270,7 @@
+       assert(0);
+       break;
+    }
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
+    if (hq->is64bit)
+       nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
+ }
+@@ -286,16 +293,21 @@
+       nv50_hw_query_update(q);
+
+    if (hq->state != NV50_HW_QUERY_STATE_READY) {
++      pipe_mutex_lock(nv50->screen->base.push_mutex);
+       if (!wait) {
+          /* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
+          if (hq->state != NV50_HW_QUERY_STATE_FLUSHED) {
+             hq->state = NV50_HW_QUERY_STATE_FLUSHED;
+             PUSH_KICK(nv50->base.pushbuf);
+          }
++         pipe_mutex_unlock(nv50->screen->base.push_mutex);
+          return false;
+       }
+-      if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
++      if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client)) {
++         pipe_mutex_unlock(nv50->screen->base.push_mutex);
+          return false;
++      }
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+    }
+    hq->state = NV50_HW_QUERY_STATE_READY;
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c    
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c 
2017-09-27 12:14:56.293115714 +0200
+@@ -176,6 +176,7 @@
+       return false;
+    }
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    assert(cfg->num_counters <= 4);
+    PUSH_SPACE(push, 4 * 4);
+
+@@ -208,6 +209,7 @@
+       BEGIN_NV04(push, NV50_CP(MP_PM_SET(c)), 1);
+       PUSH_DATA (push, 0);
+    }
++   pipe_mutex_unlock(screen->base.push_mutex);
+    return true;
+ }
+
+@@ -237,6 +239,7 @@
+       screen->pm.prog = prog;
+    }
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    /* disable all counting */
+    PUSH_SPACE(push, 8);
+    for (c = 0; c < 4; c++) {
+@@ -260,6 +263,7 @@
+    PUSH_SPACE(push, 2);
+    BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
+    PUSH_DATA (push, 0);
++   pipe_mutex_unlock(screen->base.push_mutex);
+
+    pipe->bind_compute_state(pipe, screen->pm.prog);
+    input[0] = hq->bo->offset + hq->base_offset;
+@@ -276,6 +280,7 @@
+
+    nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_QUERY);
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    /* re-active other counters */
+    PUSH_SPACE(push, 8);
+    mask = 0;
+@@ -302,6 +307,7 @@
+                     | cfg->ctr[i].unit | cfg->ctr[i].mode);
+       }
+    }
++   pipe_mutex_unlock(screen->base.push_mutex);
+ }
+
+ static inline bool
+@@ -343,7 +349,9 @@
+
+    cfg = nv50_hw_sm_query_get_cfg(nv50, hq);
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    ret = nv50_hw_sm_query_read_data(count, nv50, wait, hq, cfg, mp_count);
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    if (!ret)
+       return false;
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_surface.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_surface.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_surface.c     
2017-09-27 12:14:56.293115714 +0200
+@@ -204,10 +204,13 @@
+    bool m2mf;
+    unsigned dst_layer = dstz, src_layer = src_box->z;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
+       nouveau_copy_buffer(&nv50->base,
+                           nv04_resource(dst), dstx,
+                           nv04_resource(src), src_box->x, src_box->width);
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
+    }
+
+@@ -247,6 +250,7 @@
+          else
+             srect.base += src_mt->layer_stride;
+       }
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
+    }
+
+@@ -270,6 +274,7 @@
+          break;
+    }
+    nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ }
+
+ static void
+@@ -289,14 +294,18 @@
+
+    assert(dst->texture->target != PIPE_BUFFER);
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
+    PUSH_DATAf(push, color->f[0]);
+    PUSH_DATAf(push, color->f[1]);
+    PUSH_DATAf(push, color->f[2]);
+    PUSH_DATAf(push, color->f[3]);
+
+-   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
++   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0)) {
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
+
+@@ -358,6 +367,8 @@
+       PUSH_DATA (push, nv50->cond_condmode);
+    }
+
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
++
+    nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
+ }
+
+@@ -382,6 +393,8 @@
+    assert(dst->texture->target != PIPE_BUFFER);
+    assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    if (clear_flags & PIPE_CLEAR_DEPTH) {
+       BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
+       PUSH_DATAf(push, depth);
+@@ -394,8 +407,10 @@
+       mode |= NV50_3D_CLEAR_BUFFERS_S;
+    }
+
+-   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0))
++   if (nouveau_pushbuf_space(push, 64 + sf->depth, 1, 0)) {
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
+
+@@ -446,6 +461,8 @@
+       PUSH_DATA (push, nv50->cond_condmode);
+    }
+
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
++
+    nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
+ }
+
+@@ -534,9 +551,12 @@
+    unsigned i, j, k;
+    uint32_t mode = 0;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
+    /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
+-   if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER))
++   if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER)) {
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
++   }
+
+    /* We have to clear ALL of the layers, not up to the min number of layers
+     * of any attachment. */
+@@ -602,6 +622,7 @@
+    /* restore the array mode */
+    BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
+    PUSH_DATA (push, nv50->rt_array_mode);
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ }
+
+ static void
+@@ -729,14 +750,18 @@
+
+    assert(size % data_size == 0);
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    if (offset & 0xff) {
+       unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset);
+       assert(fixup_size % data_size == 0);
+       nv50_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);
+       offset += fixup_size;
+       size -= fixup_size;
+-      if (!size)
++      if (!size) {
++         pipe_mutex_unlock(nv50->screen->base.push_mutex);
+          return;
++      }
+    }
+
+    elements = size / data_size;
+@@ -752,8 +777,10 @@
+    PUSH_DATAf(push, color.f[2]);
+    PUSH_DATAf(push, color.f[3]);
+
+-   if (nouveau_pushbuf_space(push, 64, 1, 0))
++   if (nouveau_pushbuf_space(push, 64, 1, 0)) {
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
+
+@@ -808,6 +835,8 @@
+                              data, data_size);
+    }
+
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
++
+    nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
+ }
+
+@@ -1724,6 +1753,8 @@
+         info->src.box.height != -info->dst.box.height))
+       eng3d = true;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    if (nv50->screen->num_occlusion_queries_active) {
+       BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+       PUSH_DATA (push, 0);
+@@ -1738,6 +1769,8 @@
+       BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
+       PUSH_DATA (push, 1);
+    }
++
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ }
+
+ static void
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_transfer.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_transfer.c       
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_transfer.c    
2017-09-27 12:14:56.294115699 +0200
+@@ -304,6 +304,7 @@
+       unsigned base = tx->rect[0].base;
+       unsigned z = tx->rect[0].z;
+       unsigned i;
++      pipe_mutex_lock(nv50->screen->base.push_mutex);
+       for (i = 0; i < box->depth; ++i) {
+          nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
+                                  tx->nblocksx, tx->nblocksy);
+@@ -313,6 +314,9 @@
+             tx->rect[0].base += mt->layer_stride;
+          tx->rect[1].base += size;
+       }
++      /* Kick these reads out so we don't have to reacquire a lock below */
++      PUSH_KICK(nv50->base.pushbuf);
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+       tx->rect[0].z = z;
+       tx->rect[0].base = base;
+       tx->rect[1].base = 0;
+@@ -349,6 +353,7 @@
+    unsigned i;
+
+    if (tx->base.usage & PIPE_TRANSFER_WRITE) {
++      pipe_mutex_lock(nv50->screen->base.push_mutex);
+       for (i = 0; i < tx->base.box.depth; ++i) {
+          nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
+                                  tx->nblocksx, tx->nblocksy);
+@@ -362,6 +367,7 @@
+       /* Allow the copies above to finish executing before freeing the source 
*/
+       nouveau_fence_work(nv50->screen->base.fence.current,
+                          nouveau_fence_unref_bo, tx->rect[1].bo);
++      pipe_mutex_unlock(nv50->screen->base.push_mutex);
+    } else {
+       nouveau_bo_ref(NULL, &tx->rect[1].bo);
+    }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_vbo.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nv50/nv50_vbo.c    2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nv50/nv50_vbo.c 
2017-09-27 12:30:06.223830218 +0200
+@@ -770,6 +770,8 @@
+    bool tex_dirty = false;
+    int s;
+
++   pipe_mutex_lock(nv50->screen->base.push_mutex);
++
+    if (info->index_size && !info->has_user_indices)
+       BCTX_REFN(nv50->bufctx_3d, 3D_INDEX, 
nv04_resource(info->index.resource), RD);
+
+@@ -900,4 +902,5 @@
+    nouveau_pushbuf_bufctx(push, NULL);
+
+    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_INDEX);
++   pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c     
2017-09-27 12:14:56.295115685 +0200
+@@ -424,13 +424,17 @@
+ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
+ {
+    struct nvc0_context *nvc0 = nvc0_context(pipe);
++   struct nvc0_screen *screen = nvc0->screen;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+    struct nvc0_program *cp = nvc0->compprog;
+    int ret;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    ret = !nvc0_state_validate_cp(nvc0, ~0);
+    if (ret) {
+       NOUVEAU_ERR("Failed to launch grid !\n");
++      pipe_mutex_unlock(screen->base.push_mutex);
+       return;
+    }
+
+@@ -498,4 +502,6 @@
+    nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
+    nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES;
+    nvc0->images_dirty[5] |= nvc0->images_valid[5];
++
++   pipe_mutex_unlock(screen->base.push_mutex);
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_context.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_context.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_context.c     
2017-09-27 12:14:56.295115685 +0200
+@@ -39,7 +39,9 @@
+    if (fence)
+       nouveau_fence_ref(screen->fence.current, (struct nouveau_fence 
**)fence);
+
++   pipe_mutex_lock(screen->push_mutex);
+    PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
++   pipe_mutex_unlock(screen->push_mutex);
+
+    nouveau_context_update_frame_stats(&nvc0->base);
+ }
+@@ -49,8 +51,10 @@
+ {
+    struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
+
++   pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
+    IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+    IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
++   pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
+ }
+
+ static void
+@@ -60,6 +64,8 @@
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+    int i, s;
+
++   pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
++
+    if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
+       for (i = 0; i < nvc0->num_vtxbufs; ++i) {
+          if (!nvc0->vtxbuf[i].buffer.resource && 
!nvc0->vtxbuf[i].is_user_buffer)
+@@ -105,6 +111,8 @@
+       nvc0->cb_dirty = true;
+    if (flags & (PIPE_BARRIER_VERTEX_BUFFER | PIPE_BARRIER_INDEX_BUFFER))
+       nvc0->base.vbo_dirty = true;
++
++   pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
+ }
+
+ static void
+@@ -121,6 +129,7 @@
+       data_words = string_words;
+    else
+       data_words = string_words + !!(len & 3);
++   pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
+    BEGIN_NIC0(push, SUBC_3D(NV04_GRAPH_NOP), data_words);
+    if (string_words)
+       PUSH_DATAp(push, str, string_words);
+@@ -129,6 +138,7 @@
+       memcpy(&data, &str[string_words * 4], len & 3);
+       PUSH_DATA (push, data);
+    }
++   pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
+ }
+
+ static void
+@@ -356,6 +366,8 @@
+       return NULL;
+    pipe = &nvc0->base.pipe;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    if (!nvc0_blitctx_create(nvc0))
+       goto out_err;
+
+@@ -463,12 +475,15 @@
+
+    util_dynarray_init(&nvc0->global_residents, NULL);
+
++   pipe_mutex_unlock(screen->base.push_mutex);
++
+    return pipe;
+
+ out_err:
+    if (nvc0) {
+       if (pipe->stream_uploader)
+          u_upload_destroy(pipe->stream_uploader);
++      pipe_mutex_unlock(screen->base.push_mutex);
+       if (nvc0->bufctx_3d)
+          nouveau_bufctx_del(&nvc0->bufctx_3d);
+       if (nvc0->bufctx_cp)
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_context.h 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_context.h        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_context.h     
2017-09-27 12:14:56.296115670 +0200
+@@ -302,6 +302,11 @@
+                                     uint32_t label);
+ void nvc0_program_init_tcp_empty(struct nvc0_context *);
+
++/* nvc0_query.c */
++void nvc0_render_condition(struct pipe_context *pipe,
++                           struct pipe_query *pq,
++                           boolean condition, uint mode);
++
+ /* nvc0_shader_state.c */
+ void nvc0_vertprog_validate(struct nvc0_context *);
+ void nvc0_tctlprog_validate(struct nvc0_context *);
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query.c  2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query.c       
2017-09-27 12:14:56.296115670 +0200
+@@ -92,7 +92,7 @@
+                                        index, resource, offset);
+ }
+
+-static void
++void
+ nvc0_render_condition(struct pipe_context *pipe,
+                       struct pipe_query *pq,
+                       boolean condition, enum pipe_render_cond_flag mode)
+@@ -169,6 +169,16 @@
+    }
+ }
+
++static void
++nvc0_render_condition_locked(struct pipe_context *pipe,
++                             struct pipe_query *pq,
++                             boolean condition, uint mode)
++{
++   pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
++   nvc0_render_condition(pipe, pq, condition, mode);
++   pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
++}
++
+ int
+ nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
+                                   unsigned id,
+@@ -278,6 +288,6 @@
+    pipe->get_query_result = nvc0_get_query_result;
+    pipe->get_query_result_resource = nvc0_get_query_result_resource;
+    pipe->set_active_query_state = nvc0_set_active_query_state;
+-   pipe->render_condition = nvc0_render_condition;
++   pipe->render_condition = nvc0_render_condition_locked;
+    nvc0->cond_condmode = NVC0_3D_COND_MODE_ALWAYS;
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c       
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c    
2017-09-27 12:14:56.296115670 +0200
+@@ -154,6 +154,7 @@
+    }
+    hq->sequence++;
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
+    switch (q->type) {
+    case PIPE_QUERY_OCCLUSION_COUNTER:
+    case PIPE_QUERY_OCCLUSION_PREDICATE:
+@@ -198,6 +199,7 @@
+    default:
+       break;
+    }
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+    hq->state = NVC0_HW_QUERY_STATE_ACTIVE;
+    return ret;
+ }
+@@ -221,6 +223,7 @@
+    }
+    hq->state = NVC0_HW_QUERY_STATE_ENDED;
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
+    switch (q->type) {
+    case PIPE_QUERY_OCCLUSION_COUNTER:
+    case PIPE_QUERY_OCCLUSION_PREDICATE:
+@@ -276,6 +279,7 @@
+    default:
+       break;
+    }
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+    if (hq->is64bit)
+       nouveau_fence_ref(nvc0->screen->base.fence.current, &hq->fence);
+ }
+@@ -298,16 +302,21 @@
+       nvc0_hw_query_update(nvc0->screen->base.client, q);
+
+    if (hq->state != NVC0_HW_QUERY_STATE_READY) {
++      pipe_mutex_lock(nvc0->screen->base.push_mutex);
+       if (!wait) {
+          if (hq->state != NVC0_HW_QUERY_STATE_FLUSHED) {
+             hq->state = NVC0_HW_QUERY_STATE_FLUSHED;
+             /* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
+             PUSH_KICK(nvc0->base.pushbuf);
+          }
++         pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+          return false;
+       }
+-      if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
++      if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->screen->base.client)) {
++         pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+          return false;
++      }
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       NOUVEAU_DRV_STAT(&nvc0->screen->base, query_sync_count, 1);
+    }
+    hq->state = NVC0_HW_QUERY_STATE_READY;
+@@ -375,6 +384,8 @@
+
+    assert(!hq->funcs || !hq->funcs->get_query_result);
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
+    if (index == -1) {
+       /* TODO: Use a macro to write the availability of the query */
+       if (hq->state != NVC0_HW_QUERY_STATE_READY)
+@@ -383,6 +394,7 @@
+       nvc0->base.push_cb(&nvc0->base, buf, offset,
+                          result_type >= PIPE_QUERY_TYPE_I64 ? 2 : 1,
+                          ready);
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
+    }
+
+@@ -469,6 +481,8 @@
+    PUSH_DATAh(push, buf->address + offset);
+    PUSH_DATA (push, buf->address + offset);
+
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
++
+    if (buf->mm) {
+       nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);
+       nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c    
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c 
2017-09-27 12:14:56.297115656 +0200
+@@ -2325,6 +2325,7 @@
+       return false;
+    }
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    assert(cfg->num_counters <= 4);
+    PUSH_SPACE(push, 4 * 8 * + 6);
+
+@@ -2385,6 +2386,7 @@
+       PUSH_DATA (push, 0xff);
+    }
+
++   pipe_mutex_unlock(screen->base.push_mutex);
+    return true;
+ }
+
+@@ -2408,6 +2410,7 @@
+       return false;
+    }
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    assert(cfg->num_counters <= 8);
+    PUSH_SPACE(push, 8 * 8 + 2);
+
+@@ -2454,6 +2457,7 @@
+       BEGIN_NVC0(push, NVC0_CP(MP_PM_SET(c)), 1);
+       PUSH_DATA (push, 0);
+    }
++   pipe_mutex_unlock(screen->base.push_mutex);
+    return true;
+ }
+
+@@ -2546,6 +2550,7 @@
+    if (unlikely(!screen->pm.prog))
+       screen->pm.prog = nvc0_hw_sm_get_program(screen);
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    /* disable all counting */
+    PUSH_SPACE(push, 8);
+    for (c = 0; c < 8; ++c)
+@@ -2576,6 +2581,7 @@
+
+    /* upload input data for the compute shader which reads MP counters */
+    nvc0_hw_sm_upload_input(nvc0, hq);
++   pipe_mutex_unlock(screen->base.push_mutex);
+
+    pipe->bind_compute_state(pipe, screen->pm.prog);
+    for (i = 0; i < 3; i++) {
+@@ -2589,6 +2595,7 @@
+
+    nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_QUERY);
+
++   pipe_mutex_lock(screen->base.push_mutex);
+    /* re-activate other counters */
+    PUSH_SPACE(push, 16);
+    mask = 0;
+@@ -2613,6 +2620,7 @@
+          PUSH_DATA (push, (cfg->ctr[i].func << 4) | cfg->ctr[i].mode);
+       }
+    }
++   pipe_mutex_unlock(screen->base.push_mutex);
+ }
+
+ static inline bool
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c 2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c      
2017-09-27 12:14:56.298115641 +0200
+@@ -534,7 +534,9 @@
+        * _current_ one, and remove both.
+        */
+       nouveau_fence_ref(screen->base.fence.current, &current);
++      pipe_mutex_lock(screen->base.push_mutex);
+       nouveau_fence_wait(current, NULL);
++      pipe_mutex_unlock(screen->base.push_mutex);
+       nouveau_fence_ref(NULL, &current);
+       nouveau_fence_ref(NULL, &screen->base.fence.current);
+    }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c     
2017-09-27 12:14:56.298115641 +0200
+@@ -206,11 +206,14 @@
+    bool m2mf;
+    unsigned dst_layer = dstz, src_layer = src_box->z;
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
+    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
+       nouveau_copy_buffer(&nvc0->base,
+                           nv04_resource(dst), dstx,
+                           nv04_resource(src), src_box->x, src_box->width);
+       NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width);
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
+    }
+    NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_copy_count, 1);
+@@ -251,6 +254,7 @@
+          else
+             srect.base += src_mt->layer_stride;
+       }
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
+    }
+
+@@ -273,6 +277,7 @@
+          break;
+    }
+    nouveau_bufctx_reset(nvc0->bufctx, 0);
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+ }
+
+ static void
+@@ -291,8 +296,12 @@
+
+    assert(dst->texture->target != PIPE_BUFFER);
+
+-   if (!PUSH_SPACE(push, 32 + sf->depth))
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
++   if (!PUSH_SPACE(push, 32 + sf->depth)) {
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN (push, res->bo, res->domain | NOUVEAU_BO_WR);
+
+@@ -357,6 +366,8 @@
+       IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
+
+    nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
++
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+ }
+
+ static void
+@@ -542,8 +553,11 @@
+
+    assert(size % data_size == 0);
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
+    if (data_size == 12) {
+       nvc0_clear_buffer_push(pipe, res, offset, size, data, data_size);
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
+    }
+
+@@ -553,8 +567,10 @@
+       nvc0_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);
+       offset += fixup_size;
+       size -= fixup_size;
+-      if (!size)
++      if (!size) {
++         pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+          return;
++      }
+    }
+
+    elements = size / data_size;
+@@ -564,8 +580,10 @@
+       width &= ~0xff;
+    assert(width > 0);
+
+-   if (!PUSH_SPACE(push, 40))
++   if (!PUSH_SPACE(push, 40)) {
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
+
+@@ -613,6 +631,8 @@
+    }
+
+    nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
++
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+ }
+
+ static void
+@@ -635,8 +655,11 @@
+
+    assert(dst->texture->target != PIPE_BUFFER);
+
+-   if (!PUSH_SPACE(push, 32 + sf->depth))
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++   if (!PUSH_SPACE(push, 32 + sf->depth)) {
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
++   }
+
+    PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
+
+@@ -685,6 +708,8 @@
+       IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
+
+    nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
++
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+ }
+
+ void
+@@ -698,9 +723,13 @@
+    unsigned i, j, k;
+    uint32_t mode = 0;
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
+    /* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
+-   if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER))
++   if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER)) {
++      pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+       return;
++   }
+
+    if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+       BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
+@@ -759,6 +788,8 @@
+                     (j << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
+       }
+    }
++
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+ }
+
+
+@@ -1171,8 +1202,8 @@
+    nvc0->samplers_dirty[4] |= 3;
+
+    if (nvc0->cond_query && !blit->render_condition_enable)
+-      nvc0->base.pipe.render_condition(&nvc0->base.pipe, nvc0->cond_query,
+-                                       nvc0->cond_cond, nvc0->cond_mode);
++      nvc0_render_condition(&nvc0->base.pipe, nvc0->cond_query,
++                            nvc0->cond_cond, nvc0->cond_mode);
+
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX_TMP);
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB);
+@@ -1634,6 +1665,8 @@
+    if (info->num_window_rectangles > 0 || info->window_rectangle_include)
+       eng3d = true;
+
++   pipe_mutex_lock(nvc0->screen->base.push_mutex);
++
+    if (nvc0->screen->num_occlusion_queries_active)
+       IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
+
+@@ -1645,6 +1678,8 @@
+    if (nvc0->screen->num_occlusion_queries_active)
+       IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
+
++   pipe_mutex_unlock(nvc0->screen->base.push_mutex);
++
+    NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1);
+ }
+
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c       
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c    
2017-09-27 12:14:56.382114407 +0200
+@@ -366,16 +366,18 @@
+    return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, 
&nvc0->base.debug);
+ }
+
+-void *
+-nvc0_miptree_transfer_map(struct pipe_context *pctx,
+-                          struct pipe_resource *res,
+-                          unsigned level,
+-                          unsigned usage,
+-                          const struct pipe_box *box,
+-                          struct pipe_transfer **ptransfer)
++static void *
++nvc0_miptree_transfer_map_unlocked(
++      struct pipe_context *pctx,
++      struct pipe_resource *res,
++      unsigned level,
++      unsigned usage,
++      const struct pipe_box *box,
++      struct pipe_transfer **ptransfer)
+ {
+    struct nvc0_context *nvc0 = nvc0_context(pctx);
+-   struct nouveau_device *dev = nvc0->screen->base.device;
++   struct nvc0_screen *screen = nvc0->screen;
++   struct nouveau_device *dev = screen->base.device;
+    struct nv50_miptree *mt = nv50_miptree(res);
+    struct nvc0_transfer *tx;
+    uint32_t size;
+@@ -489,9 +491,29 @@
+    return tx->rect[1].bo->map;
+ }
+
+-void
+-nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
+-                            struct pipe_transfer *transfer)
++void *
++nvc0_miptree_transfer_map(
++      struct pipe_context *pctx,
++      struct pipe_resource *res,
++      unsigned level,
++      unsigned usage,
++      const struct pipe_box *box,
++      struct pipe_transfer **ptransfer)
++{
++   struct nvc0_context *nvc0 = nvc0_context(pctx);
++   struct nvc0_screen *screen = nvc0->screen;
++
++   pipe_mutex_lock(screen->base.push_mutex);
++   void *ret = nvc0_miptree_transfer_map_unlocked(
++         pctx, res, level, usage, box, ptransfer);
++   pipe_mutex_unlock(screen->base.push_mutex);
++
++   return ret;
++}
++
++static void
++nvc0_miptree_transfer_unmap_unlocked(struct pipe_context *pctx,
++                                     struct pipe_transfer *transfer)
+ {
+    struct nvc0_context *nvc0 = nvc0_context(pctx);
+    struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
+@@ -531,6 +553,18 @@
+    FREE(tx);
+ }
+
++void
++nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
++                            struct pipe_transfer *transfer)
++{
++   struct nvc0_context *nvc0 = nvc0_context(pctx);
++   struct nvc0_screen *screen = nvc0->screen;
++
++   pipe_mutex_lock(screen->base.push_mutex);
++   nvc0_miptree_transfer_unmap_unlocked(pctx, transfer);
++   pipe_mutex_unlock(screen->base.push_mutex);
++}
++
+ /* This happens rather often with DTD9/st. */
+ static void
+ nvc0_cb_push(struct nouveau_context *nv,
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c    2017-09-18 
01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c 
2017-09-27 12:26:24.165064878 +0200
+@@ -921,6 +921,8 @@
+    struct nvc0_screen *screen = nvc0->screen;
+    int s;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
+    nvc0->vb_elt_first = info->min_index + info->index_bias;
+    nvc0->vb_elt_limit = info->max_index - info->min_index;
+@@ -1083,4 +1085,5 @@
+    nouveau_pushbuf_bufctx(push, NULL);
+
+    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_IDX);
++   pipe_mutex_unlock(screen->base.push_mutex);
+ }
+diff -ur mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nve4_compute.c 
mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+--- mesa-17.2.1/src/gallium/drivers/nouveau/nvc0/nve4_compute.c        
2017-09-18 01:03:22.000000000 +0200
++++ mesa-17.2.1-nouvlock-1/src/gallium/drivers/nouveau/nvc0/nve4_compute.c     
2017-09-27 12:28:05.022595701 +0200
+@@ -667,12 +667,15 @@
+ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
+ {
+    struct nvc0_context *nvc0 = nvc0_context(pipe);
++   struct nvc0_screen *screen = nvc0->screen;
+    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
+    void *desc;
+    uint64_t desc_gpuaddr;
+    struct nouveau_bo *desc_bo;
+    int ret;
+
++   pipe_mutex_lock(screen->base.push_mutex);
++
+    desc = nve4_compute_alloc_launch_desc(&nvc0->base, &desc_bo, 
&desc_gpuaddr);
+    if (!desc) {
+       ret = -1;
+@@ -742,6 +745,7 @@
+       NOUVEAU_ERR("Failed to launch grid !\n");
+    nouveau_scratch_done(&nvc0->base);
+    nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_DESC);
++   pipe_mutex_unlock(screen->base.push_mutex);
+ }
+
+
diff --git a/source/x11/mesa/nouveau_locking_2.patch 
b/source/x11/mesa/nouveau_locking_2.patch
new file mode 100644
index 0000000..b6690a7
--- /dev/null
+++ b/source/x11/mesa/nouveau_locking_2.patch
@@ -0,0 +1,94 @@
+
+From 2733e5483e1c2b80e4b0ae21187ec5e3e1579397 Mon Sep 17 00:00:00 2001
+From: Ilia Mirkin <imir...@alum.mit.edu>
+Date: Mon, 6 Jun 2016 20:30:48 -0400
+Subject: [PATCH 3/4] nouveau: more locking - make sure that fence work is
+ always done with the push mutex acquired
+
+---
+ src/gallium/drivers/nouveau/nouveau_buffer.c     | 4 ++++
+ src/gallium/drivers/nouveau/nv50/nv50_miptree.c  | 7 +++++--
+ src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 5 ++++-
+ src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 5 ++++-
+ 4 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c 
b/src/gallium/drivers/nouveau/nouveau_buffer.c
+index 58fa453..a006e9f 100644
+--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
++++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
+@@ -80,6 +80,8 @@ release_allocation(struct nouveau_mm_allocation **mm,
+ inline void
+ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
+ {
++   if (buf->fence)
++      pipe_mutex_lock(buf->fence->screen->push_mutex);
+    if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
+       nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
+       buf->bo = NULL;
+@@ -89,6 +91,8 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
+
+    if (buf->mm)
+       release_allocation(&buf->mm, buf->fence);
++   if (buf->fence)
++      pipe_mutex_unlock(buf->fence->screen->push_mutex);
+
+    if (buf->domain == NOUVEAU_BO_VRAM)
+       NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, 
-(uint64_t)buf->base.width0);
+diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c 
b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+index 7450119..38e4faf 100644
+--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
++++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+@@ -163,10 +163,13 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct 
pipe_resource *pt)
+ {
+    struct nv50_miptree *mt = nv50_miptree(pt);
+
+-   if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
++   if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED) 
{
++      pipe_mutex_lock(nouveau_screen(pscreen)->push_mutex);
+       nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
+-   else
++      pipe_mutex_unlock(nouveau_screen(pscreen)->push_mutex);
++   } else {
+       nouveau_bo_ref(NULL, &mt->base.bo);
++   }
+
+    nouveau_fence_ref(NULL, &mt->base.fence);
+    nouveau_fence_ref(NULL, &mt->base.fence_wr);
+diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c 
b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+index 9067bcc..d2ad72e 100644
+--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
++++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+@@ -56,9 +56,12 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct 
nv50_query *q,
+       if (hq->mm) {
+          if (hq->state == NV50_HW_QUERY_STATE_READY)
+             nouveau_mm_free(hq->mm);
+-         else
++         else {
++            pipe_mutex_lock(screen->base.push_mutex);
+             nouveau_fence_work(screen->base.fence.current,
+                                nouveau_mm_free_work, hq->mm);
++            pipe_mutex_unlock(screen->base.push_mutex);
++         }
+       }
+    }
+    if (size) {
+diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+index f2584cb..4b51a67 100644
+--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
++++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+@@ -48,9 +48,12 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct 
nvc0_query *q,
+       if (hq->mm) {
+          if (hq->state == NVC0_HW_QUERY_STATE_READY)
+             nouveau_mm_free(hq->mm);
+-         else
++         else {
++            pipe_mutex_lock(screen->base.push_mutex);
+             nouveau_fence_work(screen->base.fence.current,
+                                nouveau_mm_free_work, hq->mm);
++            pipe_mutex_unlock(screen->base.push_mutex);
++         }
+       }
+    }
+    if (size) {
+--
+2.1.0
diff --git a/source/x11/mesa/nouveau_locking_3.patch 
b/source/x11/mesa/nouveau_locking_3.patch
new file mode 100644
index 0000000..eab5f54
--- /dev/null
+++ b/source/x11/mesa/nouveau_locking_3.patch
@@ -0,0 +1,117 @@
+
+From 940b3a773f264f3f52574160f0d06c48f8e8aeb2 Mon Sep 17 00:00:00 2001
+From: Ilia Mirkin <imir...@alum.mit.edu>
+Date: Tue, 21 Jun 2016 22:59:50 -0400
+Subject: [PATCH 4/4] nv30 locking fixes
+
+---
+ src/gallium/drivers/nouveau/nv30/nv30_draw.c     | 20 ++++++++++++++++++--
+ src/gallium/drivers/nouveau/nv30/nv30_fragprog.c |  4 ++++
+ 2 files changed, 22 insertions(+), 2 deletions(-)
+
+diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c 
b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+index 10c9f56..c5761a3 100644
+--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
++++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+@@ -127,6 +127,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
+    struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
+    unsigned i;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
+    for (i = 0; i < r->vertex_info.num_attribs; i++) {
+       PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
+@@ -134,8 +136,10 @@ nv30_render_draw_elements(struct vbuf_render *render,
+                        NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 
NV30_3D_VTXBUF_DMA1);
+    }
+
+-   if (!nv30_state_validate(nv30, ~0, false))
++   if (!nv30_state_validate(nv30, ~0, false)) {
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
++   }
+
+    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+    PUSH_DATA (push, r->prim);
+@@ -160,6 +164,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
+    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+    PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+    PUSH_RESET(push, BUFCTX_VTXTMP);
++
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ static void
+@@ -172,6 +178,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, 
unsigned start, uint nr)
+    unsigned ps = fn + (pn ? 1 : 0);
+    unsigned i;
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
+    for (i = 0; i < r->vertex_info.num_attribs; i++) {
+       PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
+@@ -179,8 +187,10 @@ nv30_render_draw_arrays(struct vbuf_render *render, 
unsigned start, uint nr)
+                        NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, 
NV30_3D_VTXBUF_DMA1);
+    }
+
+-   if (!nv30_state_validate(nv30, ~0, false))
++   if (!nv30_state_validate(nv30, ~0, false)) {
++      pipe_mutex_unlock(nv30->screen->base.push_mutex);
+       return;
++   }
+
+    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+    PUSH_DATA (push, r->prim);
+@@ -197,6 +207,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, 
unsigned start, uint nr)
+    BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
+    PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
+    PUSH_RESET(push, BUFCTX_VTXTMP);
++
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
+
+ static void
+@@ -386,6 +398,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct 
pipe_draw_info *info)
+
+    nv30_render_validate(nv30);
+
++   pipe_mutex_unlock(nv30->screen->base.push_mutex);
++
+    if (nv30->draw_dirty & NV30_NEW_VIEWPORT)
+       draw_set_viewport_states(draw, 0, 1, &nv30->viewport);
+    if (nv30->draw_dirty & NV30_NEW_RASTERIZER)
+@@ -451,6 +465,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct 
pipe_draw_info *info)
+       if (transfer[i])
+          pipe_buffer_unmap(pipe, transfer[i]);
+
++   pipe_mutex_lock(nv30->screen->base.push_mutex);
++
+    nv30->draw_dirty = 0;
+    nv30_state_release(nv30);
+ }
+diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c 
b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+index 6de61bc..fd21f99 100644
+--- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
++++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+@@ -38,6 +38,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
+    struct nv30_fragprog *fp = nv30->fragprog.program;
+    struct pipe_context *pipe = &nv30->base.pipe;
+
++   pipe_mutex_unlock(nv->screen->push_mutex);
++
+    if (unlikely(!fp->buffer))
+       fp->buffer = pipe_buffer_create(pipe->screen, 0, 0, fp->insn_len * 4);
+
+@@ -60,6 +62,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
+
+    if (nv04_resource(fp->buffer)->domain != NOUVEAU_BO_VRAM)
+       nouveau_buffer_migrate(nv, nv04_resource(fp->buffer), NOUVEAU_BO_VRAM);
++
++   pipe_mutex_lock(nv->screen->push_mutex);
+ }
+
+ void
+--
+2.1.0
diff --git a/source/x11/mesa/swr-fix.patch b/source/x11/mesa/swr-fix.patch
new file mode 100644
index 0000000..af25598
--- /dev/null
+++ b/source/x11/mesa/swr-fix.patch
@@ -0,0 +1,39 @@
+From 21e271024d8e050b75361c2da2e5783100f2e87b Mon Sep 17 00:00:00 2001
+From: Emil Velikov <emil.veli...@collabora.com>
+Date: Mon, 18 Sep 2017 11:29:21 +0100
+Subject: swr/rast: do not crash on NULL strings returned by getenv
+
+The current convenience function GetEnv feeds the results of getenv
+directly into std::string(). That is a bad idea, since the variable
+may be unset, thus we feed NULL into the C++ construct.
+
+The latter of which is not allowed and leads to a crash.
+
+v2: Better variable name, implicit char* -> std::string conversion (Eric)
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101832
+Fixes: a25093de718 ("swr/rast: Implement JIT shader caching to disk")
+Cc: Tim Rowley <timothy.o.row...@intel.com>
+Cc: Laurent Carlier <lordhea...@gmail.com>
+Cc: Bernhard Rosenkraenzer <b...@lindev.ch>
+[Emil Velikov: make an actual commit from the misc diff]
+Signed-off-by: Emil Velikov <emil.veli...@collabora.com>
+Reviewed-by: Eric Engestrom <eric.engest...@imgtec.com> (v1)
+Reviewed-by: Laurent Carlier <lordhea...@gmail.com> (v1)
+
+diff --git a/src/gallium/drivers/swr/rasterizer/core/utils.h 
b/src/gallium/drivers/swr/rasterizer/core/utils.h
+index b096d21..c926f6a 100644
+--- a/src/gallium/drivers/swr/rasterizer/core/utils.h
++++ b/src/gallium/drivers/swr/rasterizer/core/utils.h
+@@ -365,7 +365,8 @@ static INLINE std::string GetEnv(const std::string& 
variableName)
+     output.resize(valueSize - 1); // valueSize includes null, output.resize() 
does not
+     GetEnvironmentVariableA(variableName.c_str(), &output[0], valueSize);
+ #else
+-    output = getenv(variableName.c_str());
++    char *env = getenv(variableName.c_str());
++    output = env ? env : "";
+ #endif
+
+     return output;
+--
+cgit v0.10.2
\ No newline at end of file
_______________________________________________
Frugalware-git mailing list
Frugalware-git@frugalware.org
http://frugalware.org/mailman/listinfo/frugalware-git

Reply via email to