Hello community,

here is the log from the commit of package Mesa for openSUSE:Factory checked in 
at 2014-03-22 19:46:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/Mesa (Old)
 and      /work/SRC/openSUSE:Factory/.Mesa.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "Mesa"

Changes:
--------
--- /work/SRC/openSUSE:Factory/Mesa/Mesa.changes        2014-03-11 
20:33:24.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.Mesa.new/Mesa.changes   2014-03-22 
19:46:01.000000000 +0100
@@ -1,0 +2,10 @@
+Thu Mar 13 15:20:17 UTC 2014 - [email protected]
+
+- Add U_gallium_util_add_missing_u_math_include.patch (patch27)
+- Add U_nouveau_create_only_one_shared_screen.patch (patch28)
+- Add U_nouveau_add_valid_range_tracking.patch (patch29)
+- Add U_nouveau_fix_fence_waiting_logic.patch (patch30)
+  + https://bugzilla.novell.com/show_bug.cgi?id=866445
+  + https://bugs.freedesktop.org/show_bug.cgi?id=75279
+  
+-------------------------------------------------------------------

New:
----
  U_gallium_util_add_missing_u_math_include.patch
  U_nouveau_add_valid_range_tracking.patch
  U_nouveau_create_only_one_shared_screen.patch
  U_nouveau_fix_fence_waiting_logic.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ Mesa.spec ++++++
--- /var/tmp/diff_new_pack.fhj4oh/_old  2014-03-22 19:46:02.000000000 +0100
+++ /var/tmp/diff_new_pack.fhj4oh/_new  2014-03-22 19:46:02.000000000 +0100
@@ -118,6 +118,11 @@
 Patch13:        u_mesa-8.0.1-fix-16bpp.patch
 # Patch from Fedora, use shmget when available, under llvmpipe
 Patch15:        u_mesa-8.0-llvmpipe-shmget.patch
+# BNC#866445
+Patch27:        U_gallium_util_add_missing_u_math_include.patch
+Patch28:        U_nouveau_create_only_one_shared_screen.patch
+Patch29:        U_nouveau_add_valid_range_tracking.patch
+Patch30:        U_nouveau_fix_fence_waiting_logic.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -482,6 +487,11 @@
 #%patch11 -p1
 #%patch15 -p1
 #%patch13 -p1
+###
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
 
 %build
 rm -f src/mesa/depend

++++++ U_gallium_util_add_missing_u_math_include.patch ++++++
>From f19271c7bf73efe6d583e9dc5fc37329558a5cc3 Mon Sep 17 00:00:00 2001
From: Ilia Mirkin <[email protected]>
Date: Thu, 27 Feb 2014 06:07:30 +0000
Subject: gallium/util: add missing u_math include

This is needed for MIN2/MAX2

Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
---
diff --git a/src/gallium/auxiliary/util/u_range.h 
b/src/gallium/auxiliary/util/u_range.h
index 4b1d0d1..efe25ef 100644
--- a/src/gallium/auxiliary/util/u_range.h
+++ b/src/gallium/auxiliary/util/u_range.h
@@ -36,6 +36,8 @@
 
 #include "os/os_thread.h"
 
