debian/changelog | 16 debian/control | 26 debian/libdrm-nouveau1.install | 1 debian/libdrm-nouveau1.symbols | 59 + debian/patches/03_revert_abi_change.diff | 1224 +++++++++++++++++++++++++++++++ debian/patches/series | 1 debian/rules | 10 7 files changed, 1337 insertions(+)
New commits: commit eebc0b4f31062ef36d918f8762c5b85da78fc027 Author: Cyril Brulebois <k...@debian.org> Date: Wed Apr 14 13:03:08 2010 +0200 Upload to unstable. diff --git a/debian/changelog b/debian/changelog index 79153c3..bc62c1d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +libdrm (2.4.18-5) unstable; urgency=low + + * Upload to unstable. + + -- Cyril Brulebois <k...@debian.org> Wed, 14 Apr 2010 13:02:34 +0200 + libdrm (2.4.18-4) experimental; urgency=low * Steal 03_revert_abi_change.diff from Ubuntu to revert the nouveau ABI commit 197bdde16f9c405936f7a6cdce30322770022562 Author: Brice Goglin <bgog...@debian.org> Date: Wed Mar 24 22:19:10 2010 +0100 Prepare changelog for upload diff --git a/debian/changelog b/debian/changelog index c1d3dda..79153c3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -libdrm (2.4.18-4) UNRELEASED; urgency=low +libdrm (2.4.18-4) experimental; urgency=low * Steal 03_revert_abi_change.diff from Ubuntu to revert the nouveau ABI change. Current Debian kernels support only the old ABI. @@ -6,7 +6,7 @@ libdrm (2.4.18-4) UNRELEASED; urgency=low * Build a libdrm-nouveau1 package on Linux architectures (Closes: #568162). Patch adapted from the Ubuntu package. Thanks Sven Joachim! - -- Brice Goglin <bgog...@debian.org> Wed, 24 Mar 2010 22:12:36 +0100 + -- Brice Goglin <bgog...@debian.org> Wed, 24 Mar 2010 22:27:00 +0100 libdrm (2.4.18-3) unstable; urgency=low commit 9f62499e2dd1df046001d174d9a6518b3db929e4 Author: Brice Goglin <bgog...@debian.org> Date: Wed Mar 24 22:18:36 2010 +0100 Build a libdrm-nouveau1 package on Linux architectures (Closes: #568162). diff --git a/debian/changelog b/debian/changelog index fe4f1f0..c1d3dda 100644 --- a/debian/changelog +++ b/debian/changelog @@ -3,6 +3,8 @@ libdrm (2.4.18-4) UNRELEASED; urgency=low * Steal 03_revert_abi_change.diff from Ubuntu to revert the nouveau ABI change. Current Debian kernels support only the old ABI. Thanks Sven Joachim! + * Build a libdrm-nouveau1 package on Linux architectures (Closes: #568162). + Patch adapted from the Ubuntu package. Thanks Sven Joachim! -- Brice Goglin <bgog...@debian.org> Wed, 24 Mar 2010 22:12:36 +0100 diff --git a/debian/control b/debian/control index 65f013a..cf271d8 100644 --- a/debian/control +++ b/debian/control @@ -23,6 +23,7 @@ Depends: libdrm2 (= ${binary:Version}), libdrm-intel1 (= ${binary:Version}) [amd64 i386 kfreebsd-amd64 kfreebsd-i386], libdrm-radeon1 (= ${binary:Version}) [linux-any], + libdrm-nouveau1 (= ${binary:Version}) [linux-any], ${misc:Depends}, Replaces: linux-libc-dev (<< 2.6.32-10) @@ -93,6 +94,31 @@ Description: Userspace interface to intel-specific kernel DRM services -- debugg . This package provides the debugging symbols for the libdrm-intel1 package. +Package: libdrm-nouveau1 +Section: libs +Architecture: linux-any +Depends: ${shlibs:Depends}, + ${misc:Depends}, +Description: Userspace interface to nouveau-specific kernel DRM services -- runtime + This library implements the userspace interface to the nouveau-specific kernel + DRM services. DRM stands for "Direct Rendering Manager", which is the + kernelspace portion of the "Direct Rendering Infrastructure" (DRI). The DRI is + currently used on Linux to provide hardware-accelerated OpenGL drivers. + +Package: libdrm-nouveau1-dbg +Section: debug +Priority: extra +Architecture: linux-any +Depends: libdrm-nouveau1 (= ${binary:Version}), + ${misc:Depends}, +Description: Userspace interface to nouveau-specific kernel DRM -- debugging symbols + This library implements the userspace interface to the kernel DRM services. + DRM stands for "Direct Rendering Manager", which is the kernelspace portion + of the "Direct Rendering Infrastructure" (DRI). The DRI is currently used on + Linux to provide hardware-accelerated OpenGL drivers. + . + This package provides the debugging symbols for the libdrm-nouveau1 package. + Package: libdrm-radeon1 Section: libs Architecture: linux-any diff --git a/debian/libdrm-nouveau1.install b/debian/libdrm-nouveau1.install new file mode 100644 index 0000000..7650858 --- /dev/null +++ b/debian/libdrm-nouveau1.install @@ -0,0 +1 @@ +usr/lib/libdrm_nouveau.so.* diff --git a/debian/libdrm-nouveau1.symbols b/debian/libdrm-nouveau1.symbols new file mode 100644 index 0000000..48ce118 --- /dev/null +++ b/debian/libdrm-nouveau1.symbols @@ -0,0 +1,59 @@ +libdrm_nouveau.so.1 libdrm-nouveau1 #MINVER# +#MISSING: 2.4.12+git20090729.5a73f066# d...@base 2.4.4 + nouveau_bo_b...@base 2.4.4 + nouveau_bo_emit_buf...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_bo_f...@base 2.4.4 + nouveau_bo_handle_...@base 2.4.4 + nouveau_bo_handle_...@base 2.4.4 + nouveau_bo_i...@base 2.4.4 + nouveau_bo_...@base 2.4.4 + nouveau_bo_map_fl...@base 2.4.11-1ubuntu1~ + nouveau_bo_map_ra...@base 2.4.11-1ubuntu1~ + nouveau_bo_...@base 2.4.4 + nouveau_bo_new_t...@base 2.4.11-1ubuntu1~ + nouveau_bo_pend...@base 2.4.16 + nouveau_bo_...@base 2.4.4 + nouveau_bo_...@base 2.4.4 + nouveau_bo_taked...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_bo_t...@base 2.4.4 + nouveau_bo_un...@base 2.4.4 + nouveau_bo_un...@base 2.4.4 + nouveau_bo_u...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_bo_validate_n...@base 2.4.4 + nouveau_bo_w...@base 2.4.11-1ubuntu1~ + nouveau_channel_al...@base 2.4.4 + nouveau_channel_f...@base 2.4.4 + nouveau_device_cl...@base 2.4.4 + nouveau_device_get_pa...@base 2.4.4 + nouveau_device_o...@base 2.4.4 + nouveau_device_open_exist...@base 2.4.4 + nouveau_device_set_pa...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_dma_channel_i...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_dma_kick...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_dma_w...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_e...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_fl...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_signal...@base 2.4.4 +#MISSING: 2.4.12+git20090729.5a73f066# nouveau_fence_w...@base 2.4.4 + nouveau_grobj_al...@base 2.4.4 + nouveau_grobj_autob...@base 2.4.4 + nouveau_grobj_f...@base 2.4.4 + nouveau_grobj_...@base 2.4.4 + nouveau_notifier_al...@base 2.4.4 + nouveau_notifier_f...@base 2.4.4 + nouveau_notifier_re...@base 2.4.4 + nouveau_notifier_return_...@base 2.4.4 + nouveau_notifier_sta...@base 2.4.4 + nouveau_notifier_wait_sta...@base 2.4.4 + nouveau_pushbuf_emit_re...@base 2.4.4 + nouveau_pushbuf_f...@base 2.4.17-1ubuntu1~ + nouveau_pushbuf_fl...@base 2.4.4 + nouveau_pushbuf_i...@base 2.4.4 + nouveau_pushbuf_marker_e...@base 2.4.16 + nouveau_pushbuf_marker_u...@base 2.4.16 + nouveau_resource_al...@base 2.4.4 + nouveau_resource_dest...@base 2.4.18 + nouveau_resource_f...@base 2.4.4 + nouveau_resource_i...@base 2.4.4 diff --git a/debian/rules b/debian/rules index dede329..471ea74 100755 --- a/debian/rules +++ b/debian/rules @@ -24,10 +24,14 @@ else endif ifeq (linux, $(DEB_HOST_ARCH_OS)) confflags += --enable-udev + confflags += --enable-nouveau-experimental-api + NOUVEAU = yes confflags += --enable-radeon RADEON = yes else confflags += --disable-udev + confflags += --disable-nouveau-experimental-api + NOUVEAU = no confflags += --disable-radeon RADEON = no endif @@ -121,6 +125,9 @@ binary-arch: build install ifeq ($(INTEL), yes) dh_strip -plibdrm-intel1 --dbg-package=libdrm-intel1-dbg endif +ifeq ($(NOUVEAU), yes) + dh_strip -plibdrm-nouveau1 --dbg-package=libdrm-nouveau1-dbg +endif ifeq ($(RADEON), yes) dh_strip -plibdrm-radeon1 --dbg-package=libdrm-radeon1-dbg endif @@ -131,6 +138,9 @@ endif ifeq ($(INTEL), yes) dh_makeshlibs -plibdrm-intel1 -V'libdrm-intel1 (>= 2.4.16)' -- -c4 endif +ifeq ($(NOUVEAU), yes) + dh_makeshlibs -plibdrm-nouveau1 -V'libdrm-nouveau1 (>= 2.4.16)' -- -c4 +endif ifeq ($(RADEON), yes) dh_makeshlibs -plibdrm-radeon1 -V'libdrm-radeon1 (>= 2.4.17)' -- -c4 endif commit 3279d82034f7c5d0e968fff8bbdab212f39f7fba Author: Brice Goglin <bgog...@debian.org> Date: Wed Mar 24 22:12:17 2010 +0100 Steal 03_revert_abi_change.diff from Ubuntu to revert the nouveau ABI change diff --git a/debian/changelog b/debian/changelog index ed279c5..fe4f1f0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +libdrm (2.4.18-4) UNRELEASED; urgency=low + + * Steal 03_revert_abi_change.diff from Ubuntu to revert the nouveau ABI + change. Current Debian kernels support only the old ABI. + Thanks Sven Joachim! + + -- Brice Goglin <bgog...@debian.org> Wed, 24 Mar 2010 22:12:36 +0100 + libdrm (2.4.18-3) unstable; urgency=low * Include full SONAME in libdrm*.install to prevent accidental breakage. diff --git a/debian/patches/03_revert_abi_change.diff b/debian/patches/03_revert_abi_change.diff new file mode 100644 index 0000000..12dd8f6 --- /dev/null +++ b/debian/patches/03_revert_abi_change.diff @@ -0,0 +1,1224 @@ +Revert nouveau ABI change to match what is in 2.6.33. + +This reverts commits after b496c63143e9a4ca02011582329bce2df99d9b7c + +diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h +index a6a9f4a..f745948 100644 +--- a/include/drm/nouveau_drm.h ++++ b/include/drm/nouveau_drm.h +@@ -25,14 +25,13 @@ + #ifndef __NOUVEAU_DRM_H__ + #define __NOUVEAU_DRM_H__ + +-#define NOUVEAU_DRM_HEADER_PATCHLEVEL 16 ++#define NOUVEAU_DRM_HEADER_PATCHLEVEL 15 + + struct drm_nouveau_channel_alloc { + uint32_t fb_ctxdma_handle; + uint32_t tt_ctxdma_handle; + + int channel; +- uint32_t pushbuf_domains; + + /* Notifier memory */ + uint32_t notifier_handle; +@@ -110,58 +109,68 @@ struct drm_nouveau_gem_new { + uint32_t align; + }; + +-#define NOUVEAU_GEM_MAX_BUFFERS 1024 +-struct drm_nouveau_gem_pushbuf_bo_presumed { +- uint32_t valid; +- uint32_t domain; +- uint64_t offset; +-}; +- + struct drm_nouveau_gem_pushbuf_bo { + uint64_t user_priv; + uint32_t handle; + uint32_t read_domains; + uint32_t write_domains; + uint32_t valid_domains; +- struct drm_nouveau_gem_pushbuf_bo_presumed presumed; ++ uint32_t presumed_ok; ++ uint32_t presumed_domain; ++ uint64_t presumed_offset; + }; + + #define NOUVEAU_GEM_RELOC_LOW (1 << 0) + #define NOUVEAU_GEM_RELOC_HIGH (1 << 1) + #define NOUVEAU_GEM_RELOC_OR (1 << 2) +-#define NOUVEAU_GEM_MAX_RELOCS 1024 + struct drm_nouveau_gem_pushbuf_reloc { +- uint32_t reloc_bo_index; +- uint32_t reloc_bo_offset; + uint32_t bo_index; ++ uint32_t reloc_index; + uint32_t flags; + uint32_t data; + uint32_t vor; + uint32_t tor; + }; + +-#define NOUVEAU_GEM_MAX_PUSH 512 +-struct drm_nouveau_gem_pushbuf_push { +- uint32_t bo_index; +- uint32_t pad; +- uint64_t offset; +- uint64_t length; +-}; ++#define NOUVEAU_GEM_MAX_BUFFERS 1024 ++#define NOUVEAU_GEM_MAX_RELOCS 1024 + + struct drm_nouveau_gem_pushbuf { + uint32_t channel; ++ uint32_t nr_dwords; + uint32_t nr_buffers; ++ uint32_t nr_relocs; ++ uint64_t dwords; + uint64_t buffers; ++ uint64_t relocs; ++}; ++ ++struct drm_nouveau_gem_pushbuf_call { ++ uint32_t channel; ++ uint32_t handle; ++ uint32_t offset; ++ uint32_t nr_buffers; + uint32_t nr_relocs; +- uint32_t nr_push; ++ uint32_t nr_dwords; ++ uint64_t buffers; + uint64_t relocs; +- uint64_t push; + uint32_t suffix0; + uint32_t suffix1; ++ /* below only accessed for CALL2 */ + uint64_t vram_available; + uint64_t gart_available; + }; + ++struct drm_nouveau_gem_pin { ++ uint32_t handle; ++ uint32_t domain; ++ uint64_t offset; ++}; ++ ++struct drm_nouveau_gem_unpin { ++ uint32_t handle; ++}; ++ + #define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 + #define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 + #define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 +@@ -174,6 +183,14 @@ struct drm_nouveau_gem_cpu_fini { + uint32_t handle; + }; + ++struct drm_nouveau_gem_tile { ++ uint32_t handle; ++ uint32_t offset; ++ uint32_t size; ++ uint32_t tile_mode; ++ uint32_t tile_flags; ++}; ++ + enum nouveau_bus_type { + NV_AGP = 0, + NV_PCI = 1, +@@ -183,17 +200,22 @@ enum nouveau_bus_type { + struct drm_nouveau_sarea { + }; + +-#define DRM_NOUVEAU_GETPARAM 0x00 +-#define DRM_NOUVEAU_SETPARAM 0x01 +-#define DRM_NOUVEAU_CHANNEL_ALLOC 0x02 +-#define DRM_NOUVEAU_CHANNEL_FREE 0x03 +-#define DRM_NOUVEAU_GROBJ_ALLOC 0x04 +-#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 +-#define DRM_NOUVEAU_GPUOBJ_FREE 0x06 ++#define DRM_NOUVEAU_CARD_INIT 0x00 ++#define DRM_NOUVEAU_GETPARAM 0x01 ++#define DRM_NOUVEAU_SETPARAM 0x02 ++#define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 ++#define DRM_NOUVEAU_CHANNEL_FREE 0x04 ++#define DRM_NOUVEAU_GROBJ_ALLOC 0x05 ++#define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 ++#define DRM_NOUVEAU_GPUOBJ_FREE 0x07 + #define DRM_NOUVEAU_GEM_NEW 0x40 + #define DRM_NOUVEAU_GEM_PUSHBUF 0x41 +-#define DRM_NOUVEAU_GEM_CPU_PREP 0x42 +-#define DRM_NOUVEAU_GEM_CPU_FINI 0x43 +-#define DRM_NOUVEAU_GEM_INFO 0x44 ++#define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42 ++#define DRM_NOUVEAU_GEM_PIN 0x43 /* !KMS only */ ++#define DRM_NOUVEAU_GEM_UNPIN 0x44 /* !KMS only */ ++#define DRM_NOUVEAU_GEM_CPU_PREP 0x45 ++#define DRM_NOUVEAU_GEM_CPU_FINI 0x46 ++#define DRM_NOUVEAU_GEM_INFO 0x47 ++#define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48 + + #endif /* __NOUVEAU_DRM_H__ */ +diff --git a/nouveau/Makefile.am b/nouveau/Makefile.am +index 5d759c5..70bbbb2 100644 +--- a/nouveau/Makefile.am ++++ b/nouveau/Makefile.am +@@ -18,8 +18,7 @@ libdrm_nouveau_la_SOURCES = \ + nouveau_notifier.c \ + nouveau_bo.c \ + nouveau_resource.c \ +- nouveau_private.h \ +- nouveau_reloc.c ++ nouveau_private.h + + libdrm_nouveaucommonincludedir = ${includedir}/nouveau + libdrm_nouveaucommoninclude_HEADERS = \ +@@ -30,8 +29,7 @@ libdrm_nouveaucommoninclude_HEADERS = \ + nouveau_pushbuf.h \ + nouveau_bo.h \ + nouveau_resource.h \ +- nouveau_class.h \ +- nouveau_reloc.h ++ nouveau_class.h + + + libdrm_nouveauincludedir = ${includedir}/drm +diff --git a/nouveau/nouveau_bo.c b/nouveau/nouveau_bo.c +index 4973636..10cc8a6 100644 +--- a/nouveau/nouveau_bo.c ++++ b/nouveau/nouveau_bo.c +@@ -201,6 +201,14 @@ nouveau_bo_new_tile(struct nouveau_device *dev, uint32_t flags, int align, + nouveau_bo_ref(NULL, (void *)nvbo); + return ret; + } ++ ++ if (flags & NOUVEAU_BO_PIN) { ++ ret = nouveau_bo_pin((void *)nvbo, nvbo->flags); ++ if (ret) { ++ nouveau_bo_ref(NULL, (void *)nvbo); ++ return ret; ++ } ++ } + } + + *bo = &nvbo->base; +@@ -211,7 +219,16 @@ int + nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align, + int size, struct nouveau_bo **bo) + { +- return nouveau_bo_new_tile(dev, flags, align, size, 0, 0, bo); ++ uint32_t tile_flags = 0; ++ ++ if (flags & NOUVEAU_BO_TILED) { ++ if (flags & NOUVEAU_BO_ZTILE) ++ tile_flags = 0x2800; ++ else ++ tile_flags = 0x7000; ++ } ++ ++ return nouveau_bo_new_tile(dev, flags, align, size, 0, tile_flags, bo); + } + + int +@@ -466,6 +483,62 @@ nouveau_bo_unmap(struct nouveau_bo *bo) + } + + int ++nouveau_bo_pin(struct nouveau_bo *bo, uint32_t flags) ++{ ++ struct nouveau_device_priv *nvdev = nouveau_device(bo->device); ++ struct nouveau_bo_priv *nvbo = nouveau_bo(bo); ++ struct drm_nouveau_gem_pin req; ++ int ret; ++ ++ if (nvbo->pinned) ++ return 0; ++ ++ if (!nvbo->handle) ++ return -EINVAL; ++ ++ /* Now force it to stay put :) */ ++ req.handle = nvbo->handle; ++ req.domain = 0; ++ if (flags & NOUVEAU_BO_VRAM) ++ req.domain |= NOUVEAU_GEM_DOMAIN_VRAM; ++ if (flags & NOUVEAU_BO_GART) ++ req.domain |= NOUVEAU_GEM_DOMAIN_GART; ++ ++ ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_PIN, &req, ++ sizeof(struct drm_nouveau_gem_pin)); ++ if (ret) ++ return ret; ++ nvbo->offset = req.offset; ++ nvbo->domain = req.domain; ++ nvbo->pinned = 1; ++ ++ /* Fill in public nouveau_bo members */ ++ if (nvbo->domain & NOUVEAU_GEM_DOMAIN_VRAM) ++ bo->flags = NOUVEAU_BO_VRAM; ++ if (nvbo->domain & NOUVEAU_GEM_DOMAIN_GART) ++ bo->flags = NOUVEAU_BO_GART; ++ bo->offset = nvbo->offset; ++ ++ return 0; ++} ++ ++void ++nouveau_bo_unpin(struct nouveau_bo *bo) ++{ ++ struct nouveau_device_priv *nvdev = nouveau_device(bo->device); ++ struct nouveau_bo_priv *nvbo = nouveau_bo(bo); ++ struct drm_nouveau_gem_unpin req; ++ ++ if (!nvbo->pinned) ++ return; ++ ++ req.handle = nvbo->handle; ++ drmCommandWrite(nvdev->fd, DRM_NOUVEAU_GEM_UNPIN, &req, sizeof(req)); ++ ++ nvbo->pinned = bo->offset = bo->flags = 0; ++} ++ ++int + nouveau_bo_busy(struct nouveau_bo *bo, uint32_t access) + { + return nouveau_bo_wait(bo, (access & NOUVEAU_BO_WR), 1, 1); +@@ -492,7 +565,7 @@ nouveau_bo_pending(struct nouveau_bo *bo) + struct drm_nouveau_gem_pushbuf_bo * + nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) + { +- struct nouveau_pushbuf_priv *nvpb = &nouveau_channel(chan)->pb; ++ struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); + struct nouveau_bo_priv *nvbo = nouveau_bo(bo); + struct drm_nouveau_gem_pushbuf_bo *pbbo; + struct nouveau_bo *ref = NULL; +@@ -534,8 +607,8 @@ nouveau_bo_emit_buffer(struct nouveau_channel *chan, struct nouveau_bo *bo) + pbbo->valid_domains = NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART; + pbbo->read_domains = 0; + pbbo->write_domains = 0; +- pbbo->presumed.domain = nvbo->domain; +- pbbo->presumed.offset = nvbo->offset; +- pbbo->presumed.valid = 1; ++ pbbo->presumed_domain = nvbo->domain; ++ pbbo->presumed_offset = nvbo->offset; ++ pbbo->presumed_ok = 1; + return pbbo; + } +diff --git a/nouveau/nouveau_bo.h b/nouveau/nouveau_bo.h +index 1e77ab0..fdad63e 100644 +--- a/nouveau/nouveau_bo.h ++++ b/nouveau/nouveau_bo.h +@@ -30,9 +30,13 @@ + #define NOUVEAU_BO_WR (1 << 3) + #define NOUVEAU_BO_RDWR (NOUVEAU_BO_RD | NOUVEAU_BO_WR) + #define NOUVEAU_BO_MAP (1 << 4) ++#define NOUVEAU_BO_PIN (1 << 5) + #define NOUVEAU_BO_LOW (1 << 6) + #define NOUVEAU_BO_HIGH (1 << 7) + #define NOUVEAU_BO_OR (1 << 8) ++#define NOUVEAU_BO_LOCAL (1 << 9) ++#define NOUVEAU_BO_TILED (1 << 10) ++#define NOUVEAU_BO_ZTILE (1 << 11) + #define NOUVEAU_BO_INVAL (1 << 12) + #define NOUVEAU_BO_NOSYNC (1 << 13) + #define NOUVEAU_BO_NOWAIT (1 << 14) +@@ -48,6 +52,10 @@ struct nouveau_bo { + + uint32_t tile_mode; + uint32_t tile_flags; ++ ++ /* Available when buffer is pinned *only* */ ++ uint32_t flags; ++ uint64_t offset; + }; + + int +@@ -90,6 +98,12 @@ void + nouveau_bo_unmap(struct nouveau_bo *); + + int ++nouveau_bo_pin(struct nouveau_bo *, uint32_t flags); ++ ++void ++nouveau_bo_unpin(struct nouveau_bo *); ++ ++int + nouveau_bo_busy(struct nouveau_bo *, uint32_t access); + + uint32_t +diff --git a/nouveau/nouveau_channel.h b/nouveau/nouveau_channel.h +index ddcf8e4..294f749 100644 +--- a/nouveau/nouveau_channel.h ++++ b/nouveau/nouveau_channel.h +@@ -29,12 +29,11 @@ struct nouveau_subchannel { + }; + + struct nouveau_channel { +- uint32_t *cur; +- uint32_t *end; +- + struct nouveau_device *device; + int id; + ++ struct nouveau_pushbuf *pushbuf; ++ + struct nouveau_grobj *nullobj; + struct nouveau_grobj *vram; + struct nouveau_grobj *gart; +diff --git a/nouveau/nouveau_device.c b/nouveau/nouveau_device.c +index c525391..0982d3b 100644 +--- a/nouveau/nouveau_device.c ++++ b/nouveau/nouveau_device.c +@@ -26,7 +26,7 @@ + + #include "nouveau_private.h" + +-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 16 ++#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 15 + #error nouveau_drm.h does not match expected patchlevel, update libdrm. + #endif + +@@ -54,6 +54,12 @@ nouveau_device_open_existing(struct nouveau_device **dev, int close, + nvdev->ctx = ctx; + nvdev->needs_close = close; + ++ ret = drmCommandNone(nvdev->fd, DRM_NOUVEAU_CARD_INIT); ++ if (ret) { ++ nouveau_device_close((void *)&nvdev); ++ return ret; ++ } ++ + ret = nouveau_device_get_param(&nvdev->base, + NOUVEAU_GETPARAM_VM_VRAM_BASE, &value); + if (ret) { +diff --git a/nouveau/nouveau_private.h b/nouveau/nouveau_private.h +index c08fa38..39758d1 100644 +--- a/nouveau/nouveau_private.h ++++ b/nouveau/nouveau_private.h +@@ -35,11 +35,14 @@ + #include "nouveau_bo.h" + #include "nouveau_resource.h" + #include "nouveau_pushbuf.h" +-#include "nouveau_reloc.h" + + #define CALPB_BUFFERS 4 + #define CALPB_BUFSZ 16384 + struct nouveau_pushbuf_priv { ++ struct nouveau_pushbuf base; ++ ++ int no_aper_update; ++ int use_cal; + uint32_t cal_suffix0; + uint32_t cal_suffix1; + struct nouveau_bo *buffer[CALPB_BUFFERS]; +@@ -47,19 +50,15 @@ struct nouveau_pushbuf_priv { + int current_offset; + + unsigned *pushbuf; +- unsigned size; ++ unsigned size; + +- uint32_t *marker; +- unsigned marker_offset; ++ unsigned marker; + unsigned marker_relocs; +- unsigned marker_push; + + struct drm_nouveau_gem_pushbuf_bo *buffers; + unsigned nr_buffers; + struct drm_nouveau_gem_pushbuf_reloc *relocs; + unsigned nr_relocs; +- struct drm_nouveau_gem_pushbuf_push push[NOUVEAU_GEM_MAX_PUSH]; +- unsigned nr_push; + }; + #define nouveau_pushbuf(n) ((struct nouveau_pushbuf_priv *)(n)) + +diff --git a/nouveau/nouveau_pushbuf.c b/nouveau/nouveau_pushbuf.c +index 28b8018..7da3a47 100644 +--- a/nouveau/nouveau_pushbuf.c ++++ b/nouveau/nouveau_pushbuf.c +@@ -31,7 +31,7 @@ + #define PB_MIN_USER_DWORDS 2048 + + static int +-nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) ++nouveau_pushbuf_space_call(struct nouveau_channel *chan, unsigned min) + { + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; +@@ -41,8 +41,8 @@ nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) + if (min < PB_MIN_USER_DWORDS) + min = PB_MIN_USER_DWORDS; + +- nvpb->current_offset = chan->cur - nvpb->pushbuf; +- if (chan->cur + min + 2 <= chan->end) ++ nvpb->current_offset = nvpb->base.cur - nvpb->pushbuf; ++ if (nvpb->current_offset + min + 2 <= nvpb->size) + return 0; + + nvpb->current++; +@@ -58,13 +58,38 @@ nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) + nvpb->pushbuf = bo->map; + nvpb->current_offset = 0; + +- chan->cur = nvpb->pushbuf; +- chan->end = nvpb->pushbuf + nvpb->size; ++ nvpb->base.channel = chan; ++ nvpb->base.remaining = nvpb->size; ++ nvpb->base.cur = nvpb->pushbuf; + + nouveau_bo_unmap(bo); + return 0; + } + ++static int ++nouveau_pushbuf_space(struct nouveau_channel *chan, unsigned min) ++{ ++ struct nouveau_channel_priv *nvchan = nouveau_channel(chan); ++ struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; ++ ++ if (nvpb->use_cal) ++ return nouveau_pushbuf_space_call(chan, min); ++ ++ if (nvpb->pushbuf) { ++ free(nvpb->pushbuf); ++ nvpb->pushbuf = NULL; ++ } ++ ++ nvpb->size = min < PB_MIN_USER_DWORDS ? PB_MIN_USER_DWORDS : min; ++ nvpb->pushbuf = malloc(sizeof(uint32_t) * nvpb->size); ++ ++ nvpb->base.channel = chan; ++ nvpb->base.remaining = nvpb->size; ++ nvpb->base.cur = nvpb->pushbuf; ++ ++ return 0; ++} ++ + static void + nouveau_pushbuf_fini_call(struct nouveau_channel *chan) + { +@@ -74,43 +99,46 @@ nouveau_pushbuf_fini_call(struct nouveau_channel *chan) + + for (i = 0; i < CALPB_BUFFERS; i++) + nouveau_bo_ref(NULL, &nvpb->buffer[i]); ++ nvpb->use_cal = 0; + nvpb->pushbuf = NULL; + } + +-static int ++static void + nouveau_pushbuf_init_call(struct nouveau_channel *chan) + { +- struct drm_nouveau_gem_pushbuf req; ++ struct drm_nouveau_gem_pushbuf_call req; + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + struct nouveau_device *dev = chan->device; +- uint32_t flags = 0; + int i, ret; + +- if (nvchan->drm.pushbuf_domains & NOUVEAU_GEM_DOMAIN_GART) +- flags |= NOUVEAU_BO_GART; +- else +- flags |= NOUVEAU_BO_VRAM; +- + req.channel = chan->id; +- req.nr_push = 0; ++ req.handle = 0; + ret = drmCommandWriteRead(nouveau_device(dev)->fd, +- DRM_NOUVEAU_GEM_PUSHBUF, &req, sizeof(req)); +- if (ret) +- return ret; ++ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, ++ &req, sizeof(req)); ++ if (ret) { ++ ret = drmCommandWriteRead(nouveau_device(dev)->fd, ++ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, ++ &req, sizeof(req)); ++ if (ret) ++ return; ++ ++ nvpb->no_aper_update = 1; ++ } + + for (i = 0; i < CALPB_BUFFERS; i++) { +- ret = nouveau_bo_new(dev, flags | NOUVEAU_BO_MAP, ++ ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, + 0, CALPB_BUFSZ, &nvpb->buffer[i]); + if (ret) { + nouveau_pushbuf_fini_call(chan); +- return ret; ++ return; + } + } + ++ nvpb->use_cal = 1; + nvpb->cal_suffix0 = req.suffix0; + nvpb->cal_suffix1 = req.suffix1; +- return 0; + } + + int +@@ -120,18 +148,25 @@ nouveau_pushbuf_init(struct nouveau_channel *chan) + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; + int ret; + +- ret = nouveau_pushbuf_init_call(chan); +- if (ret) +- return ret; ++ nouveau_pushbuf_init_call(chan); + + ret = nouveau_pushbuf_space(chan, 0); +- if (ret) +- return ret; ++ if (ret) { ++ if (nvpb->use_cal) { ++ nouveau_pushbuf_fini_call(chan); ++ ret = nouveau_pushbuf_space(chan, 0); ++ } ++ ++ if (ret) ++ return ret; ++ } + + nvpb->buffers = calloc(NOUVEAU_GEM_MAX_BUFFERS, + sizeof(struct drm_nouveau_gem_pushbuf_bo)); + nvpb->relocs = calloc(NOUVEAU_GEM_MAX_RELOCS, + sizeof(struct drm_nouveau_gem_pushbuf_reloc)); ++ ++ chan->pushbuf = &nvpb->base; + return 0; + } + +@@ -145,129 +180,92 @@ nouveau_pushbuf_fini(struct nouveau_channel *chan) + free(nvpb->relocs); + } + +-static int +-nouveau_pushbuf_bo_add(struct nouveau_channel *chan, struct nouveau_bo *bo, +- unsigned offset, unsigned length) +-{ +- struct nouveau_channel_priv *nvchan = nouveau_channel(chan); +- struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; +- struct drm_nouveau_gem_pushbuf_push *p = &nvpb->push[nvpb->nr_push++]; +- struct drm_nouveau_gem_pushbuf_bo *pbbo; +- struct nouveau_bo_priv *nvbo = nouveau_bo(bo); +- +- pbbo = nouveau_bo_emit_buffer(chan, bo); +- if (!pbbo) +- return -ENOMEM; +- pbbo->valid_domains &= nvchan->drm.pushbuf_domains; +- pbbo->read_domains |= nvchan->drm.pushbuf_domains; +- nvbo->pending_refcnt++; +- +- p->bo_index = pbbo - nvpb->buffers; +- p->offset = offset; +- p->length = length; +- return 0; +-} +- +-int +-nouveau_pushbuf_submit(struct nouveau_channel *chan, struct nouveau_bo *bo, +- unsigned offset, unsigned length) +-{ +- struct nouveau_pushbuf_priv *nvpb = &nouveau_channel(chan)->pb; +- int ret, len; +- +- if ((AVAIL_RING(chan) + nvpb->current_offset) != nvpb->size) { +- if (nvpb->cal_suffix0 || nvpb->cal_suffix1) { +- *(chan->cur++) = nvpb->cal_suffix0; +- *(chan->cur++) = nvpb->cal_suffix1; +- } +- +- len = (chan->cur - nvpb->pushbuf) - nvpb->current_offset; +- +- ret = nouveau_pushbuf_bo_add(chan, nvpb->buffer[nvpb->current], +- nvpb->current_offset * 4, len * 4); +- if (ret) +- return ret; +- +- nvpb->current_offset += len; +- } +- +- return bo ? nouveau_pushbuf_bo_add(chan, bo, offset, length) : 0; +-} +- +-static void +-nouveau_pushbuf_bo_unref(struct nouveau_pushbuf_priv *nvpb, int index) +-{ +- struct drm_nouveau_gem_pushbuf_bo *pbbo = &nvpb->buffers[index]; +- struct nouveau_bo *bo = (void *)(unsigned long)pbbo->user_priv; +- struct nouveau_bo_priv *nvbo = nouveau_bo(bo); +- +- if (--nvbo->pending_refcnt) +- return; +- +- if (pbbo->presumed.valid == 0) { +- nvbo->domain = pbbo->presumed.domain; +- nvbo->offset = pbbo->presumed.offset; +- } +- +- nvbo->pending = NULL; +- nouveau_bo_ref(NULL, &bo); +- +- /* we only ever remove from the tail of the pending lists, +- * so this is safe. +- */ +- nvpb->nr_buffers--; +-} +- + int + nouveau_pushbuf_flush(struct nouveau_channel *chan, unsigned min) + { + struct nouveau_device_priv *nvdev = nouveau_device(chan->device); + struct nouveau_channel_priv *nvchan = nouveau_channel(chan); + struct nouveau_pushbuf_priv *nvpb = &nvchan->pb; +- struct drm_nouveau_gem_pushbuf req; + unsigned i; + int ret; + +- ret = nouveau_pushbuf_submit(chan, NULL, 0, 0); +- if (ret) +- return ret; +- +- if (!nvpb->nr_push) ++ if (nvpb->base.remaining == nvpb->size) + return 0; + +- req.channel = chan->id; +- req.nr_push = nvpb->nr_push; +- req.push = (uint64_t)(unsigned long)nvpb->push; +- req.nr_buffers = nvpb->nr_buffers; +- req.buffers = (uint64_t)(unsigned long)nvpb->buffers; +- req.nr_relocs = nvpb->nr_relocs; +- req.relocs = (uint64_t)(unsigned long)nvpb->relocs; +- req.suffix0 = nvpb->cal_suffix0; +- req.suffix1 = nvpb->cal_suffix1; +- +- do { +- ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_PUSHBUF, ++ if (nvpb->use_cal) { ++ struct drm_nouveau_gem_pushbuf_call req; ++ ++ *(nvpb->base.cur++) = nvpb->cal_suffix0; ++ *(nvpb->base.cur++) = nvpb->cal_suffix1; ++ if (nvpb->base.remaining > 2) /* space() will fixup if not */ ++ nvpb->base.remaining -= 2; ++ ++restart_cal: ++ req.channel = chan->id; ++ req.handle = nvpb->buffer[nvpb->current]->handle; ++ req.offset = nvpb->current_offset * 4; ++ req.nr_buffers = nvpb->nr_buffers; ++ req.buffers = (uint64_t)(unsigned long)nvpb->buffers; ++ req.nr_relocs = nvpb->nr_relocs; ++ req.relocs = (uint64_t)(unsigned long)nvpb->relocs; ++ req.nr_dwords = (nvpb->base.cur - nvpb->pushbuf) - ++ nvpb->current_offset; ++ req.suffix0 = nvpb->cal_suffix0; ++ req.suffix1 = nvpb->cal_suffix1; ++ ret = drmCommandWriteRead(nvdev->fd, nvpb->no_aper_update ? ++ DRM_NOUVEAU_GEM_PUSHBUF_CALL : ++ DRM_NOUVEAU_GEM_PUSHBUF_CALL2, + &req, sizeof(req)); +- } while (ret == -EAGAIN); +- nvpb->cal_suffix0 = req.suffix0; +- nvpb->cal_suffix1 = req.suffix1; +- nvdev->base.vm_vram_size = req.vram_available; +- nvdev->base.vm_gart_size = req.gart_available; ++ if (ret == -EAGAIN) ++ goto restart_cal; ++ nvpb->cal_suffix0 = req.suffix0; ++ nvpb->cal_suffix1 = req.suffix1; ++ if (!nvpb->no_aper_update) { ++ nvdev->base.vm_vram_size = req.vram_available; ++ nvdev->base.vm_gart_size = req.gart_available; ++ } ++ } else { ++ struct drm_nouveau_gem_pushbuf req; ++ -- To UNSUBSCRIBE, email to debian-x-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/e1o20pf-0006ie...@alioth.debian.org