diff --git a/Mesa.changes b/Mesa.changes index 321a7e7..d3da579 100644 --- a/Mesa.changes +++ b/Mesa.changes @@ -1,3 +1,37 @@ +------------------------------------------------------------------- +Wed Apr 12 13:41:30 UTC 2017 - sndirsch@suse.com + +- only reverse-apply 'U_draw-use-SoA-fetch-not-AoS-one.patch' on + s390x (bsc#1032272) + +------------------------------------------------------------------- +Wed Apr 12 12:31:34 UTC 2017 - sndirsch@suse.com + +- build wayland on Leap >= 42.3 +- separate package 'Mesa-dri-nouveau' on Leap + +------------------------------------------------------------------- +Wed Apr 12 12:15:27 UTC 2017 - sndirsch@suse.com + +- removed broken locking patches for nouveau DRI driver + * N_01-WIP-nouveau-add-locking.patch + * N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch + * N_03-nv30-locking-fixes.patch + * N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch + * N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch + +------------------------------------------------------------------- +Wed Apr 12 09:44:35 UTC 2017 - sndirsch@suse.com + +- let Mesa require Mesa-libGL1 for a libglvnd build (bsc#1033708) + +------------------------------------------------------------------- +Fri Apr 7 14:51:09 UTC 2017 - sndirsch@suse.com + +- U_draw-use-SoA-fetch-not-AoS-one.patch + * reverse-apply this patch to fix OpenGL support on s390x + (bsc#1032272) + ------------------------------------------------------------------- Wed Apr 5 11:32:26 UTC 2017 - afaerber@suse.de diff --git a/Mesa.spec b/Mesa.spec index 3344262..7679bee 100644 --- a/Mesa.spec +++ b/Mesa.spec @@ -16,10 +16,6 @@ # -# Only enable the Nouveau locking patches if you know what you're doing. -# They may fix KDE on Nouveau. They may also deadlock your userland. -%define use_broken_nouveau_locking_patches 0 - %define libglvnd 0 %if 0%{?suse_version} >= 1330 %define libglvnd 1 @@ -90,13 +86,8 @@ Patch32: archlinux_glvnd-fix-gl-dot-pc.patch Patch33: archlinux_0001-EGL-Implement-the-libglvnd-interface-for-EGL-v2.patch Patch34: archlinux_0002-fixup-EGL-Implement-the-libglvnd-interface-for-EGL-v.patch Patch35: fedora_0001-glxglvnddispatch-Add-missing-dispatch-for-GetDriverC.patch - -# Nouveau multithreading workarounds from https://github.com/imirkin/mesa/commits/locking -Patch61: N_01-WIP-nouveau-add-locking.patch -Patch62: N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch -Patch63: N_03-nv30-locking-fixes.patch -Patch64: N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch -Patch65: N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch +# reverse-apply this to fix OpenGL support on s390x (bsc#1032272) +Patch40: U_draw-use-SoA-fetch-not-AoS-one.patch BuildRequires: autoconf >= 2.60 BuildRequires: automake @@ -163,9 +154,9 @@ BuildRequires: libelf-devel %endif %endif # Requirements for wayland bumped up from 17.0 -%if 0%{?suse_version} > 1320 -BuildRequires: pkgconfig(wayland-client) -BuildRequires: pkgconfig(wayland-server) +%if 0%{?suse_version} > 1320 || (0%{?sle_version} >= 120300 && 0%{?is_opensuse}) +BuildRequires: pkgconfig(wayland-client) >= 1.11 +BuildRequires: pkgconfig(wayland-server) >= 1.11 %endif %ifarch aarch64 %arm ppc64 ppc64le s390x %ix86 x86_64 BuildRequires: llvm-devel @@ -178,6 +169,7 @@ BuildRequires: llvm-clang-devel %endif %if 0%{?libglvnd} +Requires: Mesa-libGL1 = %{version} Requires: libglvnd0 >= 0.1.0 %endif @@ -214,7 +206,7 @@ Obsoletes: Mesa-devel-static < %{version} Obsoletes: xorg-x11-Mesa-devel < %{version} Provides: Mesa-libIndirectGL-devel = %{version} Obsoletes: Mesa-libIndirectGL-devel < %{version} -%if 0%{?suse_version} > 1320 +%if 0%{?suse_version} > 1320 || (0%{?sle_version} >= 120300 && 0%{?is_opensuse}) Requires: libwayland-egl-devel %endif @@ -399,8 +391,8 @@ applications using the OpenGL|ES 3.x APIs. %package -n libOSMesa8 Summary: Mesa Off-screen rendering extension -Group: System/Libraries # Wrongly named package shipped .so.8 +Group: System/Libraries Obsoletes: libOSMesa9 < %{version}-%{release} Provides: libOSMesa9 = %{version}-%{release} @@ -506,8 +498,8 @@ implementation of Mesa. %package libd3d Summary: Mesa Direct3D9 state tracker -Group: System/Libraries # Manually provide d3d library (bnc#918294) +Group: System/Libraries %ifarch x86_64 s390x ppc64le aarch64 Provides: d3dadapter9.so.1()(64bit) %else @@ -667,12 +659,9 @@ rm -rf docs/README.{VMS,WIN32,OS2} %patch35 -p1 %endif -%if %{use_broken_nouveau_locking_patches} -%patch61 -p1 -%patch62 -p1 -%patch63 -p1 -%patch64 -p1 -%patch65 -p1 +# reverse-apply this patch to fix OpenGL support on s390x (bsc#1032272) +%ifarch s390x +%patch40 -R -p1 %endif # Remove requires to libglvnd0/libglvnd-devel from baselibs.conf when @@ -683,7 +672,7 @@ grep -v libglvnd $RPM_SOURCE_DIR/baselibs.conf > $RPM_SOURCE_DIR/temp && \ %endif %build -%if 0%{?suse_version} > 1320 +%if 0%{?suse_version} > 1320 || (0%{?sle_version} >= 120300 && 0%{?is_opensuse}) egl_platforms=x11,drm,wayland %else egl_platforms=x11,drm @@ -854,10 +843,12 @@ done %config %{_sysconfdir}/drirc %dir %{_libdir}/dri %{_libdir}/dri/*_dri.so +%if 0%{?is_opensuse} %ifarch %ix86 x86_64 aarch64 %arm ppc64 ppc64le %exclude %{_libdir}/dri/nouveau_dri.so %exclude %{_libdir}/dri/nouveau_vieux_dri.so %endif +%endif %if 0%{with_opencl} # only built with opencl %dir %{_libdir}/gallium-pipe/ @@ -953,7 +944,7 @@ done %{_libdir}/libOSMesa.so %{_libdir}/pkgconfig/osmesa.pc -%if 0%{?suse_version} > 1320 +%if 0%{?suse_version} > 1320 || (0%{?sle_version} >= 120300 && 0%{?is_opensuse}) %files -n libwayland-egl1 %defattr(-,root,root) %{_libdir}/libwayland-egl.so.1* @@ -1049,11 +1040,13 @@ done %{_includedir}/GL/internal %{_libdir}/pkgconfig/dri.pc +%if 0%{?is_opensuse} %ifarch %ix86 x86_64 aarch64 %arm ppc64 ppc64le %files -n Mesa-dri-nouveau %{_libdir}/dri/nouveau_dri.so %{_libdir}/dri/nouveau_vieux_dri.so %endif +%endif %files devel %defattr(-,root,root) diff --git a/N_01-WIP-nouveau-add-locking.patch b/N_01-WIP-nouveau-add-locking.patch deleted file mode 100644 index d5df30a..0000000 --- a/N_01-WIP-nouveau-add-locking.patch +++ /dev/null @@ -1,1763 +0,0 @@ -From: Ilia Mirkin -Date: Sat Jun 4 19:26:26 2016 -0400 -Subject: [PATCH 1/5]WIP nouveau: add locking -Patch-mainline: N/A -References: boo#997171 -Signed-off-by: Max Staudt - -Cherry-picked from 2e6b0e24cfb0f467e8b6d6f394730442a72dcdaf - at https://github.com/imirkin/mesa.git - -Signed-off-by: Max Staudt - -Conflicts: - src/gallium/drivers/nouveau/nvc0/nvc0_surface.c ---- - src/gallium/drivers/nouveau/nouveau_buffer.c | 29 +++++++++-- - src/gallium/drivers/nouveau/nouveau_fence.c | 18 +++++++ - src/gallium/drivers/nouveau/nouveau_fence.h | 5 +- - src/gallium/drivers/nouveau/nouveau_screen.c | 12 ++++- - src/gallium/drivers/nouveau/nouveau_screen.h | 3 ++ - src/gallium/drivers/nouveau/nv30/nv30_clear.c | 22 +++++++-- - src/gallium/drivers/nouveau/nv30/nv30_context.c | 6 +++ - src/gallium/drivers/nouveau/nv30/nv30_miptree.c | 13 ++++- - src/gallium/drivers/nouveau/nv30/nv30_query.c | 9 +++- - src/gallium/drivers/nouveau/nv30/nv30_vbo.c | 5 ++ - src/gallium/drivers/nouveau/nv50/nv50_compute.c | 4 ++ - src/gallium/drivers/nouveau/nv50/nv50_context.c | 11 +++++ - src/gallium/drivers/nouveau/nv50/nv50_context.h | 5 ++ - src/gallium/drivers/nouveau/nv50/nv50_query.c | 14 +++++- - src/gallium/drivers/nouveau/nv50/nv50_query_hw.c | 20 ++++++-- - .../drivers/nouveau/nv50/nv50_query_hw_sm.c | 8 ++++ - src/gallium/drivers/nouveau/nv50/nv50_surface.c | 43 +++++++++++++++-- - src/gallium/drivers/nouveau/nv50/nv50_transfer.c | 6 +++ - src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 5 ++ - src/gallium/drivers/nouveau/nvc0/nvc0_compute.c | 6 +++ - src/gallium/drivers/nouveau/nvc0/nvc0_context.c | 15 ++++++ - src/gallium/drivers/nouveau/nvc0/nvc0_context.h | 5 ++ - src/gallium/drivers/nouveau/nvc0/nvc0_query.c | 14 +++++- - src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c | 16 ++++++- - .../drivers/nouveau/nvc0/nvc0_query_hw_sm.c | 8 ++++ - src/gallium/drivers/nouveau/nvc0/nvc0_screen.c | 2 + - src/gallium/drivers/nouveau/nvc0/nvc0_surface.c | 49 ++++++++++++++++--- - src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c | 56 +++++++++++++++++----- - src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 4 ++ - src/gallium/drivers/nouveau/nvc0/nve4_compute.c | 4 ++ - 30 files changed, 372 insertions(+), 45 deletions(-) - -diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c -index 2db538c..b54c19b 100644 ---- a/src/gallium/drivers/nouveau/nouveau_buffer.c -+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c -@@ -380,6 +380,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, - 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; -@@ -427,14 +428,19 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, - 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; -@@ -479,7 +485,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, - if (unlikely(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) { - /* 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 -@@ -488,10 +496,13 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe, - 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. */ -@@ -515,9 +526,13 @@ nouveau_buffer_transfer_flush_region(struct pipe_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->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, -@@ -537,11 +552,15 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe, - 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 --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c -index 691553a..9cbfc2a 100644 ---- a/src/gallium/drivers/nouveau/nouveau_fence.c -+++ b/src/gallium/drivers/nouveau/nouveau_fence.c -@@ -71,12 +71,14 @@ nouveau_fence_emit(struct nouveau_fence *fence) - - ++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); - -@@ -90,6 +92,9 @@ nouveau_fence_del(struct nouveau_fence *fence) - 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) { -@@ -123,6 +128,7 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed) - 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; -@@ -144,6 +150,7 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed) - 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) -@@ -198,18 +205,27 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debu - 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) -@@ -227,6 +243,8 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debu - fence->sequence, - screen->fence.sequence_ack, screen->fence.sequence); - -+ pipe_mutex_lock(screen->push_mutex); -+ - return false; - } - -diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h -index f10016d..98d021e 100644 ---- a/src/gallium/drivers/nouveau/nouveau_fence.h -+++ b/src/gallium/drivers/nouveau/nouveau_fence.h -@@ -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" - -@@ -47,10 +48,10 @@ static inline void - 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 --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c -index 2c421cc..634fdc3 100644 ---- a/src/gallium/drivers/nouveau/nouveau_screen.c -+++ b/src/gallium/drivers/nouveau/nouveau_screen.c -@@ -73,10 +73,14 @@ nouveau_screen_fence_finish(struct pipe_screen *screen, - 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; - } - - -@@ -153,6 +157,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) - 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. - */ -@@ -253,6 +260,9 @@ nouveau_screen_fini(struct nouveau_screen *screen) - nouveau_device_del(&screen->device); - nouveau_drm_del(&screen->drm); - close(fd); -+ -+ pipe_mutex_destroy(screen->push_mutex); -+ pipe_mutex_destroy(screen->fence.list_mutex); - } - - static void -diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h -index 28c4760..28c8620 100644 ---- a/src/gallium/drivers/nouveau/nouveau_screen.h -+++ b/src/gallium/drivers/nouveau/nouveau_screen.h -@@ -3,6 +3,7 @@ - - #include "pipe/p_screen.h" - #include "util/u_memory.h" -+#include "os/os_thread.h" - - #ifdef DEBUG - # define NOUVEAU_ENABLE_DRIVER_STATISTICS -@@ -22,6 +23,7 @@ struct nouveau_screen { - struct nouveau_object *channel; - struct nouveau_client *client; - struct nouveau_pushbuf *pushbuf; -+ pipe_mutex push_mutex; - - int refcount; - -@@ -39,6 +41,7 @@ struct nouveau_screen { - 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 --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c -index c8fa38e..3a72354 100644 ---- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c -+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c -@@ -58,8 +58,11 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers, - 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 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers, - PUSH_DATA (push, mode); - - nv30_state_release(nv30); -+ pipe_mutex_unlock(nv30->screen->base.push_mutex); - } - - static void -@@ -125,11 +129,15 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps, - 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, 16, 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); -@@ -154,6 +162,8 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps, - 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; - } - -@@ -189,11 +199,15 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps, - 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); -@@ -219,6 +233,8 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps, - 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 --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c -index 3ed0889..fbc4136 100644 ---- a/src/gallium/drivers/nouveau/nv30/nv30_context.c -+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c -@@ -201,6 +201,8 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - 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; -@@ -226,6 +228,7 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - 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; - } - -@@ -259,10 +262,13 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - 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 --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c -index c6f6965..389bfaa 100644 ---- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c -+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c -@@ -130,10 +130,12 @@ nv30_resource_copy_region(struct pipe_context *pipe, - 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 @@ nv30_resource_copy_region(struct pipe_context *pipe, - 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 @@ nv30_resource_resolve(struct nv30_context *nv30, - 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_resource_resolve(struct nv30_context *nv30, - nv30_transfer_rect(nv30, BILINEAR, &src, &dst); - } - } -+ pipe_mutex_unlock(nv30->screen->base.push_mutex); - } - - void -@@ -308,8 +313,12 @@ nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt, - 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 @@ nv30_miptree_transfer_unmap(struct pipe_context *pipe, - 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 --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c b/src/gallium/drivers/nouveau/nv30/nv30_query.c -index aa9a12f..a047e15 100644 ---- a/src/gallium/drivers/nouveau/nv30/nv30_query.c -+++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c -@@ -152,6 +152,7 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) - 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 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) - } - 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 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq) - 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 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq) - 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 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq) - PUSH_DATA (push, 0); - } - PUSH_KICK (push); -+ pipe_mutex_unlock(nv30->screen->base.push_mutex); - return true; - } - -@@ -248,9 +252,11 @@ nv40_query_render_condition(struct pipe_context *pipe, - 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 @@ nv40_query_render_condition(struct pipe_context *pipe, - - 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 --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c -index bc9b9a1..8e3fdee 100644 ---- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c -+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c -@@ -563,6 +563,8 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - 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); -@@ -570,10 +572,12 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - 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; - } - -@@ -630,6 +634,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - - nv30_state_release(nv30); - nv30_release_user_vbufs(nv30); -+ pipe_mutex_unlock(nv30->screen->base.push_mutex); - } - - void -diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c -index d781f6f..3c174e4 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c -@@ -249,9 +249,11 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) - 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 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) - 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c -index 5af0e9b..8a148fc 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_context.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c -@@ -37,7 +37,9 @@ nv50_flush(struct pipe_context *pipe, - 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)); - } -@@ -47,10 +49,12 @@ nv50_texture_barrier(struct pipe_context *pipe) - { - 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 -@@ -107,6 +111,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len) - 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); -@@ -115,6 +120,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len) - memcpy(&data, &str[string_words * 4], len & 3); - PUSH_DATA (push, data); - } -+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex); - } - - void -@@ -291,6 +297,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - return NULL; - pipe = &nv50->base.pipe; - -+ pipe_mutex_lock(screen->base.push_mutex); -+ - if (!nv50_blitctx_create(nv50)) - goto out_err; - -@@ -391,9 +399,12 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - - util_dynarray_init(&nv50->global_residents); - -+ pipe_mutex_unlock(screen->base.push_mutex); -+ - return pipe; - - out_err: -+ pipe_mutex_unlock(screen->base.push_mutex); - if (nv50->bufctx_3d) - nouveau_bufctx_del(&nv50->bufctx_3d); - if (nv50->bufctx_cp) -diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h -index 2317fa2..b7963a4 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_context.h -+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h -@@ -217,6 +217,11 @@ void nv50_default_kick_notify(struct nouveau_pushbuf *); - /* 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c -index 9a1397a..c90e20e 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_query.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c -@@ -70,7 +70,7 @@ nv50_get_query_result(struct pipe_context *pipe, struct pipe_query *pq, - 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, uint mode) -@@ -145,6 +145,16 @@ nv50_render_condition(struct pipe_context *pipe, - } - - 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 @@ nv50_init_query_functions(struct nv50_context *nv50) - 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c -index 727b509..9067bcc 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c -@@ -129,6 +129,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q) - { - 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 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q) - 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 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q) - 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 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q) - - 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 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q) - 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_get_query_result(struct nv50_context *nv50, struct nv50_query *q, - 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -index bcfba9f..31445eb 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -@@ -176,6 +176,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - return false; - } - -+ pipe_mutex_lock(screen->base.push_mutex); - assert(cfg->num_counters <= 4); - PUSH_SPACE(push, 4 * 4); - -@@ -208,6 +209,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - 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 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - 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 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - 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 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - - 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 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq) - | cfg->ctr[i].unit | cfg->ctr[i].mode); - } - } -+ pipe_mutex_unlock(screen->base.push_mutex); - } - - static inline bool -@@ -343,7 +349,9 @@ nv50_hw_sm_get_query_result(struct nv50_context *nv50, struct nv50_hw_query *hq, - - 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c -index 61dec3f..d6b9de0 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c -@@ -204,10 +204,13 @@ nv50_resource_copy_region(struct pipe_context *pipe, - 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 @@ nv50_resource_copy_region(struct pipe_context *pipe, - else - srect.base += src_mt->layer_stride; - } -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - return; - } - -@@ -270,6 +274,7 @@ nv50_resource_copy_region(struct pipe_context *pipe, - break; - } - nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D); -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - } - - static void -@@ -288,14 +293,18 @@ nv50_clear_render_target(struct pipe_context *pipe, - - 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, 32 + sf->depth, 1, 0)) -+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) { -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - return; -+ } - - PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR); - -@@ -353,6 +362,8 @@ nv50_clear_render_target(struct pipe_context *pipe, - BEGIN_NV04(push, NV50_3D(COND_MODE), 1); - 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; - } - -@@ -376,6 +387,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, - 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); -@@ -388,8 +401,10 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, - mode |= NV50_3D_CLEAR_BUFFERS_S; - } - -- if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) -+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) { -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - return; -+ } - - PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR); - -@@ -436,6 +451,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe, - BEGIN_NV04(push, NV50_3D(COND_MODE), 1); - 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; - } - -@@ -524,9 +541,12 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, - 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. */ -@@ -592,6 +612,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers, - /* 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 -@@ -719,14 +740,18 @@ nv50_clear_buffer(struct pipe_context *pipe, - - 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; -@@ -742,8 +767,10 @@ nv50_clear_buffer(struct pipe_context *pipe, - PUSH_DATAf(push, color.f[2]); - PUSH_DATAf(push, color.f[3]); - -- if (nouveau_pushbuf_space(push, 32, 1, 0)) -+ if (nouveau_pushbuf_space(push, 32, 1, 0)) { -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - return; -+ } - - PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR); - -@@ -798,6 +825,8 @@ nv50_clear_buffer(struct pipe_context *pipe, - data, data_size); - } - -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); -+ - nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR; - } - -@@ -1700,6 +1729,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) - 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); -@@ -1714,6 +1745,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) - BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1); - PUSH_DATA (push, 1); - } -+ -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - } - - static void -diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c -index 86a8c15..f5c7c57 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c -@@ -304,6 +304,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx, - 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 @@ nv50_miptree_transfer_map(struct pipe_context *pctx, - 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 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx, - 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 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx, - /* 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 --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c -index a11cdf8..f73329c 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c -@@ -767,6 +767,8 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - bool tex_dirty = false; - int s; - -+ pipe_mutex_lock(nv50->screen->base.push_mutex); -+ - /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */ - nv50->vb_elt_first = info->min_index + info->index_bias; - nv50->vb_elt_limit = info->max_index - info->min_index; -@@ -827,6 +829,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - nv50_push_vbo(nv50, info); - push->kick_notify = nv50_default_kick_notify; - nouveau_pushbuf_bufctx(push, NULL); -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - return; - } - -@@ -886,4 +889,6 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - nv50_release_user_vbufs(nv50); - - nouveau_pushbuf_bufctx(push, NULL); -+ -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - } -diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c -index 59bbe1e..7511819 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c -@@ -388,13 +388,17 @@ void - 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; - } - -@@ -462,4 +466,6 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) - 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c -index 1c5f954..12d5b0e 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c -@@ -38,7 +38,9 @@ nvc0_flush(struct pipe_context *pipe, - 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); - } -@@ -48,8 +50,10 @@ nvc0_texture_barrier(struct pipe_context *pipe) - { - 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 -@@ -59,6 +63,8 @@ nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags) - 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) -@@ -108,6 +114,8 @@ nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags) - 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 -@@ -124,6 +132,7 @@ nvc0_emit_string_marker(struct pipe_context *pipe, const char *str, int len) - 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); -@@ -132,6 +141,7 @@ nvc0_emit_string_marker(struct pipe_context *pipe, const char *str, int len) - memcpy(&data, &str[string_words * 4], len & 3); - PUSH_DATA (push, data); - } -+ pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex); - } - - static void -@@ -362,6 +372,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - return NULL; - pipe = &nvc0->base.pipe; - -+ pipe_mutex_lock(screen->base.push_mutex); -+ - if (!nvc0_blitctx_create(nvc0)) - goto out_err; - -@@ -465,9 +477,12 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags) - - util_dynarray_init(&nvc0->global_residents); - -+ pipe_mutex_unlock(screen->base.push_mutex); -+ - return pipe; - - out_err: -+ pipe_mutex_unlock(screen->base.push_mutex); - if (nvc0) { - if (nvc0->bufctx_3d) - nouveau_bufctx_del(&nvc0->bufctx_3d); -diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h -index 6e1548d..ff5467c 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h -@@ -293,6 +293,11 @@ uint32_t nvc0_program_symbol_offset(const struct nvc0_program *, - 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c -index 91fb72f..55d1dc1 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c -@@ -92,7 +92,7 @@ nvc0_get_query_result_resource(struct pipe_context *pipe, - index, resource, offset); - } - --static void -+void - nvc0_render_condition(struct pipe_context *pipe, - struct pipe_query *pq, - boolean condition, uint mode) -@@ -161,6 +161,16 @@ nvc0_render_condition(struct pipe_context *pipe, - PUSH_DATA (push, hq->bo->offset + hq->offset); - } - -+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, -@@ -272,6 +282,6 @@ nvc0_init_query_functions(struct nvc0_context *nvc0) - 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c -index 4c34593..f2584cb 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c -@@ -154,6 +154,7 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct nvc0_query *q) - } - 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 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct nvc0_query *q) - default: - break; - } -+ pipe_mutex_unlock(nvc0->screen->base.push_mutex); - hq->state = NVC0_HW_QUERY_STATE_ACTIVE; - return ret; - } -@@ -221,6 +223,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q) - } - 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 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q) - 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_get_query_result(struct nvc0_context *nvc0, struct nvc0_query *q, - 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; -@@ -374,6 +383,8 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0, - - 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) -@@ -382,6 +393,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0, - 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 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0, - 4 | NVC0_IB_ENTRY_1_NO_PREFETCH); - } - -+ 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c -index 27cbbc4..d416e00 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c -@@ -1662,6 +1662,7 @@ nve4_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - return false; - } - -+ pipe_mutex_lock(screen->base.push_mutex); - assert(cfg->num_counters <= 4); - PUSH_SPACE(push, 4 * 8 * + 6); - -@@ -1710,6 +1711,7 @@ nve4_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - BEGIN_NVC0(push, NVE4_CP(MP_PM_SET(c)), 1); - PUSH_DATA (push, 0); - } -+ pipe_mutex_unlock(screen->base.push_mutex); - return true; - } - -@@ -1733,6 +1735,7 @@ nvc0_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - return false; - } - -+ pipe_mutex_lock(screen->base.push_mutex); - assert(cfg->num_counters <= 8); - PUSH_SPACE(push, 8 * 8 + 2); - -@@ -1779,6 +1782,7 @@ nvc0_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - BEGIN_NVC0(push, NVC0_CP(MP_PM_SET(c)), 1); - PUSH_DATA (push, 0); - } -+ pipe_mutex_unlock(screen->base.push_mutex); - return true; - } - -@@ -1866,6 +1870,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - 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) -@@ -1893,6 +1898,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - - /* 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++) { -@@ -1906,6 +1912,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - - 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; -@@ -1930,6 +1937,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq) - PUSH_DATA (push, (cfg->ctr[i].func << 4) | cfg->ctr[i].mode); - } - } -+ pipe_mutex_unlock(screen->base.push_mutex); - } - - static inline bool -diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c -index 6541241..1d280d8 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c -@@ -491,7 +491,9 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) - * _current_ one, and remove both. - */ - nouveau_fence_ref(screen->base.fence.current, ¤t); -+ pipe_mutex_lock(screen->base.push_mutex); - nouveau_fence_wait(current, NULL); -+ pipe_mutex_unlock(screen->base.push_mutex); - nouveau_fence_ref(NULL, ¤t); - nouveau_fence_ref(NULL, &screen->base.fence.current); - } -diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c -index a177569..67bd183 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c -@@ -206,11 +206,14 @@ nvc0_resource_copy_region(struct pipe_context *pipe, - 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 @@ nvc0_resource_copy_region(struct pipe_context *pipe, - else - srect.base += src_mt->layer_stride; - } -+ pipe_mutex_unlock(nvc0->screen->base.push_mutex); - return; - } - -@@ -273,6 +277,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe, - break; - } - nouveau_bufctx_reset(nvc0->bufctx, 0); -+ pipe_mutex_unlock(nvc0->screen->base.push_mutex); - } - - static void -@@ -290,8 +295,12 @@ nvc0_clear_render_target(struct pipe_context *pipe, - - 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); - -@@ -354,6 +363,8 @@ nvc0_clear_render_target(struct pipe_context *pipe, - 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 -@@ -539,8 +550,11 @@ nvc0_clear_buffer(struct pipe_context *pipe, - - 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; - } - -@@ -550,8 +564,10 @@ nvc0_clear_buffer(struct pipe_context *pipe, - 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; -@@ -561,8 +577,10 @@ nvc0_clear_buffer(struct pipe_context *pipe, - 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); - -@@ -610,6 +628,8 @@ nvc0_clear_buffer(struct pipe_context *pipe, - } - - nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER; -+ -+ pipe_mutex_unlock(nvc0->screen->base.push_mutex); - } - - static void -@@ -631,8 +651,11 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, - - 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); - -@@ -679,6 +702,8 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe, - 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 -@@ -692,9 +717,13 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, - 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); -@@ -753,6 +782,8 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers, - (j << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT)); - } - } -+ -+ pipe_mutex_unlock(nvc0->screen->base.push_mutex); - } - - -@@ -1146,8 +1177,8 @@ nvc0_blitctx_post_blit(struct nvc0_blitctx *blit) - 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); -@@ -1606,6 +1637,8 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) - info->src.box.height != -info->dst.box.height)) - 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); - -@@ -1617,6 +1650,8 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info) - 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c -index 14fb53c..6cb39a9 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c -@@ -342,16 +342,18 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage) - 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; -@@ -465,9 +467,29 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx, - 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; -@@ -507,6 +529,18 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx, - 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 --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c -index 94274bc..3d20c68 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c -+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c -@@ -940,6 +940,8 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - 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; -@@ -1033,6 +1035,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - nvc0_push_vbo(nvc0, info); - push->kick_notify = nvc0_default_kick_notify; - nouveau_pushbuf_bufctx(push, NULL); -+ pipe_mutex_unlock(screen->base.push_mutex); - return; - } - -@@ -1085,4 +1088,5 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) - nvc0_release_user_vbufs(nvc0); - - nouveau_pushbuf_bufctx(push, NULL); -+ pipe_mutex_unlock(screen->base.push_mutex); - } -diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c -index f2e608d..d172d73 100644 ---- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c -+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c -@@ -535,12 +535,15 @@ void - 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; - struct nve4_cp_launch_desc *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; -@@ -621,6 +624,7 @@ out: - 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/N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch b/N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch deleted file mode 100644 index 2372320..0000000 --- a/N_02-nouveau-more-locking-make-sure-that-fence-work-is-always-done-with-the-push-mutex-acquired.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: Ilia Mirkin -Date: Mon Jun 6 20:30:48 2016 -0400 -Subject: [PATCH 2/5]nouveau: more locking - make sure that fence work is always done with the push mutex acquired -Patch-mainline: N/A -References: boo#997171 -Signed-off-by: Max Staudt - -Cherry-picked from 2733e5483e1c2b80e4b0ae21187ec5e3e1579397 - at https://github.com/imirkin/mesa.git - -Signed-off-by: Max Staudt ---- - 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 b54c19b..a5a06cf 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) { diff --git a/N_03-nv30-locking-fixes.patch b/N_03-nv30-locking-fixes.patch deleted file mode 100644 index 0386831..0000000 --- a/N_03-nv30-locking-fixes.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Ilia Mirkin -Date: Tue Jun 21 22:59:50 2016 -0400 -Subject: [PATCH 3/5]nv30 locking fixes -Patch-mainline: N/A -References: boo#997171 -Signed-off-by: Max Staudt - -Cherry-picked from 940b3a773f264f3f52574160f0d06c48f8e8aeb2 - at https://github.com/imirkin/mesa.git - -Signed-off-by: Max Staudt ---- - 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 7b0d074..1c71534 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 -@@ -383,6 +395,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) -@@ -448,6 +462,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 diff --git a/N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch b/N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch deleted file mode 100644 index 67c9cd0..0000000 --- a/N_04-nv50-Fix-double-lock-in-nv50_hw_sm_get_query_result.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Max Staudt -Date: Wed Oct 5 18:49:41 2016 +0200 -Subject: [PATCH 4/5]nv50: Fix double lock in nv50_hw_sm_get_query_result() -Patch-mainline: N/A -References: boo#997171 -Signed-off-by: Max Staudt - -Signed-off-by: Max Staudt ---- - src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -index 31445eb..acc64ac 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c -@@ -351,7 +351,7 @@ nv50_hw_sm_get_query_result(struct nv50_context *nv50, struct nv50_hw_query *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); -+ pipe_mutex_unlock(nv50->screen->base.push_mutex); - if (!ret) - return false; - diff --git a/N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch b/N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch deleted file mode 100644 index ef8317c..0000000 --- a/N_05-Use-nv50_render_condition-in-nv50_blitctx_post_blit.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Max Staudt -Date: Wed Oct 5 18:51:38 2016 +0200 -Subject: [PATCH 5/5]Use nv50_render_condition() in nv50_blitctx_post_blit() -Patch-mainline: N/A -References: boo#997171 -Signed-off-by: Max Staudt - -Analogous to what happens in nvc0_blitctx_post_blit() - -Signed-off-by: Max Staudt ---- - src/gallium/drivers/nouveau/nv50/nv50_surface.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c -index d6b9de0..36cd72b 100644 ---- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c -+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c -@@ -1328,8 +1328,8 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit) - nv50->samplers[2][1] = blit->saved.sampler[1]; - - if (nv50->cond_query && !blit->render_condition_enable) -- nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query, -- nv50->cond_cond, nv50->cond_mode); -+ nv50_render_condition(&nv50->base.pipe, nv50->cond_query, -+ nv50->cond_cond, nv50->cond_mode); - - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_FB); - nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_3D_TEXTURES); diff --git a/U_draw-use-SoA-fetch-not-AoS-one.patch b/U_draw-use-SoA-fetch-not-AoS-one.patch new file mode 100644 index 0000000..8d1bc51 --- /dev/null +++ b/U_draw-use-SoA-fetch-not-AoS-one.patch @@ -0,0 +1,136 @@ +From e827d9175675aaa6cfc0b981e2a80685fb7b3a74 Mon Sep 17 00:00:00 2001 +From: Roland Scheidegger +Date: Wed, 21 Dec 2016 04:43:07 +0100 +Subject: [PATCH] draw: use SoA fetch, not AoS one + +Now that there's some SoA fetch which never falls back, we should always get +results which are better or at least not worse (something like rgba32f will +stay the same). + +For cases which get way better, think something like R16_UNORM with 8-wide +vectors: this was 8 sign-extend fetches, 8 cvt, 8 muls, followed by +a couple of shuffles to stitch things together (if it is smart enough, +6 unpacks) and then a (8-wide) transpose (not sure if llvm could even +optimize the shuffles + transpose, since the 16bit values were actually +sign-extended to 128bit before being cast to a float vec, so that would be +another 8 unpacks). Now that is just 8 fetches (directly inserted into +vector, albeit there's one 128bit insert needed), 1 cvt, 1 mul. + +v2: ditch the old AoS code instead of just disabling it. + +Reviewed-by: Jose Fonseca +--- + src/gallium/auxiliary/draw/draw_llvm.c | 71 +++++++++++----------------------- + 1 file changed, 23 insertions(+), 48 deletions(-) + +diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c +index 19b75a5003..8952dc8d3b 100644 +--- a/src/gallium/auxiliary/draw/draw_llvm.c ++++ b/src/gallium/auxiliary/draw/draw_llvm.c +@@ -713,39 +713,6 @@ fetch_instanced(struct gallivm_state *gallivm, + + + static void +-convert_to_soa(struct gallivm_state *gallivm, +- LLVMValueRef src_aos[LP_MAX_VECTOR_WIDTH / 32], +- LLVMValueRef dst_soa[TGSI_NUM_CHANNELS], +- const struct lp_type soa_type) +-{ +- unsigned j, k; +- struct lp_type aos_channel_type = soa_type; +- +- LLVMValueRef aos_channels[TGSI_NUM_CHANNELS]; +- unsigned pixels_per_channel = soa_type.length / TGSI_NUM_CHANNELS; +- +- debug_assert(TGSI_NUM_CHANNELS == 4); +- debug_assert((soa_type.length % TGSI_NUM_CHANNELS) == 0); +- +- aos_channel_type.length >>= 1; +- +- for (j = 0; j < TGSI_NUM_CHANNELS; ++j) { +- LLVMValueRef channel[LP_MAX_VECTOR_LENGTH] = { 0 }; +- +- assert(pixels_per_channel <= LP_MAX_VECTOR_LENGTH); +- +- for (k = 0; k < pixels_per_channel; ++k) { +- channel[k] = src_aos[j + TGSI_NUM_CHANNELS * k]; +- } +- +- aos_channels[j] = lp_build_concat(gallivm, channel, aos_channel_type, pixels_per_channel); +- } +- +- lp_build_transpose_aos(gallivm, soa_type, aos_channels, dst_soa); +-} +- +- +-static void + fetch_vector(struct gallivm_state *gallivm, + const struct util_format_description *format_desc, + struct lp_type vs_type, +@@ -755,11 +722,10 @@ fetch_vector(struct gallivm_state *gallivm, + LLVMValueRef *inputs, + LLVMValueRef indices) + { +- LLVMValueRef zero = LLVMConstNull(LLVMInt32TypeInContext(gallivm->context)); + LLVMBuilderRef builder = gallivm->builder; + struct lp_build_context blduivec; ++ struct lp_type fetch_type = vs_type; + LLVMValueRef offset, valid_mask; +- LLVMValueRef aos_fetch[LP_MAX_VECTOR_WIDTH / 32]; + unsigned i; + + lp_build_context_init(&blduivec, gallivm, lp_uint_type(vs_type)); +@@ -783,28 +749,37 @@ fetch_vector(struct gallivm_state *gallivm, + } + + /* +- * Note: we probably really want to use SoA fetch, not AoS one (albeit +- * for most formats it will amount to the same as this isn't very +- * optimized). But looks dangerous since it assumes alignment. ++ * Unlike fetch_instanced, use SoA fetch instead of multiple AoS fetches. ++ * This should always produce better code. + */ +- for (i = 0; i < vs_type.length; i++) { +- LLVMValueRef offset1, elem; +- elem = lp_build_const_int32(gallivm, i); +- offset1 = LLVMBuildExtractElement(builder, offset, elem, ""); + +- aos_fetch[i] = lp_build_fetch_rgba_aos(gallivm, format_desc, +- lp_float32_vec4_type(), +- FALSE, map_ptr, offset1, +- zero, zero, NULL); ++ /* The type handling is annoying here... */ ++ if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB && ++ format_desc->channel[0].pure_integer) { ++ if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { ++ fetch_type = lp_type_int_vec(vs_type.width, vs_type.width * vs_type.length); ++ } ++ else if (format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) { ++ fetch_type = lp_type_uint_vec(vs_type.width, vs_type.width * vs_type.length); ++ } + } +- convert_to_soa(gallivm, aos_fetch, inputs, vs_type); ++ ++ lp_build_fetch_rgba_soa(gallivm, format_desc, ++ fetch_type, FALSE, map_ptr, offset, ++ blduivec.zero, blduivec.zero, ++ NULL, inputs); + + for (i = 0; i < TGSI_NUM_CHANNELS; i++) { ++ inputs[i] = LLVMBuildBitCast(builder, inputs[i], ++ lp_build_vec_type(gallivm, vs_type), ""); ++ } ++ ++ /* out-of-bound fetches return all zeros */ ++ for (i = 0; i < TGSI_NUM_CHANNELS; i++) { + inputs[i] = LLVMBuildBitCast(builder, inputs[i], blduivec.vec_type, ""); + inputs[i] = LLVMBuildAnd(builder, inputs[i], valid_mask, ""); + inputs[i] = LLVMBuildBitCast(builder, inputs[i], + lp_build_vec_type(gallivm, vs_type), ""); +- + } + } + +-- +2.12.0 +