+#include "util/u_math.h"
+
 struct util_range {
    unsigned start; /* inclusive */
    unsigned end; /* exclusive */
--
cgit v0.9.0.2-2-gbebe
 
++++++ U_nouveau_add_valid_range_tracking.patch ++++++
>From 5bf90cb521d1d6f26684b1ce9d0811c636b6abb1 Mon Sep 17 00:00:00 2001
From: Ilia Mirkin <[email protected]>
Date: Thu, 27 Feb 2014 06:07:51 +0000
Subject: nouveau: add valid range tracking to nouveau_buffer

This logic is borrowed from the radeon code. The transfer logic will
only get called for PIPE_BUFFER resources, so it shouldn't be necessary
to worry about them becoming render targets.

Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Christoph Bumiller <[email protected]>
---
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c 
b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 5b0b93b..e308ff4 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -69,6 +69,8 @@ nouveau_buffer_allocate(struct nouveau_screen *screen,
    if (buf->bo)
       buf->address = buf->bo->offset + buf->offset;
 
+   util_range_set_empty(&buf->valid_buffer_range);
+
    return TRUE;
 }
 
@@ -124,6 +126,8 @@ nouveau_buffer_destroy(struct pipe_screen *pscreen,
    nouveau_fence_ref(NULL, &res->fence);
    nouveau_fence_ref(NULL, &res->fence_wr);
 
+   util_range_destroy(&res->valid_buffer_range);
+
    FREE(res);
 
    NOUVEAU_DRV_STAT(nouveau_screen(pscreen), buf_obj_current_count, -1);
@@ -387,6 +391,17 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
    if (usage & PIPE_TRANSFER_WRITE)
       NOUVEAU_DRV_STAT(nv->screen, buf_transfers_wr, 1);
 
+   /* If we are trying to write to an uninitialized range, the user shouldn't
+    * care what was there before. So we can treat the write as if the target
+    * range were being discarded. Furthermore, since we know that even if this
+    * buffer is busy due to GPU activity, because the contents were
+    * uninitialized, the GPU can't care what was there, and so we can treat
+    * the write as being unsynchronized.
+    */
+   if ((usage & PIPE_TRANSFER_WRITE) &&
+       !util_ranges_intersect(&buf->valid_buffer_range, box->x, box->x + 
box->width))
+      usage |= PIPE_TRANSFER_DISCARD_RANGE | PIPE_TRANSFER_UNSYNCHRONIZED;
+
    if (buf->domain == NOUVEAU_BO_VRAM) {
       if (usage & NOUVEAU_TRANSFER_DISCARD) {
          /* Set up a staging area for the user to write to. It will be copied
@@ -492,8 +507,14 @@ nouveau_buffer_transfer_flush_region(struct pipe_context 
*pipe,
                                      const struct pipe_box *box)
 {
    struct nouveau_transfer *tx = nouveau_transfer(transfer);
+   struct nv04_resource *buf = nv04_resource(transfer->resource);
+
    if (tx->map)
       nouveau_transfer_write(nouveau_context(pipe), tx, box->x, box->width);
+
+   util_range_add(&buf->valid_buffer_range,
+                  tx->base.box.x + box->x,
+                  tx->base.box.x + box->x + box->width);
 }
 
 /* Unmap stage of the transfer. If it was a WRITE transfer and the map that
@@ -522,6 +543,9 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
          if (bind & (PIPE_BIND_CONSTANT_BUFFER))
             nv->cb_dirty = TRUE;
       }
+
+      util_range_add(&buf->valid_buffer_range,
+                     tx->base.box.x, tx->base.box.x + tx->base.box.width);
    }
 
    if (!tx->bo && (tx->base.usage & PIPE_TRANSFER_WRITE))
@@ -562,6 +586,8 @@ nouveau_copy_buffer(struct nouveau_context *nv,
                                 &dst->base, 0, dstx, 0, 0,
                                 &src->base, 0, &src_box);
    }
+
+   util_range_add(&dst->valid_buffer_range, dstx, dstx + size);
 }
 
 
@@ -659,6 +685,8 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
 
    NOUVEAU_DRV_STAT(screen, buf_obj_current_count, 1);
 
+   util_range_init(&buffer->valid_buffer_range);
+
    return &buffer->base;
 
 fail:
@@ -690,6 +718,9 @@ nouveau_user_buffer_create(struct pipe_screen *pscreen, 
void *ptr,
    buffer->data = ptr;
    buffer->status = NOUVEAU_BUFFER_STATUS_USER_MEMORY;
 
+   util_range_init(&buffer->valid_buffer_range);
+   util_range_add(&buffer->valid_buffer_range, 0, bytes);
+
    return &buffer->base;
 }
 
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.h 
b/src/gallium/drivers/nouveau/nouveau_buffer.h
index aeb9b17..f881adc 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.h
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.h
@@ -1,6 +1,7 @@
 #ifndef __NOUVEAU_BUFFER_H__
 #define __NOUVEAU_BUFFER_H__
 
+#include "util/u_range.h"
 #include "util/u_transfer.h"
 #include "util/u_double_list.h"
 
@@ -44,6 +45,9 @@ struct nv04_resource {
    struct nouveau_fence *fence_wr;
 
    struct nouveau_mm_allocation *mm;
+
+   /* buffer range that has been initialized */
+   struct util_range valid_buffer_range;
 };
 
 void
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_resource.c 
b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
index 7fbb0a9..d289b4a 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_resource.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_resource.c
@@ -68,6 +68,8 @@ nv50_surface_create(struct pipe_context *pipe,
                    struct pipe_resource *pres,
                    const struct pipe_surface *templ)
 {
+   /* surfaces are assumed to be miptrees all over the place. */
+   assert(pres->target != PIPE_BUFFER);
    if (unlikely(pres->target == PIPE_BUFFER))
       return nv50_surface_from_buffer(pipe, pres, templ);
    return nv50_miptree_surface_new(pipe, pres, templ);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_state.c 
b/src/gallium/drivers/nouveau/nv50/nv50_state.c
index 288ba46..c03d729 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_state.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_state.c
@@ -1010,6 +1010,7 @@ nv50_so_target_create(struct pipe_context *pipe,
                       struct pipe_resource *res,
                       unsigned offset, unsigned size)
 {
+   struct nv04_resource *buf = (struct nv04_resource *)res;
    struct nv50_so_target *targ = MALLOC_STRUCT(nv50_so_target);
    if (!targ)
       return NULL;
@@ -1033,6 +1034,9 @@ nv50_so_target_create(struct pipe_context *pipe,
    pipe_resource_reference(&targ->pipe.buffer, res);
    pipe_reference_init(&targ->pipe.reference, 1);
 
+   assert(buf->base.target == PIPE_BUFFER);
+   util_range_add(&buf->valid_buffer_range, offset, offset + size);
+
    return &targ->pipe;
 }
 
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
index 4e70903..12b5a02 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_resource.c
@@ -36,6 +36,8 @@ nvc0_surface_create(struct pipe_context *pipe,
                     struct pipe_resource *pres,
                     const struct pipe_surface *templ)
 {
+   /* surfaces are assumed to be miptrees all over the place. */
+   assert(pres->target != PIPE_BUFFER);
    if (unlikely(pres->target == PIPE_BUFFER))
       return nv50_surface_from_buffer(pipe, pres, templ);
    return nvc0_miptree_surface_new(pipe, pres, templ);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
index 0213a8e..dec5355 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
@@ -992,6 +992,7 @@ nvc0_so_target_create(struct pipe_context *pipe,
                       struct pipe_resource *res,
                       unsigned offset, unsigned size)
 {
+   struct nv04_resource *buf = (struct nv04_resource *)res;
    struct nvc0_so_target *targ = MALLOC_STRUCT(nvc0_so_target);
    if (!targ)
       return NULL;
@@ -1010,6 +1011,9 @@ nvc0_so_target_create(struct pipe_context *pipe,
    pipe_resource_reference(&targ->pipe.buffer, res);
    pipe_reference_init(&targ->pipe.reference, 1);
 
+   assert(buf->base.target == PIPE_BUFFER);
+   util_range_add(&buf->valid_buffer_range, offset, offset + size);
+
    return &targ->pipe;
 }
 
--
cgit v0.9.0.2-2-gbebe
 
++++++ U_nouveau_create_only_one_shared_screen.patch ++++++
>From fee0686c21c631d96d6042741267a3c218c23ffc Mon Sep 17 00:00:00 2001
From: Maarten Lankhorst <[email protected]>
Date: Wed, 12 Feb 2014 13:56:53 +0000
Subject: nouveau: create only 1 shared screen between vdpau and opengl

This fixes bug 73200 "vdpau-GL interop fails due to different screen
objects" in the same way radeon does.

Signed-off-by: Maarten Lankhorst <[email protected]>
Reviewed-by: Emil Velikov <[email protected]>
---
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c 
b/src/gallium/drivers/nouveau/nouveau_screen.c
index 21b31e0..f742a94 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -144,6 +144,12 @@ nouveau_screen_init(struct nouveau_screen *screen, struct 
nouveau_device *dev)
        if (nv_dbg)
           nouveau_mesa_debug = atoi(nv_dbg);
 
+       /*
+        * this is initialized to 1 in nouveau_drm_screen_create after screen
+        * is fully constructed and added to the global screen list.
+        */
+       screen->refcount = -1;
+
        if (dev->chipset < 0xc0) {
                data = &nv04_data;
                size = sizeof(nv04_data);
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h 
b/src/gallium/drivers/nouveau/nouveau_screen.h
index 51e24fa..cf06f7e 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -22,6 +22,8 @@ struct nouveau_screen {
        struct nouveau_client *client;
        struct nouveau_pushbuf *pushbuf;
 
+       int refcount;
+
        unsigned vidmem_bindings; /* PIPE_BIND_* where VRAM placement is 
desired */
        unsigned sysmem_bindings; /* PIPE_BIND_* where GART placement is 
desired */
        unsigned lowmem_bindings; /* PIPE_BIND_* that require an address < 4 
GiB */
@@ -112,6 +114,8 @@ nouveau_screen(struct pipe_screen *pscreen)
        return (struct nouveau_screen *)pscreen;
 }
 
+boolean nouveau_drm_screen_unref(struct nouveau_screen *screen);
+
 boolean
 nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
                             struct nouveau_bo *bo,
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c 
b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index c027a5f..9854708 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -302,6 +302,9 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
 {
    struct nv30_screen *screen = nv30_screen(pscreen);
 
+   if (!nouveau_drm_screen_unref(&screen->base))
+      return;
+
    if (screen->base.fence.current &&
        screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) {
       nouveau_fence_wait(screen->base.fence.current);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c 
b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index e636bf8..db3265f 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -287,6 +287,9 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
 {
    struct nv50_screen *screen = nv50_screen(pscreen);
 
+   if (!nouveau_drm_screen_unref(&screen->base))
+      return;
+
    if (screen->base.fence.current) {
       nouveau_fence_wait(screen->base.fence.current);
       nouveau_fence_ref (NULL, &screen->base.fence.current);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 28d9be2..f04771d 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -333,6 +333,9 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
 {
    struct nvc0_screen *screen = nvc0_screen(pscreen);
 
+   if (!nouveau_drm_screen_unref(&screen->base))
+      return;
+
    if (screen->base.fence.current) {
       nouveau_fence_wait(screen->base.fence.current);
       nouveau_fence_ref(NULL, &screen->base.fence.current);
diff --git a/src/gallium/targets/dri-nouveau/Makefile.am 
b/src/gallium/targets/dri-nouveau/Makefile.am
index 1988067..4bd4e21 100644
--- a/src/gallium/targets/dri-nouveau/Makefile.am
+++ b/src/gallium/targets/dri-nouveau/Makefile.am
@@ -20,6 +20,7 @@
 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
+DRI_VERSION_SCRIPT = $(srcdir)/nouveau_dri.link
 include $(top_srcdir)/src/gallium/Automake.inc
 
 AM_CFLAGS = \
diff --git a/src/gallium/targets/dri-nouveau/nouveau_dri.link 
b/src/gallium/targets/dri-nouveau/nouveau_dri.link
new file mode 100644
index 0000000..16015aa
--- a/dev/null
+++ b/src/gallium/targets/dri-nouveau/nouveau_dri.link
@@ -0,0 +1,6 @@
+VERSION {
+       global:
+               __driDriverExtensions;
+               nouveau_drm_screen_create;
+       local: *;
+};
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c 
b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
index e4f27f6..a077c48 100644
--- a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
@@ -1,24 +1,83 @@
+#include <sys/stat.h>
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "util/u_format.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
+#include "util/u_hash_table.h"
+#include "os/os_thread.h"
 
 #include "nouveau_drm_public.h"
 
 #include "nouveau/nouveau_winsys.h"
 #include "nouveau/nouveau_screen.h"
 
-struct pipe_screen *
+static struct util_hash_table *fd_tab = NULL;
+
+pipe_static_mutex(nouveau_screen_mutex);
+
+boolean nouveau_drm_screen_unref(struct nouveau_screen *screen)
+{
+       int ret;
+       if (screen->refcount == -1)
+               return true;
+
+       pipe_mutex_lock(nouveau_screen_mutex);
+       ret = --screen->refcount;
+       assert(ret >= 0);
+       if (ret == 0)
+               util_hash_table_remove(fd_tab, 
intptr_to_pointer(screen->device->fd));
+       pipe_mutex_unlock(nouveau_screen_mutex);
+       return ret == 0;
+}
+
+static unsigned hash_fd(void *key)
+{
+    int fd = pointer_to_intptr(key);
+    struct stat stat;
+    fstat(fd, &stat);
+
+    return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
+}
+
+static int compare_fd(void *key1, void *key2)
+{
+    int fd1 = pointer_to_intptr(key1);
+    int fd2 = pointer_to_intptr(key2);
+    struct stat stat1, stat2;
+    fstat(fd1, &stat1);
+    fstat(fd2, &stat2);
+
+    return stat1.st_dev != stat2.st_dev ||
+           stat1.st_ino != stat2.st_ino ||
+           stat1.st_rdev != stat2.st_rdev;
+}
+
+PUBLIC struct pipe_screen *
 nouveau_drm_screen_create(int fd)
 {
        struct nouveau_device *dev = NULL;
        struct pipe_screen *(*init)(struct nouveau_device *);
+       struct nouveau_screen *screen;
        int ret;
 
+       pipe_mutex_lock(nouveau_screen_mutex);
+       if (!fd_tab) {
+               fd_tab = util_hash_table_create(hash_fd, compare_fd);
+               if (!fd_tab)
+                       goto err;
+       }
+
+       screen = util_hash_table_get(fd_tab, intptr_to_pointer(fd));
+       if (screen) {
+               screen->refcount++;
+               pipe_mutex_unlock(nouveau_screen_mutex);
+               return &screen->base;
+       }
+
        ret = nouveau_device_wrap(fd, 0, &dev);
        if (ret)
-               return NULL;
+               goto err;
 
        switch (dev->chipset & ~0xf) {
        case 0x30:
@@ -42,8 +101,19 @@ nouveau_drm_screen_create(int fd)
        default:
                debug_printf("%s: unknown chipset nv%02x\n", __func__,
                             dev->chipset);
-               return NULL;
+               goto err;
        }
 
-       return init(dev);
+       screen = (struct nouveau_screen*)init(dev);
+       if (!screen)
+               goto err;
+
+       util_hash_table_set(fd_tab, intptr_to_pointer(fd), screen);
+       screen->refcount = 1;
+       pipe_mutex_unlock(nouveau_screen_mutex);
+       return &screen->base;
+
+err:
+       pipe_mutex_unlock(nouveau_screen_mutex);
+       return NULL;
 }
--
cgit v0.9.0.2-2-gbebe
 
++++++ U_nouveau_fix_fence_waiting_logic.patch ++++++
>From 507f0230d4ca2238c818006499e21abb4c133203 Mon Sep 17 00:00:00 2001
From: Ilia Mirkin <[email protected]>
Date: Thu, 06 Mar 2014 03:25:55 +0000
Subject: nouveau: fix fence waiting logic in screen destroy

nouveau_fence_wait has the expectation that an external entity is
holding onto the fence being waited on, not that it is merely held onto
by the current pointer. Fixes a use-after-free in nouveau_fence_wait
when used on the screen's current fence.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=75279
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Christoph Bumiller <[email protected]>
Cc: "9.2 10.0 10.1" <[email protected]>
---
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c 
b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
index 82f2c06..5378913 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c
@@ -308,10 +308,16 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
    if (!nouveau_drm_screen_unref(&screen->base))
       return;
 
-   if (screen->base.fence.current &&
-       screen->base.fence.current->state >= NOUVEAU_FENCE_STATE_EMITTED) {
-      nouveau_fence_wait(screen->base.fence.current);
-      nouveau_fence_ref (NULL, &screen->base.fence.current);
+   if (screen->base.fence.current) {
+      struct nouveau_fence *current = NULL;
+
+      /* nouveau_fence_wait will create a new current fence, so wait on the
+       * _current_ one, and remove both.
+       */
+      nouveau_fence_ref(screen->base.fence.current, &current);
+      nouveau_fence_wait(current);
+      nouveau_fence_ref(NULL, &current);
+      nouveau_fence_ref(NULL, &screen->base.fence.current);
    }
 
    nouveau_object_del(&screen->query);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_screen.c 
b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
index ab0d63e..e8c7fe3 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_screen.c
@@ -294,8 +294,15 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
       return;
 
    if (screen->base.fence.current) {
-      nouveau_fence_wait(screen->base.fence.current);
-      nouveau_fence_ref (NULL, &screen->base.fence.current);
+      struct nouveau_fence *current = NULL;
+
+      /* nouveau_fence_wait will create a new current fence, so wait on the
+       * _current_ one, and remove both.
+       */
+      nouveau_fence_ref(screen->base.fence.current, &current);
+      nouveau_fence_wait(current);
+      nouveau_fence_ref(NULL, &current);
+      nouveau_fence_ref(NULL, &screen->base.fence.current);
    }
    if (screen->base.pushbuf)
       screen->base.pushbuf->user_priv = NULL;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c 
b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 044847d..04f3088 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -340,7 +340,14 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
       return;
 
    if (screen->base.fence.current) {
-      nouveau_fence_wait(screen->base.fence.current);
+      struct nouveau_fence *current = NULL;
+
+      /* nouveau_fence_wait will create a new current fence, so wait on the
+       * _current_ one, and remove both.
+       */
+      nouveau_fence_ref(screen->base.fence.current, &current);
+      nouveau_fence_wait(current);
+      nouveau_fence_ref(NULL, &current);
       nouveau_fence_ref(NULL, &screen->base.fence.current);
    }
    if (screen->base.pushbuf)
--
cgit v0.9.0.2-2-gbebe
 
-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to