aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--main/xf86-video-nouveau/APKBUILD33
-rw-r--r--main/xf86-video-nouveau/git.patch2137
2 files changed, 2162 insertions, 8 deletions
diff --git a/main/xf86-video-nouveau/APKBUILD b/main/xf86-video-nouveau/APKBUILD
index af6505b660..7e6e14eca6 100644
--- a/main/xf86-video-nouveau/APKBUILD
+++ b/main/xf86-video-nouveau/APKBUILD
@@ -1,8 +1,9 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
pkgname=xf86-video-nouveau
#_gitdate=20111010
-pkgver=1.0.11
-pkgrel=3
+pkgver=1.0.11_git20150913
+_ver=${pkgver%_git*}
+pkgrel=0
pkgdesc="Open-source X.org drivers for nVidia video cards"
url="http://nouveau.freedesktop.org/"
arch="all"
@@ -11,12 +12,15 @@ depends="mesa-dri-nouveau"
depends_dev=
makedepends="randrproto renderproto videoproto xextproto libdrm-dev
xorg-server-dev util-macros libtool autoconf automake xf86driproto
- eudev-dev"
+ eudev-dev
+ automake autoconf libtool"
install=""
subpackages="$pkgname-doc"
-source="http://xorg.freedesktop.org/releases/individual/driver/xf86-video-nouveau-$pkgver.tar.bz2"
+source="http://xorg.freedesktop.org/releases/individual/driver/xf86-video-nouveau-${_ver}.tar.bz2
+ git.patch
+ "
-_builddir="$srcdir"/xf86-video-nouveau-$pkgver
+_builddir="$srcdir"/xf86-video-nouveau-$_ver
mksource() {
mkdir /tmp/${pkgname}-${_gitdate}
@@ -26,6 +30,16 @@ mksource() {
git archive --prefix=xf86-video-nouveau-${_gitdate}/ --format=tar HEAD | bzip2 > /tmp/${pkgname}-${_gitdate}/${pkgname}-${_gitdate}.tar.bz2)
}
+prepare() {
+ cd "$_builddir"
+ for i in $source; do
+ case $i in
+ *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;;
+ esac
+ done
+ autoreconf -vif
+}
+
build() {
cd "$_builddir"
export LDFLAGS="$LDFLAGS -Wl,-z,lazy"
@@ -42,6 +56,9 @@ package() {
make DESTDIR="$pkgdir" install || return 1
}
-md5sums="a0d2932d84ba10c4933c8332c9afe157 xf86-video-nouveau-1.0.11.tar.bz2"
-sha256sums="f84fe2b2787f3ea9419eac3aa86462b929a551b3dbc4de550cc83b67f3216848 xf86-video-nouveau-1.0.11.tar.bz2"
-sha512sums="4ceffc711798b98a5ee67d9df33d1a4f1d2b7d100605ea04b2e689debf745bc5a4f8907b602d1689ec6ed6400b2fc0ffe0eb0f7e7787bd2dd3cd5db1d14e90ee xf86-video-nouveau-1.0.11.tar.bz2"
+md5sums="a0d2932d84ba10c4933c8332c9afe157 xf86-video-nouveau-1.0.11.tar.bz2
+93561d95226bc2d5ea811f4277424f43 git.patch"
+sha256sums="f84fe2b2787f3ea9419eac3aa86462b929a551b3dbc4de550cc83b67f3216848 xf86-video-nouveau-1.0.11.tar.bz2
+c90d9643179d589300a45ac6fe330c44dc46faf382f0e646a8eff0791f53e903 git.patch"
+sha512sums="4ceffc711798b98a5ee67d9df33d1a4f1d2b7d100605ea04b2e689debf745bc5a4f8907b602d1689ec6ed6400b2fc0ffe0eb0f7e7787bd2dd3cd5db1d14e90ee xf86-video-nouveau-1.0.11.tar.bz2
+3ec5d839d0591f1c8525b661dc195b873bd9a992ce10000afeebdec37849b19a14e4230f4230286efa7753e5c5b86968e7a560268ca55af5d70b9f37e929be75 git.patch"
diff --git a/main/xf86-video-nouveau/git.patch b/main/xf86-video-nouveau/git.patch
new file mode 100644
index 0000000000..e234ee8a00
--- /dev/null
+++ b/main/xf86-video-nouveau/git.patch
@@ -0,0 +1,2137 @@
+diff --git a/configure.ac b/configure.ac
+index ccf320a..9c77f94 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -80,7 +80,7 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
+ XORG_DRIVER_CHECK_EXT(DRI2, [dri2proto >= 2.6])
+
+ # Checks for pkg-config packages
+-PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.17])
++PKG_CHECK_MODULES(LIBDRM, [libdrm >= 2.4.60])
+ PKG_CHECK_MODULES(LIBDRM_NOUVEAU, [libdrm_nouveau >= 2.4.25])
+ AC_SUBST(LIBDRM_NOUVEAU_CFLAGS)
+ AC_SUBST(LIBDRM_NOUVEAU_LIBS)
+@@ -140,17 +140,6 @@ if test "x$have_list_h" = xyes; then
+ #include "list.h"])
+ fi
+
+-AC_CHECK_HEADERS([glamor.h],[found_glamor_header=yes],[found_glamor_header=no],
+- [#include "xorg-server.h"])
+-AC_MSG_CHECKING([whether to include GLAMOR support])
+-if test "x$found_glamor_header" = xyes && pkg-config --exists "xorg-server >= 1.15.99.901"
+-then
+- AC_DEFINE(HAVE_GLAMOR, 1, [Build support for glamor acceleration])
+- AC_MSG_RESULT([yes])
+-else
+- AC_MSG_RESULT([no])
+-fi
+-
+ AC_CONFIG_FILES([
+ Makefile
+ src/Makefile
+diff --git a/man/nouveau.man b/man/nouveau.man
+index 129bb7f..64e4144 100644
+--- a/man/nouveau.man
++++ b/man/nouveau.man
+@@ -81,8 +81,7 @@ are supported:
+ Enable or disable the HW cursor. Default: on.
+ .TP
+ .BI "Option \*qAccelMethod\*q \*q" string \*q
+-Specify the acceleration method. One of \*qnone\*q, \*qexa\*q, or
+-\*qglamor\*q. Default: exa, except for GMxxx which default to glamor.
++Specify the acceleration method. One of \*qnone\*q, or \*qexa\*q. Default: exa.
+ .TP
+ .BI "Option \*qNoAccel\*q \*q" boolean \*q
+ Disable or enable acceleration. Default: acceleration is enabled.
+@@ -125,6 +124,12 @@ that relies on correct presentation timing behaviour as defined in that
+ specification.
+ .br
+ Default: 1.
++.TP
++.BI "Option \*qDRI\*q \*q" integer \*q
++Define the maximum level of DRI to enable. Valid values are 2 or 3.
++exa acceleration will honor the maximum level if it is supported.
++Under glamor acceleration DRI3 is always enabled if supported,
++as glamor currently does not support DRI2. Default: 2 on exa, 3 on glamor.
+ .SH "SEE ALSO"
+ __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
+ .SH AUTHORS
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 9d39a00..1e04ddf 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -35,7 +35,6 @@ nouveau_drv_la_SOURCES = \
+ nouveau_copy90b5.c \
+ nouveau_copya0b5.c \
+ nouveau_exa.c nouveau_xv.c nouveau_dri2.c \
+- nouveau_glamor.c \
+ nouveau_present.c \
+ nouveau_sync.c \
+ nouveau_wfb.c \
+@@ -123,7 +122,6 @@ EXTRA_DIST = hwdefs/nv_3ddefs.xml.h \
+ shader/Makefile \
+ nouveau_local.h \
+ nouveau_copy.h \
+- nouveau_glamor.h \
+ nouveau_present.h \
+ nouveau_sync.h \
+ nv_const.h \
+diff --git a/src/drmmode_display.c b/src/drmmode_display.c
+index 6d225cb..dc2e0ac 100644
+--- a/src/drmmode_display.c
++++ b/src/drmmode_display.c
+@@ -42,8 +42,6 @@
+ #include "libudev.h"
+ #endif
+
+-#include "nouveau_glamor.h"
+-
+ static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height);
+ typedef struct {
+ int fd;
+@@ -106,9 +104,6 @@ drmmode_from_scrn(ScrnInfoPtr scrn)
+ static inline struct nouveau_pixmap *
+ drmmode_pixmap(PixmapPtr ppix)
+ {
+- NVPtr pNv = NVPTR(xf86ScreenToScrn(ppix->drawable.pScreen));
+- if (pNv->AccelMethod == GLAMOR)
+- return nouveau_glamor_pixmap_get(ppix);
+ return nouveau_pixmap(ppix);
+ }
+
+@@ -332,7 +327,7 @@ drmmode_fbcon_copy(ScreenPtr pScreen)
+ ExaDriverPtr exa = pNv->EXADriverPtr;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ struct nouveau_bo *bo = NULL;
+- PixmapPtr pspix, pdpix;
++ PixmapPtr pspix, pdpix = NULL;
+ drmModeFBPtr fb;
+ unsigned w = pScrn->virtualX, h = pScrn->virtualY;
+ int i, ret, fbcon_id = 0;
+@@ -340,6 +335,17 @@ drmmode_fbcon_copy(ScreenPtr pScreen)
+ if (pNv->AccelMethod != EXA)
+ goto fallback;
+
++ pdpix = drmmode_pixmap_wrap(pScreen, pScrn->virtualX,
++ pScrn->virtualY, pScrn->depth,
++ pScrn->bitsPerPixel, pScrn->displayWidth *
++ pScrn->bitsPerPixel / 8, pNv->scanout,
++ NULL);
++ if (!pdpix) {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "Failed to init scanout pixmap for fbcon mirror\n");
++ goto fallback;
++ }
++
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ drmmode_crtc_private_ptr drmmode_crtc =
+ xf86_config->crtc[i]->driver_private;
+@@ -382,18 +388,6 @@ drmmode_fbcon_copy(ScreenPtr pScreen)
+ goto fallback;
+ }
+
+- pdpix = drmmode_pixmap_wrap(pScreen, pScrn->virtualX,
+- pScrn->virtualY, pScrn->depth,
+- pScrn->bitsPerPixel, pScrn->displayWidth *
+- pScrn->bitsPerPixel / 8, pNv->scanout,
+- NULL);
+- if (!pdpix) {
+- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+- "Failed to init scanout pixmap for fbcon mirror\n");
+- pScreen->DestroyPixmap(pspix);
+- goto fallback;
+- }
+-
+ exa->PrepareCopy(pspix, pdpix, 0, 0, GXcopy, ~0);
+ exa->Copy(pdpix, 0, 0, 0, 0, w, h);
+ exa->DoneCopy(pdpix);
+@@ -410,6 +404,17 @@ drmmode_fbcon_copy(ScreenPtr pScreen)
+ return;
+
+ fallback:
++ if (pdpix) {
++ if (exa->PrepareSolid(pdpix, GXcopy, ~0, 0)) {
++ exa->Solid(pdpix, 0, 0, w, h);
++ exa->DoneSolid(pdpix);
++ PUSH_KICK(pNv->pushbuf);
++ nouveau_bo_wait(pNv->scanout, NOUVEAU_BO_RDWR, pNv->client);
++ pScreen->DestroyPixmap(pdpix);
++ return;
++ }
++ pScreen->DestroyPixmap(pdpix);
++ }
+ #endif
+ if (nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR, pNv->client))
+ return;
+@@ -719,7 +724,9 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
+ screen->height = screenpix->drawable.height = max_height;
+ }
+ drmmode_crtc->scanout_pixmap_x = this_x;
+-#ifdef HAS_DIRTYTRACKING2
++#ifdef HAS_DIRTYTRACKING_ROTATION
++ PixmapStartDirtyTracking(ppix, screenpix, 0, 0, this_x, 0, RR_Rotate_0);
++#elif defined(HAS_DIRTYTRACKING2)
+ PixmapStartDirtyTracking2(ppix, screenpix, 0, 0, this_x, 0);
+ #else
+ PixmapStartDirtyTracking(ppix, screenpix, 0, 0);
+@@ -897,7 +904,7 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
+
+ for (i = 0; i < koutput->count_props; i++) {
+ props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+- if (props && (props->flags && DRM_MODE_PROP_ENUM)) {
++ if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
+ if (!strcmp(props->name, "DPMS")) {
+ mode_id = koutput->props[i];
+ drmModeFreeProperty(props);
+@@ -1381,9 +1388,6 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
+ crtc->rotation, crtc->x, crtc->y);
+ }
+
+- if (pNv->AccelMethod == GLAMOR)
+- nouveau_glamor_create_screen_resources(scrn->pScreen);
+-
+ if (old_fb_id)
+ drmModeRmFB(drmmode->fd, old_fb_id);
+ nouveau_bo_ref(NULL, &old_bo);
+diff --git a/src/nouveau_copy.c b/src/nouveau_copy.c
+index f46f0c3..d0b868d 100644
+--- a/src/nouveau_copy.c
++++ b/src/nouveau_copy.c
+@@ -61,6 +61,10 @@ nouveau_copy_init(ScreenPtr pScreen)
+
+ switch (pNv->Architecture) {
+ case NV_TESLA:
++ if (pNv->dev->chipset < 0xa3 ||
++ pNv->dev->chipset == 0xaa ||
++ pNv->dev->chipset == 0xac)
++ return FALSE;
+ data = &(struct nv04_fifo) {
+ .vram = NvDmaFB,
+ .gart = NvDmaTT,
+@@ -87,7 +91,7 @@ nouveau_copy_init(ScreenPtr pScreen)
+ &pNv->ce_channel);
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+- "[COPY} error allocating channel: %d\n", ret);
++ "[COPY] error allocating channel: %d\n", ret);
+ return FALSE;
+ }
+
+diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
+index 3361869..81ee9be 100644
+--- a/src/nouveau_dri2.c
++++ b/src/nouveau_dri2.c
+@@ -10,7 +10,9 @@
+ #else
+ #error "This driver requires a DRI2-enabled X server"
+ #endif
+-
++#ifdef DRI3
++#include "dri3.h"
++#endif
+ #include "xf86drmMode.h"
+
+ struct nouveau_dri2_buffer {
+@@ -168,9 +170,13 @@ nouveau_dri2_copy_region2(ScreenPtr pScreen, DrawablePtr pDraw, RegionPtr pRegio
+ }
+
+ if (translate && pDraw->type == DRAWABLE_WINDOW) {
++#ifdef COMPOSITE
+ PixmapPtr pPix = get_drawable_pixmap(pDraw);
+- off_x = pDraw->x - pPix->screen_x;
+- off_y = pDraw->y - pPix->screen_y;
++ off_x = -pPix->screen_x;
++ off_y = -pPix->screen_y;
++#endif
++ off_x += pDraw->x;
++ off_y += pDraw->y;
+ }
+
+ pGC = GetScratchGC(pDraw->depth, pScreen);
+@@ -1012,3 +1018,135 @@ nouveau_dri2_fini(ScreenPtr pScreen)
+ if (pNv->AccelMethod == EXA)
+ DRI2CloseScreen(pScreen);
+ }
++
++#ifdef DRI3
++static int is_render_node(int fd, struct stat *st)
++{
++ if (fstat(fd, st))
++ return 0;
++
++ if (!S_ISCHR(st->st_mode))
++ return 0;
++
++ return st->st_rdev & 0x80;
++ }
++
++static int
++nouveau_dri3_open(ScreenPtr screen, RRProviderPtr provider, int *out)
++{
++ ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
++ NVPtr pNv = NVPTR(pScrn);
++ int fd = -1;
++ struct stat buff;
++
++#ifdef O_CLOEXEC
++ fd = open(pNv->render_node, O_RDWR | O_CLOEXEC);
++#endif
++ if (fd < 0)
++ fd = open(pNv->render_node, O_RDWR);
++ if (fd < 0)
++ return -BadAlloc;
++
++ if (fstat(fd, &buff)) {
++ close(fd);
++ return -BadMatch;
++ }
++ if (!is_render_node(fd, &buff)) {
++ drm_magic_t magic;
++
++ if (drmGetMagic(fd, &magic) || drmAuthMagic(pNv->dev->fd, magic)) {
++ close(fd);
++ return -BadMatch;
++ }
++ }
++
++ *out = fd;
++ return Success;
++}
++
++static PixmapPtr nouveau_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp)
++{
++ ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
++ NVPtr pNv = NVPTR(pScrn);
++ PixmapPtr pixmap;
++ struct nouveau_bo *bo = NULL;
++ struct nouveau_pixmap *nvpix;
++
++ if (depth < 8 || depth > 32 || depth % 8)
++ return NULL;
++
++ pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0);
++ if (!pixmap)
++ return NULL;
++
++ if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL))
++ goto free_pixmap;
++
++ if (nouveau_bo_prime_handle_ref(pNv->dev, fd, &bo))
++ goto free_pixmap;
++
++ nvpix = nouveau_pixmap(pixmap);
++ nouveau_bo_ref(NULL, &nvpix->bo);
++ nvpix->bo = bo;
++ nvpix->shared = (bo->flags & NOUVEAU_BO_APER) == NOUVEAU_BO_GART;
++ return pixmap;
++
++free_pixmap:
++ screen->DestroyPixmap(pixmap);
++ return NULL;
++}
++
++static int nouveau_dri3_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, CARD16 *stride, CARD32 *size)
++{
++ struct nouveau_bo *bo = nouveau_pixmap_bo(pixmap);
++ int fd;
++
++ if (!bo || nouveau_bo_set_prime(bo, &fd) < 0)
++ return -EINVAL;
++
++ *stride = pixmap->devKind;
++ *size = bo->size;
++ return fd;
++}
++
++static dri3_screen_info_rec nouveau_dri3_screen_info = {
++ .version = DRI3_SCREEN_INFO_VERSION,
++
++ .open = nouveau_dri3_open,
++ .pixmap_from_fd = nouveau_dri3_pixmap_from_fd,
++ .fd_from_pixmap = nouveau_dri3_fd_from_pixmap
++};
++#endif
++
++Bool
++nouveau_dri3_screen_init(ScreenPtr screen)
++{
++#ifdef DRI3
++ ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
++ NVPtr pNv = NVPTR(pScrn);
++ struct stat master, render;
++ char *buf;
++
++ if (is_render_node(pNv->dev->fd, &master))
++ return TRUE;
++
++ buf = drmGetRenderDeviceNameFromFd(pNv->dev->fd);
++ if (buf && stat(buf, &render) == 0 &&
++ master.st_mode == render.st_mode) {
++ pNv->render_node = buf;
++ if (dri3_screen_init(screen, &nouveau_dri3_screen_info)) {
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "DRI3 on EXA enabled\n");
++ return TRUE;
++ }
++ else {
++ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
++ "DRI3 on EXA initialization failed\n");
++ return FALSE;
++ }
++ } else
++ free(buf);
++#endif
++
++ return TRUE;
++}
+diff --git a/src/nouveau_glamor.c b/src/nouveau_glamor.c
+deleted file mode 100644
+index ec6ebf9..0000000
+--- a/src/nouveau_glamor.c
++++ /dev/null
+@@ -1,246 +0,0 @@
+-/*
+- * Copyright 2014 Red Hat Inc.
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining a
+- * copy of this software and associated documentation files (the "Software"),
+- * to deal in the Software without restriction, including without limitation
+- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+- * and/or sell copies of the Software, and to permit persons to whom the
+- * Software is furnished to do so, subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+- * OTHER DEALINGS IN THE SOFTWARE.
+- *
+- * Authors: Ben Skeggs <bskeggs@redhat.com>
+- */
+-
+-#include "nouveau_glamor.h"
+-#ifdef HAVE_GLAMOR
+-
+-static DevPrivateKeyRec glamor_private;
+-
+-void
+-nouveau_glamor_pixmap_set(PixmapPtr pixmap, struct nouveau_pixmap *priv)
+-{
+- dixSetPrivate(&pixmap->devPrivates, &glamor_private, priv);
+-}
+-
+-struct nouveau_pixmap *
+-nouveau_glamor_pixmap_get(PixmapPtr pixmap)
+-{
+- return dixGetPrivate(&pixmap->devPrivates, &glamor_private);
+-}
+-
+-static Bool
+-nouveau_glamor_destroy_pixmap(PixmapPtr pixmap)
+-{
+- struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap);
+- if (pixmap->refcnt == 1) {
+- glamor_egl_destroy_textured_pixmap(pixmap);
+- if (priv)
+- nouveau_bo_ref(NULL, &priv->bo);
+- }
+- fbDestroyPixmap(pixmap);
+- return TRUE;
+-}
+-
+-static PixmapPtr
+-nouveau_glamor_create_pixmap(ScreenPtr screen, int w, int h, int depth,
+- unsigned usage)
+-{
+- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+- struct nouveau_pixmap *priv;
+- PixmapPtr pixmap;
+- int pitch;
+-
+- if (usage != CREATE_PIXMAP_USAGE_SHARED)
+- return glamor_create_pixmap(screen, w, h, depth, usage);
+- if (depth == 1)
+- return fbCreatePixmap(screen, w, h, depth, usage);
+- if (w > 32767 || h > 32767)
+- return NullPixmap;
+-
+- pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
+- if (pixmap == NullPixmap || !w || !h)
+- return pixmap;
+-
+- priv = calloc(1, sizeof(*priv));
+- if (!priv)
+- goto fail_priv;
+-
+- if (!nouveau_allocate_surface(scrn, w, h,
+- pixmap->drawable.bitsPerPixel,
+- usage, &pitch, &priv->bo))
+- goto fail_bo;
+-
+- nouveau_glamor_pixmap_set(pixmap, priv);
+- screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, pitch, NULL);
+-
+- if (!glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
+- pixmap->devKind)) {
+- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+- "[GLAMOR] failed to create textured PRIME pixmap.");
+- return pixmap;
+- }
+-
+- return pixmap;
+-fail_bo:
+- free(priv);
+-fail_priv:
+- fbDestroyPixmap(pixmap);
+- return fbCreatePixmap(screen, w, h, depth, usage);
+-}
+-
+-static Bool
+-nouveau_glamor_share_pixmap_backing(PixmapPtr pixmap, ScreenPtr slave,
+- void **phandle)
+-{
+- struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap);
+- int ret, handle;
+-
+- ret = nouveau_bo_set_prime(priv->bo, &handle);
+- if (ret)
+- return FALSE;
+-
+- priv->shared = TRUE;
+- *phandle = (void *)(long)handle;
+- return TRUE;
+-}
+-
+-static Bool
+-nouveau_glamor_set_shared_pixmap_backing(PixmapPtr pixmap, void *_handle)
+-{
+- struct nouveau_pixmap *priv = nouveau_glamor_pixmap_get(pixmap);
+- ScreenPtr screen = pixmap->drawable.pScreen;
+- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+- NVPtr pNv = NVPTR(scrn);
+- struct nouveau_bo *bo;
+- int ret, handle = (int)(long)_handle;
+-
+- ret = nouveau_bo_prime_handle_ref(pNv->dev, handle, &bo);
+- if (ret)
+- return FALSE;
+-
+- priv->bo = bo;
+- priv->shared = TRUE;
+- close(handle);
+-
+- if (!glamor_egl_create_textured_pixmap(pixmap, priv->bo->handle,
+- pixmap->devKind)) {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+- "[GLAMOR] failed to get PRIME drawable\n");
+- return FALSE;
+- }
+-
+- return TRUE;
+-}
+-
+-static void
+-nouveau_glamor_flush(ScrnInfoPtr pScrn)
+-{
+- glamor_block_handler(pScrn->pScreen);
+-}
+-
+-Bool
+-nouveau_glamor_create_screen_resources(ScreenPtr screen)
+-{
+- PixmapPtr ppix = screen->GetScreenPixmap(screen);
+- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+- NVPtr pNv = NVPTR(scrn);
+-
+- if (!glamor_glyphs_init(screen))
+- return FALSE;
+-
+- if (!glamor_egl_create_textured_screen_ext(screen,
+- pNv->scanout->handle,
+- scrn->displayWidth *
+- scrn->bitsPerPixel / 8,
+- NULL))
+- return FALSE;
+-
+- if (!nouveau_glamor_pixmap_get(ppix)) {
+- struct nouveau_pixmap *priv = calloc(1, sizeof(*priv));
+- if (priv) {
+- nouveau_bo_ref(pNv->scanout, &priv->bo);
+- nouveau_glamor_pixmap_set(ppix, priv);
+- }
+- }
+-
+- return TRUE;
+-}
+-
+-Bool
+-nouveau_glamor_pre_init(ScrnInfoPtr scrn)
+-{
+- NVPtr pNv = NVPTR(scrn);
+- pointer glamor_module;
+-
+- if (scrn->depth < 24) {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+- "[GLAMOR] requires depth >= 24\n");
+- return FALSE;
+- }
+-
+- if ((glamor_module = xf86LoadSubModule(scrn, GLAMOR_EGL_MODULE_NAME))) {
+- if (!glamor_egl_init(scrn, pNv->dev->fd)) {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+- "[GLAMOR] failed to initialise EGL\n");
+- return FALSE;
+- }
+- } else {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR, "[GLAMOR] unavailable\n");
+- return FALSE;
+- }
+-
+- xf86DrvMsg(scrn->scrnIndex, X_INFO, "[GLAMOR] EGL initialised\n");
+- return TRUE;
+-}
+-
+-Bool
+-nouveau_glamor_init(ScreenPtr screen)
+-{
+- ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+- NVPtr pNv = NVPTR(scrn);
+-
+- if (!glamor_init(screen, GLAMOR_INVERTED_Y_AXIS |
+- GLAMOR_USE_EGL_SCREEN |
+- GLAMOR_USE_SCREEN |
+- GLAMOR_USE_PICTURE_SCREEN)) {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+- "[GLAMOR] failed to initialise\n");
+- return FALSE;
+- }
+-
+- if (!glamor_egl_init_textured_pixmap(screen)) {
+- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+- "[GLAMOR] failed to initialize screen pixmap\n");
+- return FALSE;
+- }
+-
+- if (!dixRegisterPrivateKey(&glamor_private, PRIVATE_PIXMAP, 0))
+- return FALSE;
+-
+- screen->CreatePixmap = nouveau_glamor_create_pixmap;
+- screen->DestroyPixmap = nouveau_glamor_destroy_pixmap;
+- screen->SharePixmapBacking = nouveau_glamor_share_pixmap_backing;
+- screen->SetSharedPixmapBacking = nouveau_glamor_set_shared_pixmap_backing;
+-
+- xf86DrvMsg(scrn->scrnIndex, X_INFO, "[GLAMOR] initialised\n");
+- pNv->Flush = nouveau_glamor_flush;
+- return TRUE;
+-}
+-
+-XF86VideoAdaptorPtr
+-nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt)
+-{
+- return glamor_xv_init(pScreen, num_adapt);
+-}
+-#endif
+diff --git a/src/nouveau_glamor.h b/src/nouveau_glamor.h
+deleted file mode 100644
+index fb6565d..0000000
+--- a/src/nouveau_glamor.h
++++ /dev/null
+@@ -1,33 +0,0 @@
+-#ifndef __NOUVEAU_GLAMOR_H__
+-#define __NOUVEAU_GLAMOR_H__
+-
+-#ifdef HAVE_CONFIG_H
+-#include "config.h"
+-#endif
+-#include "xf86xv.h"
+-
+-#ifdef HAVE_GLAMOR
+-#include "nv_include.h"
+-#define GLAMOR_FOR_XORG 1
+-#include "glamor.h"
+-
+-Bool nouveau_glamor_pre_init(ScrnInfoPtr scrn);
+-Bool nouveau_glamor_init(ScreenPtr screen);
+-Bool nouveau_glamor_create_screen_resources(ScreenPtr screen);
+-XF86VideoAdaptorPtr nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt);
+-void nouveau_glamor_pixmap_set(PixmapPtr pixmap, struct nouveau_pixmap *priv);
+-struct nouveau_pixmap *nouveau_glamor_pixmap_get(PixmapPtr pixmap);
+-#else
+-static inline Bool nouveau_glamor_pre_init(ScrnInfoPtr scrn) { return FALSE; }
+-static inline Bool nouveau_glamor_init(ScreenPtr screen) { return FALSE; }
+-static inline Bool
+-nouveau_glamor_create_screen_resources(ScreenPtr screen) { return FALSE; }
+-static inline void
+-nouveau_glamor_pixmap_set(PixmapPtr pixmap, void *priv) { }
+-static inline struct nouveau_pixmap *
+-nouveau_glamor_pixmap_get(PixmapPtr pixmap) { return NULL; }
+-static inline XF86VideoAdaptorPtr
+-nouveau_glamor_xv_init(ScreenPtr pScreen, int num_adapt) { return NULL; }
+-#endif
+-
+-#endif
+diff --git a/src/nouveau_present.c b/src/nouveau_present.c
+index ea1686e..482ac6e 100644
+--- a/src/nouveau_present.c
++++ b/src/nouveau_present.c
+@@ -23,9 +23,8 @@
+ */
+
+ #include "nouveau_present.h"
+-#if defined(DRI3) && defined(HAVE_GLAMOR)
++#if defined(DRI3)
+ #include "nv_include.h"
+-#include "nouveau_glamor.h"
+ #include "xf86drmMode.h"
+
+ struct nouveau_present {
+@@ -177,34 +176,12 @@ static Bool
+ nouveau_present_flip_exec(ScrnInfoPtr scrn, uint64_t event_id, int sync,
+ uint64_t target_msc, PixmapPtr pixmap, Bool vsync)
+ {
+- ScreenPtr screen = scrn->pScreen;
+- struct nouveau_pixmap *priv;
++ struct nouveau_pixmap *priv = nouveau_pixmap(pixmap);
+ NVPtr pNv = NVPTR(scrn);
+ uint32_t next_fb;
+- CARD16 stride;
+- CARD32 size;
+ void *token;
+ int ret;
+
+- priv = nouveau_glamor_pixmap_get(pixmap);
+- if (priv == NULL) {
+- int fd = glamor_fd_from_pixmap(screen, pixmap, &stride, &size);
+- if (fd < 0)
+- return FALSE;
+-
+- priv = calloc(1, sizeof(*priv));
+- if (!priv)
+- return FALSE;
+-
+- ret = nouveau_bo_prime_handle_ref(pNv->dev, fd, &priv->bo);
+- if (ret) {
+- free(priv);
+- return FALSE;
+- }
+-
+- nouveau_glamor_pixmap_set(pixmap, priv);
+- }
+-
+ ret = drmModeAddFB(pNv->dev->fd, pixmap->drawable.width,
+ pixmap->drawable.height, pixmap->drawable.depth,
+ pixmap->drawable.bitsPerPixel, pixmap->devKind,
+@@ -289,7 +266,7 @@ nouveau_present_fini(ScreenPtr screen)
+ }
+ }
+
+-int
++Bool
+ nouveau_present_init(ScreenPtr screen)
+ {
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+@@ -298,12 +275,9 @@ nouveau_present_init(ScreenPtr screen)
+ uint64_t value;
+ int ret;
+
+- if (pNv->AccelMethod != GLAMOR)
+- return -ENOSYS;
+-
+ present = pNv->present = calloc(1, sizeof(*present));
+ if (!present)
+- return -ENOMEM;
++ return FALSE;
+
+ present->info.version = PRESENT_SCREEN_INFO_VERSION;
+ present->info.get_crtc = nouveau_present_crtc;
+diff --git a/src/nouveau_present.h b/src/nouveau_present.h
+index 958c2f7..e807b6d 100644
+--- a/src/nouveau_present.h
++++ b/src/nouveau_present.h
+@@ -8,7 +8,7 @@
+ #include "config.h"
+ #endif
+
+-#if defined(DRI3) && defined(HAVE_GLAMOR)
++#if defined(DRI3)
+ #include "present.h"
+ Bool nouveau_present_init(ScreenPtr pScreen);
+ void nouveau_present_fini(ScreenPtr pScreen);
+diff --git a/src/nouveau_wfb.c b/src/nouveau_wfb.c
+index 10f0f27..a52f2fd 100644
+--- a/src/nouveau_wfb.c
++++ b/src/nouveau_wfb.c
+@@ -26,7 +26,6 @@
+ */
+
+ #include "nv_include.h"
+-#include "nouveau_glamor.h"
+
+ struct wfb_pixmap {
+ PixmapPtr ppix;
+@@ -136,12 +135,7 @@ nouveau_wfb_setup_wrap(ReadMemoryProcPtr *pRead, WriteMemoryProcPtr *pWrite,
+
+ ppix = NVGetDrawablePixmap(pDraw);
+ if (ppix) {
+- NVPtr pNv = NVPTR(xf86ScreenToScrn(pDraw->pScreen));
+- struct nouveau_pixmap *priv;
+- if (pNv->AccelMethod == GLAMOR)
+- priv = nouveau_glamor_pixmap_get(ppix);
+- else
+- priv = nouveau_pixmap(ppix);
++ struct nouveau_pixmap *priv = nouveau_pixmap(ppix);
+ bo = priv ? priv->bo : NULL;
+ }
+
+diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
+index a479d38..d514dbf 100644
+--- a/src/nouveau_xv.c
++++ b/src/nouveau_xv.c
+@@ -38,7 +38,6 @@
+
+ #include "nv_include.h"
+ #include "nv_dma.h"
+-#include "nouveau_glamor.h"
+
+ #include "vl_hwmc.h"
+
+@@ -1069,6 +1068,8 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
+ if (pPriv->grabbedByV4L)
+ return Success;
+
++ if (width > pPriv->max_image_dim || height > pPriv->max_image_dim)
++ return BadMatch;
+
+ NV_set_action_flags(pScrn, pDraw, pPriv, id, drw_x, drw_y, drw_w,
+ drw_h, &action_flags);
+@@ -1442,11 +1443,6 @@ NVQueryImageAttributes(ScrnInfoPtr pScrn, int id,
+ {
+ int size, tmp;
+
+- if (*w > IMAGE_MAX_W)
+- *w = IMAGE_MAX_W;
+- if (*h > IMAGE_MAX_H)
+- *h = IMAGE_MAX_H;
+-
+ *w = (*w + 1) & ~1; // width rounded up to an even number
+ if (offsets)
+ offsets[0] = 0;
+@@ -1707,6 +1703,7 @@ NVSetupBlitVideo (ScreenPtr pScreen)
+ pPriv->bicubic = FALSE;
+ pPriv->doubleBuffer = FALSE;
+ pPriv->SyncToVBlank = (pNv->dev->chipset >= 0x11);
++ pPriv->max_image_dim = 2048;
+
+ pNv->blitAdaptor = adapt;
+
+@@ -1767,6 +1764,7 @@ NVSetupOverlayVideoAdapter(ScreenPtr pScreen)
+ pPriv->blitter = FALSE;
+ pPriv->texture = FALSE;
+ pPriv->bicubic = FALSE;
++ pPriv->max_image_dim = 2048;
+
+ NVSetPortDefaults (pScrn, pPriv);
+
+@@ -1968,6 +1966,7 @@ NV30SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
+ pPriv->bicubic = bicubic;
+ pPriv->doubleBuffer = FALSE;
+ pPriv->SyncToVBlank = TRUE;
++ pPriv->max_image_dim = 4096;
+
+ if (bicubic)
+ pNv->textureAdaptor[1] = adapt;
+@@ -2049,6 +2048,7 @@ NV40SetupTexturedVideo (ScreenPtr pScreen, Bool bicubic)
+ pPriv->bicubic = bicubic;
+ pPriv->doubleBuffer = FALSE;
+ pPriv->SyncToVBlank = TRUE;
++ pPriv->max_image_dim = 4096;
+
+ if (bicubic)
+ pNv->textureAdaptor[1] = adapt;
+@@ -2182,9 +2182,6 @@ NVInitVideo(ScreenPtr pScreen)
+ }
+
+ NVSetupTexturedVideo(pScreen, textureAdaptor);
+- } else
+- if (pNv->AccelMethod == GLAMOR) {
+- blitAdaptor = nouveau_glamor_xv_init(pScreen, 16);
+ }
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+diff --git a/src/nv04_exa.c b/src/nv04_exa.c
+index 7a58dd7..d5dec68 100644
+--- a/src/nv04_exa.c
++++ b/src/nv04_exa.c
+@@ -49,7 +49,8 @@ NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask)
+ NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+
+- planemask |= ~0 << ppix->drawable.bitsPerPixel;
++ if (ppix->drawable.bitsPerPixel < 32)
++ planemask |= ~0 << ppix->drawable.bitsPerPixel;
+ if (planemask != ~0 || alu != GXcopy) {
+ if (ppix->drawable.bitsPerPixel == 32)
+ return FALSE;
+diff --git a/src/nv10_exa.c b/src/nv10_exa.c
+index 78bc739..7daa281 100644
+--- a/src/nv10_exa.c
++++ b/src/nv10_exa.c
+@@ -697,9 +697,9 @@ NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0);
+ }
+
+- BEGIN_NV04(push, SUBC_3D(0x290), 1);
++ BEGIN_NV04(push, NV10_3D(UNK0290), 1);
+ PUSH_DATA (push, (0x10<<16)|1);
+- BEGIN_NV04(push, SUBC_3D(0x3f4), 1);
++ BEGIN_NV04(push, NV10_3D(UNK03F4), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV04_GRAPH(3D, NOP), 1);
+@@ -707,12 +707,12 @@ NVAccelInitNV10TCL(ScrnInfoPtr pScrn)
+
+ if (class != NV10_3D_CLASS) {
+ /* For nv11, nv17 */
+- BEGIN_NV04(push, SUBC_3D(0x120), 3);
++ BEGIN_NV04(push, SUBC_3D(NV15_3D_FLIP_SET_READ), 3);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 2);
+
+- BEGIN_NV04(push, SUBC_BLIT(0x120), 3);
++ BEGIN_NV04(push, NV15_BLIT(FLIP_SET_READ), 3);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 2);
+diff --git a/src/nv30_exa.c b/src/nv30_exa.c
+index 21586e9..9d63119 100644
+--- a/src/nv30_exa.c
++++ b/src/nv30_exa.c
+@@ -644,16 +644,16 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0);
+ }
+
+- BEGIN_NV04(push, SUBC_3D(0x220), 1);
++ BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+ PUSH_DATA (push, 1);
+
+- BEGIN_NV04(push, SUBC_3D(0x03b0), 1);
+- PUSH_DATA (push, 0x00100000);
+- BEGIN_NV04(push, SUBC_3D(0x1454), 1);
++ BEGIN_NV04(push, NV40_3D(MIPMAP_ROUNDING), 1);
++ PUSH_DATA (push, NV40_3D_MIPMAP_ROUNDING_MODE_DOWN);
++ BEGIN_NV04(push, NV30_3D(FLATSHADE_FIRST), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, SUBC_3D(0x1d80), 1);
+ PUSH_DATA (push, 3);
+- BEGIN_NV04(push, SUBC_3D(0x1450), 1);
++ BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1);
+ PUSH_DATA (push, 0x00030004);
+
+ /* NEW */
+@@ -670,17 +670,17 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0);
+ PUSH_DATA (push, 0); PUSH_DATA (push, 0); PUSH_DATA (push, 0);
+
+- BEGIN_NV04(push, SUBC_3D(0x120), 3);
++ BEGIN_NV04(push, NV30_3D(FLIP_SET_READ), 3);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 2);
+
+- BEGIN_NV04(push, SUBC_BLIT(0x120), 3);
++ BEGIN_NV04(push, NV15_BLIT(FLIP_SET_READ), 3);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 2);
+
+- BEGIN_NV04(push, SUBC_3D(0x1d88), 1);
++ BEGIN_NV04(push, NV30_3D(COORD_CONVENTIONS), 1);
+ PUSH_DATA (push, 0x00001200);
+
+ BEGIN_NV04(push, NV30_3D(MULTISAMPLE_CONTROL), 1);
+@@ -742,7 +742,7 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
+ * it's not needed between nouveau restarts - which suggests that
+ * the 3D context (wherever it's stored?) survives somehow.
+ */
+- //BEGIN_NV04(push, SUBC_3D(0x1d60),1);
++ //BEGIN_NV04(push, NV30_3D(FP_CONTROL),1);
+ //PUSH_DATA (push, 0x03008000);
+
+ int w=4096;
+@@ -756,7 +756,7 @@ NVAccelInitNV30TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0x0);
+ BEGIN_NV04(push, NV30_3D(VIEWPORT_TX_ORIGIN), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_3D(0x0a00), 2);
++ BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
+ PUSH_DATA (push, (w<<16) | 0);
+ PUSH_DATA (push, (h<<16) | 0);
+ BEGIN_NV04(push, NV30_3D(VIEWPORT_CLIP_HORIZ(0)), 2);
+diff --git a/src/nv40_exa.c b/src/nv40_exa.c
+index c9e99e0..8a1e2b5 100644
+--- a/src/nv40_exa.c
++++ b/src/nv40_exa.c
+@@ -633,13 +633,13 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0x0020ffff);
+ BEGIN_NV04(push, SUBC_3D(0x1d64), 1);
+ PUSH_DATA (push, 0x00d30000);
+- BEGIN_NV04(push, SUBC_3D(0x1e94), 1);
+- PUSH_DATA (push, 0x00000001);
++ BEGIN_NV04(push, NV30_3D(ENGINE), 1);
++ PUSH_DATA (push, NV30_3D_ENGINE_FP);
+
+ /* This removes the the stair shaped tearing that i get. */
+ /* Verified on one G70 card that it doesn't cause regressions for people without the problem. */
+ /* The blob sets this up by default for NV43. */
+- BEGIN_NV04(push, SUBC_3D(0x1450), 1);
++ BEGIN_NV04(push, NV30_3D(FP_REG_CONTROL), 1);
+ PUSH_DATA (push, 0x0000000F);
+
+ BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
+@@ -690,7 +690,7 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0);
+ }
+
+- BEGIN_NV04(push, SUBC_3D(0x1d78), 1);
++ BEGIN_NV04(push, NV30_3D(DEPTH_CONTROL), 1);
+ PUSH_DATA (push, 0x110);
+
+ BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
+diff --git a/src/nv50_accel.c b/src/nv50_accel.c
+index b27f67a..bce5a81 100644
+--- a/src/nv50_accel.c
++++ b/src/nv50_accel.c
+@@ -110,13 +110,13 @@ NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
+ /* Magics from nv, no clue what they do, but at least some
+ * of them are needed to avoid crashes.
+ */
+- BEGIN_NV04(push, SUBC_2D(0x0260), 1);
++ BEGIN_NV04(push, NV50_2D(UNK260), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(CLIP_ENABLE), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NV04(push, NV50_2D(COLOR_KEY_ENABLE), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_2D(0x058c), 1);
++ BEGIN_NV04(push, NV50_2D(UNK58C), 1);
+ PUSH_DATA (push, 0x111);
+
+ pNv->currentRop = 0xfffffffa;
+@@ -205,8 +205,10 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
+
+ BEGIN_NV04(push, NV50_3D(VIEWPORT_TRANSFORM_EN), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_3D(0x0f90), 1);
++ BEGIN_NV04(push, NV50_3D(COLOR_MASK_COMMON), 1);
+ PUSH_DATA (push, 1);
++ BEGIN_NV04(push, NV50_3D(ZETA_ENABLE), 1);
++ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(TIC_ADDRESS_HIGH), 3);
+ PUSH_DATA (push, (pNv->scratch->offset + TIC_OFFSET) >> 32);
+@@ -223,65 +225,65 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
+
+ PUSH_DATAu(push, pNv->scratch, PVP_OFFSET, 30 * 2);
+ PUSH_DATA (push, 0x10000001);
+- PUSH_DATA (push, 0x0423c788);
++ PUSH_DATA (push, 0x0423c788); /* mov b32 o[0x0] a[0x0] */
+ PUSH_DATA (push, 0x10000205);
+- PUSH_DATA (push, 0x0423c788);
++ PUSH_DATA (push, 0x0423c788); /* mov b32 o[0x4] a[0x4] */
+ PUSH_DATA (push, 0xc0800401);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r0 a[0x8] c0[0x0] */
+ PUSH_DATA (push, 0xc0830405);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r1 a[0x8] c0[0xc] */
+ PUSH_DATA (push, 0xc0860409);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r2 a[0x8] c0[0x18] */
+ PUSH_DATA (push, 0xe0810601);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* add f32 $r0 (mul a[0xc] c0[0x4]) $r0 */
+ PUSH_DATA (push, 0xe0840605);
+- PUSH_DATA (push, 0x00204780);
++ PUSH_DATA (push, 0x00204780); /* add f32 $r1 (mul a[0xc] c0[0x10]) $r1 */
+ PUSH_DATA (push, 0xe0870609);
+- PUSH_DATA (push, 0x00208780);
++ PUSH_DATA (push, 0x00208780); /* add f32 $r2 (mul a[0xc] c0[0x1c]) $r2 */
+ PUSH_DATA (push, 0xb1000001);
+- PUSH_DATA (push, 0x00008780);
++ PUSH_DATA (push, 0x00008780); /* add rn f32 $r0 $r0 c0[0x8] */
+ PUSH_DATA (push, 0xb1000205);
+- PUSH_DATA (push, 0x00014780);
++ PUSH_DATA (push, 0x00014780); /* add rn f32 $r1 $r1 c0[0x14] */
+ PUSH_DATA (push, 0xb1000409);
+- PUSH_DATA (push, 0x00020780);
++ PUSH_DATA (push, 0x00020780); /* add rn f32 $r2 $r2 c0[0x20] */
+ PUSH_DATA (push, 0x90000409);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* rcp f32 $r2 $r2 */
+ PUSH_DATA (push, 0xc0020001);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r0 $r0 $r2 */
+ PUSH_DATA (push, 0xc0020205);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r1 $r1 $r2 */
+ PUSH_DATA (push, 0xc0890009);
+- PUSH_DATA (push, 0x00000788);
++ PUSH_DATA (push, 0x00000788); /* mul rn f32 o[0x8] $r0 c0[0x24] */
+ PUSH_DATA (push, 0xc08a020d);
+- PUSH_DATA (push, 0x00000788);
++ PUSH_DATA (push, 0x00000788); /* mul rn f32 o[0xc] $r1 c0[0x28] */
+ PUSH_DATA (push, 0xc08b0801);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r0 a[0x10] c0[0x2c] */
+ PUSH_DATA (push, 0xc08e0805);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r1 a[0x10] c0[0x38] */
+ PUSH_DATA (push, 0xc0910809);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* mul rn f32 $r2 a[0x10] c0[0x44] */
+ PUSH_DATA (push, 0xe08c0a01);
+- PUSH_DATA (push, 0x00200780);
++ PUSH_DATA (push, 0x00200780); /* add f32 $r0 (mul a[0x14] c0[0x30]) $r0 */
+ PUSH_DATA (push, 0xe08f0a05);
+- PUSH_DATA (push, 0x00204780);
++ PUSH_DATA (push, 0x00204780); /* add f32 $r1 (mul a[0x14] c0[0x3c]) $r1 */
+ PUSH_DATA (push, 0xe0920a09);
+- PUSH_DATA (push, 0x00208780);
++ PUSH_DATA (push, 0x00208780); /* add f32 $r2 (mul a[0x14] c0[0x48]) $r2 */
+ PUSH_DATA (push, 0xb1000001);
+- PUSH_DATA (push, 0x00034780);
++ PUSH_DATA (push, 0x00034780); /* add rn f32 $r0 $r0 c0[0x34] */
+ PUSH_DATA (push, 0xb1000205);
+- PUSH_DATA (push, 0x00040780);
++ PUSH_DATA (push, 0x00040780); /* add rn f32 $r1 $r1 c0[0x40] */
+ PUSH_DATA (push, 0xb1000409);
+- PUSH_DATA (push, 0x0004c780);
++ PUSH_DATA (push, 0x0004c780); /* add rn f32 $r2 $r2 c0[0x4c] */
+ PUSH_DATA (push, 0x90000409);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* rcp f32 $r2 $r2 */
+ PUSH_DATA (push, 0xc0020001);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r0 $r0 $r2 */
+ PUSH_DATA (push, 0xc0020205);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r1 $r1 $r2 */
+ PUSH_DATA (push, 0xc0940011);
+- PUSH_DATA (push, 0x00000788);
++ PUSH_DATA (push, 0x00000788); /* mul rn f32 o[0x10] $r0 c0[0x50] */
+ PUSH_DATA (push, 0xc0950215);
+- PUSH_DATA (push, 0x00000789);
++ PUSH_DATA (push, 0x00000789); /* exit mul rn f32 o[0x14] $r1 c0[0x54] */
+
+ /* fetch only VTX_ATTR[0,8,9].xy */
+ BEGIN_NV04(push, NV50_3D(VP_ATTR_EN(0)), 2);
+@@ -305,116 +307,116 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 0);
+
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_S, 6);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82010200);
+- PUSH_DATA (push, 0x82020204);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82010200); /* interp $r0 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020204); /* interp $r1 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf6400001);
+- PUSH_DATA (push, 0x0000c785);
++ PUSH_DATA (push, 0x0000c785); /* exit texauto live $r0:$r1:$r2:$r3 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_C, 16);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82030210);
+- PUSH_DATA (push, 0x82040214);
+- PUSH_DATA (push, 0x82010200);
+- PUSH_DATA (push, 0x82020204);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82030210); /* interp $r4 v[0xc] $r1 */
++ PUSH_DATA (push, 0x82040214); /* interp $r5 v[0x10] $r1 */
++ PUSH_DATA (push, 0x82010200); /* interp $r0 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020204); /* interp $r1 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf6400001);
+- PUSH_DATA (push, 0x0000c784);
++ PUSH_DATA (push, 0x0000c784); /* texauto live $r0:$r1:$r2:$r3 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
+ PUSH_DATA (push, 0xf0400211);
+- PUSH_DATA (push, 0x00008784);
+- PUSH_DATA (push, 0xc0040000);
+- PUSH_DATA (push, 0xc0040204);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r4 $t1 $s0 $r4:$r5 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0xc0040000); /* mul f32 $r0 $r0 $r4 */
++ PUSH_DATA (push, 0xc0040204); /* mul f32 $r1 $r1 $r4 */
+ PUSH_DATA (push, 0xc0040409);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r2 $r2 $r4 */
+ PUSH_DATA (push, 0xc004060d);
+- PUSH_DATA (push, 0x00000781);
++ PUSH_DATA (push, 0x00000781); /* exit mul rn f32 $r3 $r3 $r4 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_CCA, 16);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82030210);
+- PUSH_DATA (push, 0x82040214);
+- PUSH_DATA (push, 0x82010200);
+- PUSH_DATA (push, 0x82020204);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82030210); /* interp $r4 v[0xc] $r1 */
++ PUSH_DATA (push, 0x82040214); /* interp $r5 v[0x10] $r1 */
++ PUSH_DATA (push, 0x82010200); /* interp $r0 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020204); /* interp $r1 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf6400001);
+- PUSH_DATA (push, 0x0000c784);
++ PUSH_DATA (push, 0x0000c784); /* texauto live $r0:$r1:$r2:$r3 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
+ PUSH_DATA (push, 0xf6400211);
+- PUSH_DATA (push, 0x0000c784);
+- PUSH_DATA (push, 0xc0040000);
+- PUSH_DATA (push, 0xc0050204);
++ PUSH_DATA (push, 0x0000c784); /* texauto live $r4:$r5:$r6:$r7 $t1 $s0 $r4:$r5 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0xc0040000); /* mul f32 $r0 $r0 $r4 */
++ PUSH_DATA (push, 0xc0050204); /* mul f32 $r1 $r1 $r5 */
+ PUSH_DATA (push, 0xc0060409);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r2 $r2 $r6 */
+ PUSH_DATA (push, 0xc007060d);
+- PUSH_DATA (push, 0x00000781);
++ PUSH_DATA (push, 0x00000781); /* exit mul rn f32 $r3 $r3 $r7 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_CCASA, 16);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82030200);
+- PUSH_DATA (push, 0x82040204);
+- PUSH_DATA (push, 0x82010210);
+- PUSH_DATA (push, 0x82020214);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82030200); /* interp $r0 v[0xc] $r1 */
++ PUSH_DATA (push, 0x82040204); /* interp $r1 v[0x10] $r1 */
++ PUSH_DATA (push, 0x82010210); /* interp $r4 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020214); /* interp $r5 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf6400201);
+- PUSH_DATA (push, 0x0000c784);
++ PUSH_DATA (push, 0x0000c784); /* texauto live $r0:$r1:$r2:$r3 $t1 $s0 $r0:$r1 0x0 0x0 0x0 */
+ PUSH_DATA (push, 0xf0400011);
+- PUSH_DATA (push, 0x00008784);
+- PUSH_DATA (push, 0xc0040000);
+- PUSH_DATA (push, 0xc0040204);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r4 $t0 $s0 $r4:$r5 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0xc0040000); /* mul f32 $r0 $r0 $r4 */
++ PUSH_DATA (push, 0xc0040204); /* mul f32 $r1 $r1 $r4 */
+ PUSH_DATA (push, 0xc0040409);
+- PUSH_DATA (push, 0x00000780);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r2 $r2 $r4 */
+ PUSH_DATA (push, 0xc004060d);
+- PUSH_DATA (push, 0x00000781);
++ PUSH_DATA (push, 0x00000781); /* exit mul rn f32 $r3 $r3 $r4 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_S_A8, 10);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82010200);
+- PUSH_DATA (push, 0x82020204);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82010200); /* interp $r0 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020204); /* interp $r1 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf0400001);
+- PUSH_DATA (push, 0x00008784);
+- PUSH_DATA (push, 0x10008004);
+- PUSH_DATA (push, 0x10008008);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r0 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0x10008004); /* mov b32 $r1 $r0 */
++ PUSH_DATA (push, 0x10008008); /* mov b32 $r2 $r0 */
+ PUSH_DATA (push, 0x1000000d);
+- PUSH_DATA (push, 0x0403c781);
++ PUSH_DATA (push, 0x0403c781); /* exit mov b32 $r3 $r0 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_C_A8, 16);
+- PUSH_DATA (push, 0x80000000);
+- PUSH_DATA (push, 0x90000004);
+- PUSH_DATA (push, 0x82030208);
+- PUSH_DATA (push, 0x8204020c);
+- PUSH_DATA (push, 0x82010200);
+- PUSH_DATA (push, 0x82020204);
++ PUSH_DATA (push, 0x80000000); /* interp $r0 v[0x0] */
++ PUSH_DATA (push, 0x90000004); /* rcp f32 $r1 $r0 */
++ PUSH_DATA (push, 0x82030208); /* interp $r2 v[0xc] $r1 */
++ PUSH_DATA (push, 0x8204020c); /* interp $r3 v[0x10] $r1 */
++ PUSH_DATA (push, 0x82010200); /* interp $r0 v[0x4] $r1 */
++ PUSH_DATA (push, 0x82020204); /* interp $r1 v[0x8] $r1 */
+ PUSH_DATA (push, 0xf0400001);
+- PUSH_DATA (push, 0x00008784);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r0 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
+ PUSH_DATA (push, 0xf0400209);
+- PUSH_DATA (push, 0x00008784);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r2 $t1 $s0 $r2:$r3 0x0 0x0 0x0 */
+ PUSH_DATA (push, 0xc002000d);
+- PUSH_DATA (push, 0x00000780);
+- PUSH_DATA (push, 0x10008600);
+- PUSH_DATA (push, 0x10008604);
++ PUSH_DATA (push, 0x00000780); /* mul rn f32 $r3 $r0 $r2 */
++ PUSH_DATA (push, 0x10008600); /* mov b32 $r0 $r3 */
++ PUSH_DATA (push, 0x10008604); /* mov b32 $r1 $r3 */
+ PUSH_DATA (push, 0x10000609);
+- PUSH_DATA (push, 0x0403c781);
++ PUSH_DATA (push, 0x0403c781); /* exit mov b32 $r2 $r3 */
+ PUSH_DATAu(push, pNv->scratch, PFP_OFFSET + PFP_NV12, 24);
+- PUSH_DATA (push, 0x80000008);
+- PUSH_DATA (push, 0x90000408);
+- PUSH_DATA (push, 0x82010400);
+- PUSH_DATA (push, 0x82020404);
++ PUSH_DATA (push, 0x80000008); /* interp $r2 v[0x0] */
++ PUSH_DATA (push, 0x90000408); /* rcp f32 $r2 $r2 */
++ PUSH_DATA (push, 0x82010400); /* interp $r0 v[0x4] $r2 */
++ PUSH_DATA (push, 0x82020404); /* interp $r1 v[0x8] $r2 */
+ PUSH_DATA (push, 0xf0400001);
+- PUSH_DATA (push, 0x00008784);
+- PUSH_DATA (push, 0xc0800014);
+- PUSH_DATA (push, 0xb0810a0c);
+- PUSH_DATA (push, 0xb0820a10);
+- PUSH_DATA (push, 0xb0830a14);
+- PUSH_DATA (push, 0x82010400);
+- PUSH_DATA (push, 0x82020404);
++ PUSH_DATA (push, 0x00008784); /* texauto live #:#:#:$r0 $t0 $s0 $r0:$r1 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0xc0800014); /* mul f32 $r5 $r0 c0[0x0] */
++ PUSH_DATA (push, 0xb0810a0c); /* add f32 $r3 $r5 c0[0x4] */
++ PUSH_DATA (push, 0xb0820a10); /* add f32 $r4 $r5 c0[0x8] */
++ PUSH_DATA (push, 0xb0830a14); /* add f32 $r5 $r5 c0[0xc] */
++ PUSH_DATA (push, 0x82010400); /* interp $r0 v[0x4] $r2 */
++ PUSH_DATA (push, 0x82020404); /* interp $r1 v[0x8] $r2 */
+ PUSH_DATA (push, 0xf0400201);
+- PUSH_DATA (push, 0x0000c784);
+- PUSH_DATA (push, 0xe084000c);
+- PUSH_DATA (push, 0xe0850010);
++ PUSH_DATA (push, 0x0000c784); /* texauto live #:#:$r0:$r1 $t1 $s0 $r0:$r1 0x0 0x0 0x0 */
++ PUSH_DATA (push, 0xe084000c); /* add f32 $r3 (mul $r0 c0[0x10]) $r3 */
++ PUSH_DATA (push, 0xe0850010); /* add f32 $r4 (mul $r0 c0[0x14]) $r4 */
+ PUSH_DATA (push, 0xe0860015);
+- PUSH_DATA (push, 0x00014780);
++ PUSH_DATA (push, 0x00014780); /* add f32 $r5 (mul $r0 c0[0x18]) $r5 */
+ PUSH_DATA (push, 0xe0870201);
+- PUSH_DATA (push, 0x0000c780);
++ PUSH_DATA (push, 0x0000c780); /* add f32 $r0 (mul $r1 c0[0x1c]) $r3 */
+ PUSH_DATA (push, 0xe0890209);
+- PUSH_DATA (push, 0x00014780);
++ PUSH_DATA (push, 0x00014780); /* add f32 $r2 (mul $r1 c0[0x24]) $r5 */
+ PUSH_DATA (push, 0xe0880205);
+- PUSH_DATA (push, 0x00010781);
++ PUSH_DATA (push, 0x00010781); /* exit add f32 $r1 (mul $r1 c0[0x20]) $r4 */
+
+ /* HPOS.xy = ($o0, $o1), HPOS.zw = (0.0, 1.0), then map $o2 - $o5 */
+ BEGIN_NV04(push, NV50_3D(VP_RESULT_MAP(0)), 2);
+@@ -454,4 +456,3 @@ NVAccelInitNV50TCL(ScrnInfoPtr pScrn)
+
+ return TRUE;
+ }
+-
+diff --git a/src/nv50_accel.h b/src/nv50_accel.h
+index 87c88a3..9b06e38 100644
+--- a/src/nv50_accel.h
++++ b/src/nv50_accel.h
+@@ -8,6 +8,7 @@
+ #include "hwdefs/nv50_texture.h"
+ #include "hwdefs/nv_3ddefs.xml.h"
+ #include "hwdefs/nv_m2mf.xml.h"
++#include "hwdefs/nv_object.xml.h"
+
+ /* subchannel assignments - graphics channel */
+ #define SUBC_M2MF(mthd) 0, (mthd)
+diff --git a/src/nv50_exa.c b/src/nv50_exa.c
+index 7b12985..221160d 100644
+--- a/src/nv50_exa.c
++++ b/src/nv50_exa.c
+@@ -286,9 +286,9 @@ NV50EXACopy(PixmapPtr pdpix, int srcX , int srcY,
+ if (!PUSH_SPACE(push, 32))
+ return;
+
+- BEGIN_NV04(push, SUBC_2D(0x0110), 1);
++ BEGIN_NV04(push, SUBC_2D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_2D(0x088c), 1);
++ BEGIN_NV04(push, NV50_2D(BLIT_CONTROL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NV04(push, NV50_2D(BLIT_DST_X), 12);
+ PUSH_DATA (push, dstX);
+@@ -837,7 +837,7 @@ NV50EXAPrepareComposite(int op,
+ PUSH_RESET(push);
+ PUSH_REFN (push, pNv->scratch, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR);
+
+- BEGIN_NV04(push, SUBC_2D(0x0110), 1);
++ BEGIN_NV04(push, SUBC_2D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (push, 0);
+
+ if (!NV50EXARenderTarget(pdpix, pdpict))
+@@ -875,7 +875,7 @@ NV50EXAPrepareComposite(int op,
+ PUSH_DATA (push, PFP_S);
+ }
+
+- BEGIN_NV04(push, SUBC_3D(0x1334), 1);
++ BEGIN_NV04(push, NV50_3D(TIC_FLUSH), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1);
+diff --git a/src/nv50_xv.c b/src/nv50_xv.c
+index 909074a..b2541b9 100644
+--- a/src/nv50_xv.c
++++ b/src/nv50_xv.c
+@@ -206,7 +206,7 @@ nv50_xv_image_put(ScrnInfoPtr pScrn,
+ BEGIN_NV04(push, NV50_3D(FP_START_ID), 1);
+ PUSH_DATA (push, PFP_NV12);
+
+- BEGIN_NV04(push, SUBC_3D(0x1334), 1);
++ BEGIN_NV04(push, NV50_3D(TIC_FLUSH), 1);
+ PUSH_DATA (push, 0);
+
+ BEGIN_NV04(push, NV50_3D(BIND_TIC(2)), 1);
+@@ -364,6 +364,7 @@ nv50_xv_set_port_defaults(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv)
+ pPriv->saturation = 0;
+ pPriv->hue = 0;
+ pPriv->iturbt_709 = 0;
++ pPriv->max_image_dim = 8192;
+ }
+
+ int
+diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
+index 4484c1c..9361ce8 100644
+--- a/src/nv_accel_common.c
++++ b/src/nv_accel_common.c
+@@ -48,22 +48,15 @@ nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp,
+ if (bpp >= 8)
+ flags |= shared ? NOUVEAU_BO_GART : NOUVEAU_BO_VRAM;
+
++ if (scanout && pNv->tiled_scanout)
++ tiled = TRUE;
++
+ if (pNv->Architecture >= NV_TESLA) {
+- if (scanout) {
+- if (pNv->tiled_scanout) {
+- tiled = TRUE;
+- *pitch = NOUVEAU_ALIGN(width * cpp, 64);
+- } else {
+- *pitch = NOUVEAU_ALIGN(width * cpp, 256);
+- }
+- } else {
+- if (bpp >= 8 && !shared)
+- tiled = TRUE;
+- *pitch = NOUVEAU_ALIGN(width * cpp, shared ? 256 : 64);
+- }
+- } else {
+- if (scanout && pNv->tiled_scanout)
++ if (!scanout && bpp >= 8 && !shared)
+ tiled = TRUE;
++
++ *pitch = NOUVEAU_ALIGN(width * cpp, !tiled ? 256 : 64);
++ } else {
+ *pitch = NOUVEAU_ALIGN(width * cpp, 64);
+ }
+
+@@ -152,13 +145,13 @@ NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
+
+ head = drmmode_head(crtc);
+
+- BEGIN_NV04(push, SUBC_BLIT(0x0000012C), 1);
++ BEGIN_NV04(push, NV15_BLIT(FLIP_INCR_WRITE), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_BLIT(0x00000134), 1);
++ BEGIN_NV04(push, NV15_BLIT(FLIP_CRTC_INCR_READ), 1);
+ PUSH_DATA (push, head);
+ BEGIN_NV04(push, SUBC_BLIT(0x00000100), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NV04(push, SUBC_BLIT(0x00000130), 1);
++ BEGIN_NV04(push, NV15_BLIT(FLIP_WAIT), 1);
+ PUSH_DATA (push, 0);
+ }
+
+diff --git a/src/nv_const.h b/src/nv_const.h
+index f1b4e9b..3f18d23 100644
+--- a/src/nv_const.h
++++ b/src/nv_const.h
+@@ -18,6 +18,7 @@ typedef enum {
+ OPTION_SWAP_LIMIT,
+ OPTION_ASYNC_COPY,
+ OPTION_ACCELMETHOD,
++ OPTION_DRI,
+ } NVOpts;
+
+
+@@ -34,6 +35,7 @@ static const OptionInfoRec NVOptions[] = {
+ { OPTION_SWAP_LIMIT, "SwapLimit", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_ASYNC_COPY, "AsyncUTSDFS", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_ACCELMETHOD, "AccelMethod", OPTV_STRING, {0}, FALSE },
++ { OPTION_DRI, "DRI", OPTV_INTEGER, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+ };
+
+diff --git a/src/nv_driver.c b/src/nv_driver.c
+index 4bad985..4dde8e0 100644
+--- a/src/nv_driver.c
++++ b/src/nv_driver.c
+@@ -21,6 +21,7 @@
+ */
+
+ #include <stdio.h>
++#include <fcntl.h>
+
+ #include "nv_include.h"
+
+@@ -33,7 +34,6 @@
+ #endif
+
+ #include "nouveau_copy.h"
+-#include "nouveau_glamor.h"
+ #include "nouveau_present.h"
+ #include "nouveau_sync.h"
+
+@@ -299,21 +299,21 @@ NVOpenNouveauDevice(struct pci_device *pci_dev,
+ char *busid;
+ int ret, fd = -1;
+
++#ifdef ODEV_ATTRIB_PATH
++ if (platform_dev)
++ busid = NULL;
++ else
++#endif
++ {
+ #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
+- XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
+- pci_dev->domain, pci_dev->bus, pci_dev->dev, pci_dev->func);
++ XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
++ pci_dev->domain, pci_dev->bus,
++ pci_dev->dev, pci_dev->func);
+ #else
+- busid = XNFprintf("pci:%04x:%02x:%02x.%d",
+- pci_dev->domain, pci_dev->bus, pci_dev->dev, pci_dev->func);
++ busid = XNFprintf("pci:%04x:%02x:%02x.%d",
++ pci_dev->domain, pci_dev->bus,
++ pci_dev->dev, pci_dev->func);
+ #endif
+-
+- if (probe) {
+- ret = drmCheckModesettingSupported(busid);
+- if (ret) {
+- xf86DrvMsg(scrnIndex, X_ERROR, "[drm] KMS not enabled\n");
+- free(busid);
+- return NULL;
+- }
+ }
+
+ #if defined(ODEV_ATTRIB_FD)
+@@ -323,6 +323,19 @@ NVOpenNouveauDevice(struct pci_device *pci_dev,
+ #endif
+ if (fd != -1)
+ ret = nouveau_device_wrap(fd, 0, &dev);
++#ifdef ODEV_ATTRIB_PATH
++ else if (platform_dev) {
++ const char *path;
++
++ path = xf86_get_platform_device_attrib(platform_dev,
++ ODEV_ATTRIB_PATH);
++
++ fd = open(path, O_RDWR | O_CLOEXEC);
++ ret = nouveau_device_wrap(fd, 1, &dev);
++ if (ret)
++ close(fd);
++ }
++#endif
+ else
+ ret = nouveau_device_open(busid, &dev);
+ if (ret)
+@@ -376,10 +389,9 @@ NVHasKMS(struct pci_device *pci_dev, struct xf86_platform_device *platform_dev)
+ case 0xe0:
+ case 0xf0:
+ case 0x100:
+- case 0x110:
+ break;
+ default:
+- xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02x\n", chipset);
++ xf86DrvMsg(-1, X_ERROR, "Unknown chipset: NV%02X\n", chipset);
+ return FALSE;
+ }
+ return TRUE;
+@@ -417,9 +429,6 @@ NVPlatformProbe(DriverPtr driver,
+ ScrnInfoPtr scrn = NULL;
+ uint32_t scr_flags = 0;
+
+- if (!dev->pdev)
+- return FALSE;
+-
+ if (!NVHasKMS(dev->pdev, dev))
+ return FALSE;
+
+@@ -546,7 +555,11 @@ redisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
+ PixmapRegionInit(&pixregion, dirty->slave_dst);
+
+ DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
++#ifdef HAS_DIRTYTRACKING_ROTATION
++ PixmapSyncDirtyHelper(dirty);
++#else
+ PixmapSyncDirtyHelper(dirty, &pixregion);
++#endif
+
+ DamageRegionProcessPending(&dirty->slave_dst->drawable);
+ RegionUninit(&pixregion);
+@@ -610,9 +623,6 @@ NVCreateScreenResources(ScreenPtr pScreen)
+ if (pNv->AccelMethod == EXA) {
+ PixmapPtr ppix = pScreen->GetScreenPixmap(pScreen);
+ nouveau_bo_ref(pNv->scanout, &nouveau_pixmap(ppix)->bo);
+- } else
+- if (pNv->AccelMethod == GLAMOR) {
+- nouveau_glamor_create_screen_resources(pScreen);
+ }
+
+ return TRUE;
+@@ -721,6 +731,7 @@ NVCloseDRM(ScrnInfoPtr pScrn)
+ drmFree(pNv->drm_device_name);
+ nouveau_client_del(&pNv->client);
+ nouveau_device_del(&pNv->dev);
++ free(pNv->render_node);
+ }
+
+ static void
+@@ -1033,9 +1044,6 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
+ if (string) {
+ if (!strcmp(string, "none")) pNv->AccelMethod = NONE;
+ else if (!strcmp(string, "exa")) pNv->AccelMethod = EXA;
+-#ifdef HAVE_GLAMOR
+- else if (!strcmp(string, "glamor")) pNv->AccelMethod = GLAMOR;
+-#endif
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Invalid AccelMethod specified\n");
+@@ -1043,12 +1051,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
+ }
+
+ if (pNv->AccelMethod == UNKNOWN) {
+-#ifdef HAVE_GLAMOR
+- if (pNv->Architecture >= NV_MAXWELL)
+- pNv->AccelMethod = GLAMOR;
+- else
+-#endif
+- pNv->AccelMethod = EXA;
++ pNv->AccelMethod = EXA;
+ }
+
+ if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) {
+@@ -1071,14 +1074,27 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
+ pNv->tiled_scanout = TRUE;
+ }
+
+- if (pNv->AccelMethod == GLAMOR) {
+- if (!nouveau_glamor_pre_init(pScrn))
+- pNv->AccelMethod = EXA;
+- }
+-
+ pNv->ce_enabled =
+ xf86ReturnOptValBool(pNv->Options, OPTION_ASYNC_COPY, FALSE);
+
++ /* Define maximum allowed level of DRI implementation to use.
++ * We default to DRI2 on EXA for now, as DRI3 still has some
++ * problems.
++ */
++ pNv->max_dri_level = 2;
++ from = X_DEFAULT;
++
++ if (xf86GetOptValInteger(pNv->Options, OPTION_DRI,
++ &pNv->max_dri_level)) {
++ from = X_CONFIG;
++ if (pNv->max_dri_level < 2)
++ pNv->max_dri_level = 2;
++ if (pNv->max_dri_level > 3)
++ pNv->max_dri_level = 3;
++ }
++ xf86DrvMsg(pScrn->scrnIndex, from, "Allowed maximum DRI level %i.\n",
++ pNv->max_dri_level);
++
+ if (pNv->AccelMethod > NONE && pNv->dev->chipset >= 0x11) {
+ from = X_DEFAULT;
+ pNv->glx_vblank = TRUE;
+@@ -1351,9 +1367,6 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
+ }
+
+ nouveau_copy_init(pScreen);
+- nouveau_sync_init(pScreen);
+- nouveau_dri2_init(pScreen);
+- nouveau_present_init(pScreen);
+
+ /* Allocate and map memory areas we need */
+ if (!NVMapMem(pScrn))
+@@ -1461,11 +1474,20 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
+
+ xf86SetBlackWhitePixels(pScreen);
+
+- if (pNv->AccelMethod == GLAMOR) {
+- if (!nouveau_glamor_init(pScreen))
+- return FALSE;
+- } else
++ if (nouveau_present_init(pScreen))
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Hardware support for Present enabled\n");
++ else
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Hardware support for Present disabled\n");
++
++ nouveau_sync_init(pScreen);
++ nouveau_dri2_init(pScreen);
+ if (pNv->AccelMethod == EXA) {
++ if (pNv->max_dri_level >= 3 &&
++ !nouveau_dri3_screen_init(pScreen))
++ return FALSE;
++
+ if (!nouveau_exa_init(pScreen))
+ return FALSE;
+ }
+diff --git a/src/nv_proto.h b/src/nv_proto.h
+index cc4fd09..122ede5 100644
+--- a/src/nv_proto.h
++++ b/src/nv_proto.h
+@@ -36,6 +36,7 @@ Bool nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height,
+ /* in nouveau_dri2.c */
+ Bool nouveau_dri2_init(ScreenPtr pScreen);
+ void nouveau_dri2_fini(ScreenPtr pScreen);
++Bool nouveau_dri3_screen_init(ScreenPtr pScreen);
+
+ /* in nouveau_xv.c */
+ void NVInitVideo(ScreenPtr);
+diff --git a/src/nv_type.h b/src/nv_type.h
+index c0517c6..d7bb4f4 100644
+--- a/src/nv_type.h
++++ b/src/nv_type.h
+@@ -53,7 +53,6 @@ typedef struct _NVRec {
+ UNKNOWN = 0,
+ NONE,
+ EXA,
+- GLAMOR,
+ } AccelMethod;
+ void (*Flush)(ScrnInfoPtr);
+
+@@ -71,6 +70,7 @@ typedef struct _NVRec {
+ Bool has_pageflip;
+ int swap_limit;
+ int max_swap_limit;
++ int max_dri_level;
+
+ ScreenBlockHandlerProcPtr BlockHandler;
+ CreateScreenResourcesProcPtr CreateScreenResources;
+@@ -140,6 +140,8 @@ typedef struct _NVRec {
+ PixmapPtr pspix, pmpix, pdpix;
+ PicturePtr pspict, pmpict;
+ Pixel fg_colour;
++
++ char *render_node;
+ } NVRec;
+
+ #define NVPTR(p) ((NVPtr)((p)->driverPrivate))
+@@ -163,6 +165,7 @@ typedef struct _NVPortPrivRec {
+ Bool texture;
+ Bool bicubic; /* only for texture adapter */
+ Bool SyncToVBlank;
++ int max_image_dim;
+ struct nouveau_bo *video_mem;
+ int pitch;
+ int offset;
+diff --git a/src/nvc0_accel.c b/src/nvc0_accel.c
+index c04e270..d2a3b93 100644
+--- a/src/nvc0_accel.c
++++ b/src/nvc0_accel.c
+@@ -180,9 +180,9 @@ NVAccelInit2D_NVC0(ScrnInfoPtr pScrn)
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NV50_2D(COLOR_KEY_ENABLE), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NVC0(push, SUBC_2D(0x0884), 1);
++ BEGIN_NVC0(push, NV50_2D(UNK0884), 1);
+ PUSH_DATA (push, 0x3f);
+- BEGIN_NVC0(push, SUBC_2D(0x0888), 1);
++ BEGIN_NVC0(push, NV50_2D(UNK0888), 1);
+ PUSH_DATA (push, 1);
+ BEGIN_NVC0(push, NV50_2D(ROP), 1);
+ PUSH_DATA (push, 0x55);
+@@ -217,8 +217,10 @@ NVAccelInit3D_NVC0(ScrnInfoPtr pScrn)
+ if (pNv->Architecture < NV_KEPLER) {
+ class = 0x9097;
+ handle = 0x001f906e;
+- } else
+- if (pNv->dev->chipset < 0xf0) {
++ } else if (pNv->dev->chipset == 0xea) {
++ class = 0xa297;
++ handle = 0x0000906e;
++ } else if (pNv->dev->chipset < 0xf0) {
+ class = 0xa097;
+ handle = 0x0000906e;
+ } else {
+@@ -323,7 +325,7 @@ NVAccelInit3D_NVC0(ScrnInfoPtr pScrn)
+ BEGIN_NVC0(push, NVC0_3D(MEM_BARRIER), 1);
+ PUSH_DATA (push, 0x1111);
+ } else
+- if (pNv->dev->chipset < 0xf0) {
++ if (pNv->dev->chipset < 0xf0 && pNv->dev->chipset != 0xea) {
+ NVC0PushProgram(pNv, PVP_PASS, NVE0VP_Transform2);
+ NVC0PushProgram(pNv, PFP_S, NVE0FP_Source);
+ NVC0PushProgram(pNv, PFP_C, NVE0FP_Composite);
+diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
+index 1f33353..7aa98cf 100644
+--- a/src/nvc0_exa.c
++++ b/src/nvc0_exa.c
+@@ -290,7 +290,7 @@ NVC0EXACopy(PixmapPtr pdpix, int srcX , int srcY,
+
+ BEGIN_NVC0(push, SUBC_2D(NV50_GRAPH_SERIALIZE), 1);
+ PUSH_DATA (push, 0);
+- BEGIN_NVC0(push, SUBC_2D(0x088c), 1);
++ BEGIN_NVC0(push, NV50_2D(BLIT_CONTROL), 1);
+ PUSH_DATA (push, 0);
+ BEGIN_NVC0(push, NV50_2D(BLIT_DST_X), 12);
+ PUSH_DATA (push, dstX);
+diff --git a/src/shader/Makefile b/src/shader/Makefile
+index 46658e9..2d789be 100644
+--- a/src/shader/Makefile
++++ b/src/shader/Makefile
+@@ -24,20 +24,21 @@ NVF0_SHADERS = xfrm2nvf0.vpc \
+ videonvf0.fpc
+
+ SHADERS = $(NVC0_SHADERS) $(NVE0_SHADERS) $(NVF0_SHADERS)
++ENVYAS ?= envyas
+
+ all: $(SHADERS)
+
+ $(filter %nvc0.vpc,$(SHADERS)): %.vpc: %.vp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m nvc0 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m nvc0 -o $@
+ $(filter %nvc0.fpc,$(SHADERS)): %.fpc: %.fp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m nvc0 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m nvc0 -o $@
+
+ $(filter %nve0.vpc,$(SHADERS)): %.vpc: %.vp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m nvc0 -V nve4 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m nvc0 -V nve4 -o $@
+ $(filter %nve0.fpc,$(SHADERS)): %.fpc: %.fp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m nvc0 -V nve4 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m nvc0 -V nve4 -o $@
+
+ $(filter %nvf0.vpc,$(SHADERS)): %.vpc: %.vp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m gk110 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m gk110 -o $@
+ $(filter %nvf0.fpc,$(SHADERS)): %.fpc: %.fp
+- cpp -DENVYAS $< | sed -e '/^#/d' | envyas -w -m gk110 -o $@
++ cpp -DENVYAS $< | sed -e '/^#/d' | $(ENVYAS) -w -m gk110 -o $@
+diff --git a/src/shader/exac8nvf0.fp b/src/shader/exac8nvf0.fp
+index e4a7b04..f1c7fed 100644
+--- a/src/shader/exac8nvf0.fp
++++ b/src/shader/exac8nvf0.fp
+@@ -29,10 +29,10 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x94] $r0 0x0 0x0
+ interp mul f32 $r2 a[0x90] $r0 0x0 0x0
+-tex t lauto #:#:#:$r1 t2d c[0x4] xy__ $r2:$r3 0x0
++tex t lauto live dfp #:#:#:$r1 t2d c[0x4] xy__ $r2:$r3 0x0
+ interp mul f32 $r3 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r2 a[0x80] $r0 0x0 0x0
+-tex t lauto #:#:#:$r0 t2d c[0x0] xy__ $r2:$r3 0x0
++tex t lauto live dfp #:#:#:$r0 t2d c[0x0] xy__ $r2:$r3 0x0
+ texbar 0x0
+ mul ftz rn f32 $r3 $r0 $r1
+ mov b32 $r2 $r3
+diff --git a/src/shader/exac8nvf0.fpc b/src/shader/exac8nvf0.fpc
+index 465cabf..7cfecb5 100644
+--- a/src/shader/exac8nvf0.fpc
++++ b/src/shader/exac8nvf0.fpc
+@@ -6,13 +6,13 @@
+ 0x74a3fc4a,
+ 0x001ffc0a,
+ 0x74a3fc48,
+-0x7f9c0805,
++0xff9c0805,
+ 0x600080a1,
+ 0x001ffc0e,
+ 0x74a3fc42,
+ 0x001ffc0a,
+ 0x74a3fc40,
+-0x7f9c0801,
++0xff9c0801,
+ 0x600000a1,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/exacanve0.fp b/src/shader/exacanve0.fp
+index edeb717..3928b6d 100644
+--- a/src/shader/exacanve0.fp
++++ b/src/shader/exacanve0.fp
+@@ -30,7 +30,6 @@ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x94] $r0 0x0
+ interp mul f32 $r2 a[0x90] $r0 0x0
+ tex t lauto live dfp $r4:$r5:$r6:$r7 t2d $t1 $s0 $r2:$r3 ()
+-texbar 0x0
+ interp mul f32 $r1 a[0x84] $r0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0
+ tex t lauto live dfp $r0:$r1:$r2:$r3 t2d $t0 $s0 $r0:$r1 ()
+diff --git a/src/shader/exacanve0.fpc b/src/shader/exacanve0.fpc
+index a8320f0..fa96dae 100644
+--- a/src/shader/exacanve0.fpc
++++ b/src/shader/exacanve0.fpc
+@@ -8,8 +8,6 @@
+ 0xc07e0090,
+ 0x00211e86,
+ 0x8013c001,
+-0x00001de6,
+-0xf0000000,
+ 0x03f05c40,
+ 0xc07e0084,
+ 0x03f01c40,
+diff --git a/src/shader/exacanvf0.fp b/src/shader/exacanvf0.fp
+index 338a1e1..dddc22e 100644
+--- a/src/shader/exacanvf0.fp
++++ b/src/shader/exacanvf0.fp
+@@ -29,11 +29,10 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x94] $r0 0x0 0x0
+ interp mul f32 $r2 a[0x90] $r0 0x0 0x0
+-tex t lauto $r4:$r5:$r6:$r7 t2d c[0x4] xy__ $r2:$r3 0x0
+-texbar 0x0
++tex t lauto live dfp $r4:$r5:$r6:$r7 t2d c[0x4] xy__ $r2:$r3 0x0
+ interp mul f32 $r1 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0 0x0
+-tex t lauto $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
++tex t lauto live dfp $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
+ texbar 0x0
+ mul ftz rn f32 $r3 $r3 $r7
+ mul ftz rn f32 $r2 $r2 $r6
+diff --git a/src/shader/exacanvf0.fpc b/src/shader/exacanvf0.fpc
+index 70dd4b1..793f15c 100644
+--- a/src/shader/exacanvf0.fpc
++++ b/src/shader/exacanvf0.fpc
+@@ -6,15 +6,13 @@
+ 0x74a3fc4a,
+ 0x001ffc0a,
+ 0x74a3fc48,
+-0x7f9c0811,
++0xff9c0811,
+ 0x600080bd,
+-0x001c0002,
+-0x77000000,
+ 0x001ffc06,
+ 0x74a3fc42,
+ 0x001ffc02,
+ 0x74a3fc40,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600000bd,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/exacmnve0.fp b/src/shader/exacmnve0.fp
+index 09d22c1..71895f4 100644
+--- a/src/shader/exacmnve0.fp
++++ b/src/shader/exacmnve0.fp
+@@ -30,7 +30,6 @@ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x94] $r0 0x0
+ interp mul f32 $r2 a[0x90] $r0 0x0
+ tex t lauto live dfp #:#:#:$r4 t2d $t1 $s0 $r2:$r3 ()
+-texbar 0x0
+ interp mul f32 $r1 a[0x84] $r0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0
+ tex t lauto live dfp $r0:$r1:$r2:$r3 t2d $t0 $s0 $r0:$r1 ()
+diff --git a/src/shader/exacmnve0.fpc b/src/shader/exacmnve0.fpc
+index 5c2d4bf..2c256b1 100644
+--- a/src/shader/exacmnve0.fpc
++++ b/src/shader/exacmnve0.fpc
+@@ -8,8 +8,6 @@
+ 0xc07e0090,
+ 0x00211e86,
+ 0x80120001,
+-0x00001de6,
+-0xf0000000,
+ 0x03f05c40,
+ 0xc07e0084,
+ 0x03f01c40,
+diff --git a/src/shader/exacmnvf0.fp b/src/shader/exacmnvf0.fp
+index 787b4f5..e52b7bd 100644
+--- a/src/shader/exacmnvf0.fp
++++ b/src/shader/exacmnvf0.fp
+@@ -29,11 +29,10 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x94] $r0 0x0 0x0
+ interp mul f32 $r2 a[0x90] $r0 0x0 0x0
+-tex t lauto #:#:#:$r4 t2d c[0x4] xy__ $r2:$r3 0x0
+-texbar 0x0
++tex t lauto live dfp #:#:#:$r4 t2d c[0x4] xy__ $r2:$r3 0x0
+ interp mul f32 $r1 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0 0x0
+-tex t lauto $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
++tex t lauto live dfp $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
+ texbar 0x0
+ mul ftz rn f32 $r3 $r3 $r4
+ mul ftz rn f32 $r2 $r2 $r4
+diff --git a/src/shader/exacmnvf0.fpc b/src/shader/exacmnvf0.fpc
+index b2acf6f..4ec8a33 100644
+--- a/src/shader/exacmnvf0.fpc
++++ b/src/shader/exacmnvf0.fpc
+@@ -6,15 +6,13 @@
+ 0x74a3fc4a,
+ 0x001ffc0a,
+ 0x74a3fc48,
+-0x7f9c0811,
++0xff9c0811,
+ 0x600080a1,
+-0x001c0002,
+-0x77000000,
+ 0x001ffc06,
+ 0x74a3fc42,
+ 0x001ffc02,
+ 0x74a3fc40,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600000bd,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/exas8nvf0.fp b/src/shader/exas8nvf0.fp
+index 3804b27..245262c 100644
+--- a/src/shader/exas8nvf0.fp
++++ b/src/shader/exas8nvf0.fp
+@@ -29,7 +29,7 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r1 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0 0x0
+-tex t lauto #:#:#:$r0 t2d c[0x0] xy__ $r0:$r1 0x0
++tex t lauto live dfp #:#:#:$r0 t2d c[0x0] xy__ $r0:$r1 0x0
+ texbar 0x0
+ mov b32 $r3 $r0
+ mov b32 $r2 $r0
+diff --git a/src/shader/exas8nvf0.fpc b/src/shader/exas8nvf0.fpc
+index 4ec3bb7..a59ffe6 100644
+--- a/src/shader/exas8nvf0.fpc
++++ b/src/shader/exas8nvf0.fpc
+@@ -6,7 +6,7 @@
+ 0x74a3fc42,
+ 0x001ffc02,
+ 0x74a3fc40,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600000a1,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/exasanve0.fp b/src/shader/exasanve0.fp
+index dea8eab..8ddcc4a 100644
+--- a/src/shader/exasanve0.fp
++++ b/src/shader/exasanve0.fp
+@@ -30,7 +30,6 @@ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x84] $r0 0x0
+ interp mul f32 $r2 a[0x80] $r0 0x0
+ tex t lauto live dfp #:#:#:$r4 t2d $t0 $s0 $r2:$r3 ()
+-texbar 0x0
+ interp mul f32 $r1 a[0x94] $r0 0x0
+ interp mul f32 $r0 a[0x90] $r0 0x0
+ tex t lauto live dfp $r0:$r1:$r2:$r3 t2d $t1 $s0 $r0:$r1 ()
+diff --git a/src/shader/exasanve0.fpc b/src/shader/exasanve0.fpc
+index efc701e..170c5df 100644
+--- a/src/shader/exasanve0.fpc
++++ b/src/shader/exasanve0.fpc
+@@ -8,8 +8,6 @@
+ 0xc07e0080,
+ 0x00211e86,
+ 0x80120000,
+-0x00001de6,
+-0xf0000000,
+ 0x03f05c40,
+ 0xc07e0094,
+ 0x03f01c40,
+diff --git a/src/shader/exasanvf0.fp b/src/shader/exasanvf0.fp
+index 8175f9b..c5c60a3 100644
+--- a/src/shader/exasanvf0.fp
++++ b/src/shader/exasanvf0.fp
+@@ -29,11 +29,10 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r3 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r2 a[0x80] $r0 0x0 0x0
+-tex t lauto #:#:#:$r4 t2d c[0x0] xy__ $r2:$r3 0x0
+-texbar 0x0
++tex t lauto live dfp #:#:#:$r4 t2d c[0x0] xy__ $r2:$r3 0x0
+ interp mul f32 $r1 a[0x94] $r0 0x0 0x0
+ interp mul f32 $r0 a[0x90] $r0 0x0 0x0
+-tex t lauto $r0:$r1:$r2:$r3 t2d c[0x4] xy__ $r0:$r1 0x0
++tex t lauto live dfp $r0:$r1:$r2:$r3 t2d c[0x4] xy__ $r0:$r1 0x0
+ texbar 0x0
+ mul ftz rn f32 $r3 $r3 $r4
+ mul ftz rn f32 $r2 $r2 $r4
+diff --git a/src/shader/exasanvf0.fpc b/src/shader/exasanvf0.fpc
+index 6e68d98..afddc84 100644
+--- a/src/shader/exasanvf0.fpc
++++ b/src/shader/exasanvf0.fpc
+@@ -6,15 +6,13 @@
+ 0x74a3fc42,
+ 0x001ffc0a,
+ 0x74a3fc40,
+-0x7f9c0811,
++0xff9c0811,
+ 0x600000a1,
+-0x001c0002,
+-0x77000000,
+ 0x001ffc06,
+ 0x74a3fc4a,
+ 0x001ffc02,
+ 0x74a3fc48,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600080bd,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/exascnvf0.fp b/src/shader/exascnvf0.fp
+index e56c27f..447c67d 100644
+--- a/src/shader/exascnvf0.fp
++++ b/src/shader/exascnvf0.fp
+@@ -29,7 +29,7 @@ interp pass f32 $r0 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r0 $r0
+ interp mul f32 $r1 a[0x84] $r0 0x0 0x0
+ interp mul f32 $r0 a[0x80] $r0 0x0 0x0
+-tex t lauto $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
++tex t lauto live dfp $r0:$r1:$r2:$r3 t2d c[0x0] xy__ $r0:$r1 0x0
+ texbar 0x0
+ exit
+ #endif
+diff --git a/src/shader/exascnvf0.fpc b/src/shader/exascnvf0.fpc
+index 53af859..5d2dce6 100644
+--- a/src/shader/exascnvf0.fpc
++++ b/src/shader/exascnvf0.fpc
+@@ -6,7 +6,7 @@
+ 0x74a3fc42,
+ 0x001ffc02,
+ 0x74a3fc40,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600000bd,
+ 0x001c0002,
+ 0x77000000,
+diff --git a/src/shader/videonvf0.fp b/src/shader/videonvf0.fp
+index a684203..3612dcd 100644
+--- a/src/shader/videonvf0.fp
++++ b/src/shader/videonvf0.fp
+@@ -29,8 +29,8 @@ interp pass f32 $r2 a[0x7c] 0x0 0x0 0x0
+ rcp f32 $r2 $r2
+ interp mul f32 $r0 a[0x80] $r2 0x0 0x0
+ interp mul f32 $r1 a[0x84] $r2 0x0 0x0
+-tex t lauto #:#:#:$r4 t2d c[0x0] xy__ $r0:$r1 0x0
+-tex p lauto #:#:$r0:$r1 t2d c[0x4] xy__ $r0:$r1 0x0
++tex t lauto live dfp #:#:#:$r4 t2d c[0x0] xy__ $r0:$r1 0x0
++tex p lauto live dfp #:#:$r0:$r1 t2d c[0x4] xy__ $r0:$r1 0x0
+ texbar 0x1
+ mul ftz rn f32 $r5 $r4 c0[0x0]
+ add ftz rn f32 $r3 $r5 c0[0x4]
+diff --git a/src/shader/videonvf0.fpc b/src/shader/videonvf0.fpc
+index c545967..a7e5e98 100644
+--- a/src/shader/videonvf0.fpc
++++ b/src/shader/videonvf0.fpc
+@@ -6,9 +6,9 @@
+ 0x74a3fc40,
+ 0x011ffc06,
+ 0x74a3fc42,
+-0x7f9c0011,
++0xff9c0011,
+ 0x600000a1,
+-0x7f9c0001,
++0xff9c0001,
+ 0x600080b2,
+ 0x009c0002,
+ 0x77000000,