Accepting request 232654 from X11:XOrg
Mesa 10.2-rc1 (forwarded request 232615 from tobijk) OBS-URL: https://build.opensuse.org/request/show/232654 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/Mesa?expand=0&rev=210
This commit is contained in:
commit
d7e32bb54e
@ -1,3 +1,12 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Sat May 3 22:15:22 UTC 2014 - tobias.johannes.klausmann@mni.thm.de
|
||||||
|
|
||||||
|
- Update to 10.2-rc1:
|
||||||
|
- Remove U_gallium_util_add_missing_u_math_include.patch (patch27)
|
||||||
|
- Remove U_nouveau_create_only_one_shared_screen.patch (patch28)
|
||||||
|
- Remove U_nouveau_add_valid_range_tracking.patch (patch29)
|
||||||
|
- Remove U_nouveau_fix_fence_waiting_logic.patch (patch30)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Apr 25 00:19:50 UTC 2014 - tobias.johannes.klausmann@mni.thm.de
|
Fri Apr 25 00:19:50 UTC 2014 - tobias.johannes.klausmann@mni.thm.de
|
||||||
|
|
||||||
|
18
Mesa.spec
18
Mesa.spec
@ -49,11 +49,11 @@
|
|||||||
%define egl_gallium 0
|
%define egl_gallium 0
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
%define _version 10.1.0
|
|
||||||
%define _name_archive MesaLib
|
%define _name_archive MesaLib
|
||||||
|
%define _version 10.2.0-rc1
|
||||||
|
|
||||||
Name: Mesa
|
Name: Mesa
|
||||||
Version: 10.1.0
|
Version: 10.2.0~rc1
|
||||||
Release: 0
|
Release: 0
|
||||||
BuildRequires: autoconf >= 2.60
|
BuildRequires: autoconf >= 2.60
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
@ -68,9 +68,9 @@ BuildRequires: imake
|
|||||||
BuildRequires: libexpat-devel
|
BuildRequires: libexpat-devel
|
||||||
BuildRequires: libtalloc-devel
|
BuildRequires: libtalloc-devel
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
BuildRequires: libxml2-python
|
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
BuildRequires: python-base
|
BuildRequires: python-base
|
||||||
|
BuildRequires: python-xml
|
||||||
BuildRequires: pkgconfig(dri2proto)
|
BuildRequires: pkgconfig(dri2proto)
|
||||||
BuildRequires: pkgconfig(dri3proto)
|
BuildRequires: pkgconfig(dri3proto)
|
||||||
BuildRequires: pkgconfig(glproto)
|
BuildRequires: pkgconfig(glproto)
|
||||||
@ -134,17 +134,13 @@ Source2: baselibs.conf
|
|||||||
Source3: README.updates
|
Source3: README.updates
|
||||||
Source4: manual-pages.tar.bz2
|
Source4: manual-pages.tar.bz2
|
||||||
Source6: %name-rpmlintrc
|
Source6: %name-rpmlintrc
|
||||||
|
|
||||||
# to be upstreamed
|
# to be upstreamed
|
||||||
Patch11: u_Fix-crash-in-swrast-when-setting-a-texture-for-a-pix.patch
|
Patch11: u_Fix-crash-in-swrast-when-setting-a-texture-for-a-pix.patch
|
||||||
# Patch from Fedora, fix 16bpp in llvmpipe
|
# Patch from Fedora, fix 16bpp in llvmpipe
|
||||||
Patch13: u_mesa-8.0.1-fix-16bpp.patch
|
Patch13: u_mesa-8.0.1-fix-16bpp.patch
|
||||||
# Patch from Fedora, use shmget when available, under llvmpipe
|
# Patch from Fedora, use shmget when available, under llvmpipe
|
||||||
Patch15: u_mesa-8.0-llvmpipe-shmget.patch
|
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
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
|
||||||
@ -510,10 +506,6 @@ rm -rf docs/README.{VMS,WIN32,OS2}
|
|||||||
#%patch15 -p1
|
#%patch15 -p1
|
||||||
#%patch13 -p1
|
#%patch13 -p1
|
||||||
###
|
###
|
||||||
%patch27 -p1
|
|
||||||
%patch28 -p1
|
|
||||||
%patch29 -p1
|
|
||||||
%patch30 -p1
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
rm -f src/mesa/depend
|
rm -f src/mesa/depend
|
||||||
@ -549,7 +541,7 @@ autoreconf -fi
|
|||||||
--with-dri-drivers=i915,i965,nouveau,r200,radeon \
|
--with-dri-drivers=i915,i965,nouveau,r200,radeon \
|
||||||
--enable-opencl-icd \
|
--enable-opencl-icd \
|
||||||
%if %llvm_r600
|
%if %llvm_r600
|
||||||
--with-llvm-shared-libs \
|
--enable-llvm-shared-libs \
|
||||||
--enable-r600-llvm-compiler \
|
--enable-r600-llvm-compiler \
|
||||||
--with-gallium-drivers=r300,r600,radeonsi,nouveau,swrast,svga \
|
--with-gallium-drivers=r300,r600,radeonsi,nouveau,swrast,svga \
|
||||||
%else
|
%else
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:5941c3d4772a9f447f51569dfca48e01af98080bc996991d00a13f900dab2230
|
|
||||||
size 6908005
|
|
3
MesaLib-10.2.0-rc1.tar.bz2
Normal file
3
MesaLib-10.2.0-rc1.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:7fd039bb789be8b4fcb8d2f476577d51d8436ee6ba2856fa95d21f87b5d1e0c6
|
||||||
|
size 7096905
|
@ -1,26 +0,0 @@
|
|||||||
From f19271c7bf73efe6d583e9dc5fc37329558a5cc3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ilia Mirkin <imirkin@alum.mit.edu>
|
|
||||||
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 <imirkin@alum.mit.edu>
|
|
||||||
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
|||||||
From 5bf90cb521d1d6f26684b1ce9d0811c636b6abb1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ilia Mirkin <imirkin@alum.mit.edu>
|
|
||||||
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 <imirkin@alum.mit.edu>
|
|
||||||
Reviewed-by: Christoph Bumiller <e0425955@student.tuwien.ac.at>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
|
|
@ -1,231 +0,0 @@
|
|||||||
From fee0686c21c631d96d6042741267a3c218c23ffc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Maarten Lankhorst <maarten.lankhorst@canonical.com>
|
|
||||||
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 <maarten.lankhorst@canonical.com>
|
|
||||||
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
|
|
||||||
---
|
|
||||||
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
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
|||||||
From 507f0230d4ca2238c818006499e21abb4c133203 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ilia Mirkin <imirkin@alum.mit.edu>
|
|
||||||
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 <imirkin@alum.mit.edu>
|
|
||||||
Reviewed-by: Christoph Bumiller <e0425955@student.tuwien.ac.at>
|
|
||||||
Cc: "9.2 10.0 10.1" <mesa-stable@lists.freedesktop.org>
|
|
||||||
---
|
|
||||||
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, ¤t);
|
|
||||||
+ nouveau_fence_wait(current);
|
|
||||||
+ nouveau_fence_ref(NULL, ¤t);
|
|
||||||
+ 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, ¤t);
|
|
||||||
+ nouveau_fence_wait(current);
|
|
||||||
+ nouveau_fence_ref(NULL, ¤t);
|
|
||||||
+ 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, ¤t);
|
|
||||||
+ nouveau_fence_wait(current);
|
|
||||||
+ nouveau_fence_ref(NULL, ¤t);
|
|
||||||
nouveau_fence_ref(NULL, &screen->base.fence.current);
|
|
||||||
}
|
|
||||||
if (screen->base.pushbuf)
|
|
||||||
--
|
|
||||||
cgit v0.9.0.2-2-gbebe
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user