src/compat-api.h      |   55 ++++++++++++++++++++++++++++++++++++++
 src/drmmode_display.c |    2 -
 src/nouveau_exa.c     |    9 ++++++
 src/nv04_exa.c        |   15 +++++-----
 src/nv50_accel.c      |   23 ++++++++++++++++
 src/nv50_accel.h      |    5 ++-
 src/nv50_exa.c        |   59 +++++++++++++++++++++++++++++++++++++++++
 src/nv_accel_common.c |    4 ++
 src/nv_const.h        |    2 +
 src/nv_dma.c          |   38 ++++++++++++++++++++++++++
 src/nv_driver.c       |   71 +++++++++++++++++++++++---------------------------
 src/nv_proto.h        |   10 ++++++-
 src/nv_type.h         |    6 ++++
 src/nvc0_accel.c      |   21 ++++++++++++++
 src/nvc0_exa.c        |   59 +++++++++++++++++++++++++++++++++++++++++
 15 files changed, 331 insertions(+), 48 deletions(-)

New commits:
commit 4dbc132f22721e3da30eb2e7fc97dea5b8458df6
Author: Viktor Novotný <novik...@seznam.cz>
Date:   Sat May 26 22:15:20 2012 +0200

    nv04/exa: Reset destination surface offset in the same call of NV04EXACopy
    
    Fixes FDO bug #48954.
    
    Signed-off-by: Viktor Novotný <novik...@seznam.cz>
    Reviewed-by: Marcin Slusarz <marcin.slus...@gmail.com>
    Signed-off-by: Ben Skeggs <bske...@redhat.com>

diff --git a/src/nv04_exa.c b/src/nv04_exa.c
index 7ede9d9..ca92868 100644
--- a/src/nv04_exa.c
+++ b/src/nv04_exa.c
@@ -220,7 +220,7 @@ NV04EXACopy(PixmapPtr pdpix, int srcX, int srcY, int dstX, 
int dstY,
        int split_dstY = NOUVEAU_ALIGN(dstY + 1, 64);
        int split_height = split_dstY - dstY;
 
-       if (nouveau_pushbuf_space(push, 16, 1, 0))
+       if (nouveau_pushbuf_space(push, 16, 2, 0))
                return;
 
        if ((width * height) >= 200000 && pNv->pspix != pNv->pdpix &&
@@ -249,7 +249,13 @@ NV04EXACopy(PixmapPtr pdpix, int srcX, int srcY, int dstX, 
int dstY,
                height -= split_height;
                dstY = 0;
                pNv->pmpix = pdpix;
-       } else
+       }
+
+       BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3);
+       PUSH_DATA (push, (srcY << 16) | srcX);
+       PUSH_DATA (push, (dstY << 16) | dstX);
+       PUSH_DATA (push, (height  << 16) | width);
+
        if (pNv->pmpix) {
                struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix);
 
@@ -258,11 +264,6 @@ NV04EXACopy(PixmapPtr pdpix, int srcX, int srcY, int dstX, 
int dstY,
                pNv->pmpix = NULL;
        }
 
-       BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3);
-       PUSH_DATA (push, (srcY << 16) | srcX);
-       PUSH_DATA (push, (dstY << 16) | dstX);
-       PUSH_DATA (push, (height  << 16) | width);
-
        if ((width * height) >= 512)
                PUSH_KICK(push);
 }

commit aab58ee9a8025422416458d637c203af5ba008fd
Author: Dave Airlie <airl...@redhat.com>
Date:   Tue Jun 5 12:34:06 2012 +0100

    nouveau: i is used inside the function
    
    fixes build, reported by tallica on irc.
    
    Signed-off-by: Dave Airlie <airl...@redhat.com>

diff --git a/src/compat-api.h b/src/compat-api.h
index d0f8c1d..b1591b1 100644
--- a/src/compat-api.h
+++ b/src/compat-api.h
@@ -46,7 +46,7 @@
 #define SCREEN_ARG_TYPE int
 #define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)]
 
-#define SCREEN_INIT_ARGS_DECL int i, ScreenPtr pScreen, int argc, char **argv
+#define SCREEN_INIT_ARGS_DECL int index, ScreenPtr pScreen, int argc, char 
**argv
 
 #define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, 
pointer pReadmask
 #define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask

commit 619e99731f772ff8d9d93cd1d6d83de5d450574b
Author: Dave Airlie <airl...@redhat.com>
Date:   Tue Jun 5 11:02:54 2012 +0100

    nouveau: port to compat server API.
    
    This ports to the new server API.
    
    Signed-off-by: Dave Airlie <airl...@redhat.com>

diff --git a/src/compat-api.h b/src/compat-api.h
index 1bb7724..d0f8c1d 100644
--- a/src/compat-api.h
+++ b/src/compat-api.h
@@ -38,4 +38,59 @@
 #define xf86ScrnToScreen(s) screenInfo.screens[(s)->scrnIndex]
 #endif
 
+#ifndef XF86_SCRN_INTERFACE
+
+#define SCRN_ARG_TYPE int
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = xf86Screens[(arg1)]
+
+#define SCREEN_ARG_TYPE int
+#define SCREEN_PTR(arg1) ScreenPtr pScreen = screenInfo.screens[(arg1)]
+
+#define SCREEN_INIT_ARGS_DECL int i, ScreenPtr pScreen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL int arg, pointer blockData, pointer pTimeout, 
pointer pReadmask
+#define BLOCKHANDLER_ARGS arg, blockData, pTimeout, pReadmask
+
+#define CLOSE_SCREEN_ARGS_DECL int scrnIndex, ScreenPtr pScreen
+#define CLOSE_SCREEN_ARGS scrnIndex, pScreen
+
+#define ADJUST_FRAME_ARGS_DECL int arg, int x, int y, int flags
+
+#define SWITCH_MODE_ARGS_DECL int arg, DisplayModePtr mode, int flags
+
+#define FREE_SCREEN_ARGS_DECL int arg, int flags
+#define FREE_SCREEN_ARGS(x) (x)->scrnIndex, 0
+
+#define VT_FUNC_ARGS_DECL int arg, int flags
+#define VT_FUNC_ARGS(flags) pScrn->scrnIndex, (flags)
+
+#define XF86_ENABLEDISABLEFB_ARG(x) ((x)->scrnIndex)
+#else
+#define SCRN_ARG_TYPE ScrnInfoPtr
+#define SCRN_INFO_PTR(arg1) ScrnInfoPtr pScrn = (arg1)
+
+#define SCREEN_ARG_TYPE ScreenPtr
+#define SCREEN_PTR(arg1) ScreenPtr pScreen = (arg1)
+
+#define SCREEN_INIT_ARGS_DECL ScreenPtr pScreen, int argc, char **argv
+
+#define BLOCKHANDLER_ARGS_DECL ScreenPtr arg, pointer pTimeout, pointer 
pReadmask
+#define BLOCKHANDLER_ARGS arg, pTimeout, pReadmask
+
+#define CLOSE_SCREEN_ARGS_DECL ScreenPtr pScreen
+#define CLOSE_SCREEN_ARGS pScreen
+
+#define ADJUST_FRAME_ARGS_DECL ScrnInfoPtr arg, int x, int y
+#define SWITCH_MODE_ARGS_DECL ScrnInfoPtr arg, DisplayModePtr mode
+
+#define FREE_SCREEN_ARGS_DECL ScrnInfoPtr arg
+#define FREE_SCREEN_ARGS(x) (x)
+
+#define VT_FUNC_ARGS_DECL ScrnInfoPtr arg
+#define VT_FUNC_ARGS(flags) pScrn
+
+#define XF86_ENABLEDISABLEFB_ARG(x) (x)
+
+#endif
+
 #endif
diff --git a/src/nv_driver.c b/src/nv_driver.c
index cdfb25e..9a7b9c2 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -40,18 +40,17 @@
 static const OptionInfoRec * NVAvailableOptions(int chipid, int busid);
 static void    NVIdentify(int flags);
 static Bool    NVPreInit(ScrnInfoPtr pScrn, int flags);
-static Bool    NVScreenInit(int Index, ScreenPtr pScreen, int argc,
-                            char **argv);
-static Bool    NVEnterVT(int scrnIndex, int flags);
-static void    NVLeaveVT(int scrnIndex, int flags);
-static Bool    NVCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool    NVScreenInit(SCREEN_INIT_ARGS_DECL);
+static Bool    NVEnterVT(VT_FUNC_ARGS_DECL);
+static void    NVLeaveVT(VT_FUNC_ARGS_DECL);
+static Bool    NVCloseScreen(CLOSE_SCREEN_ARGS_DECL);
 static Bool    NVSaveScreen(ScreenPtr pScreen, int mode);
 static void    NVCloseDRM(ScrnInfoPtr);
 
 /* Optional functions */
-static Bool    NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static void    NVAdjustFrame(int scrnIndex, int x, int y, int flags);
-static void    NVFreeScreen(int scrnIndex, int flags);
+static Bool    NVSwitchMode(SWITCH_MODE_ARGS_DECL);
+static void    NVAdjustFrame(ADJUST_FRAME_ARGS_DECL);
+static void    NVFreeScreen(FREE_SCREEN_ARGS_DECL);
 
 /* Internally used functions */
 
@@ -300,9 +299,9 @@ NVPciProbe(DriverPtr drv, int entity_num, struct pci_device 
*pci_dev,
 #define MAX_CHIPS MAXSCREENS
 
 Bool
-NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+NVSwitchMode(SWITCH_MODE_ARGS_DECL)
 {
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       SCRN_INFO_PTR(arg);
 
        return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
 }
@@ -313,10 +312,9 @@ NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
  */
 /* Usually mandatory */
 void 
-NVAdjustFrame(int scrnIndex, int x, int y, int flags)
+NVAdjustFrame(ADJUST_FRAME_ARGS_DECL)
 {
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
+       SCRN_INFO_PTR(arg);
        drmmode_adjust_frame(pScrn, x, y);
 }
 
@@ -327,9 +325,9 @@ NVAdjustFrame(int scrnIndex, int x, int y, int flags)
 
 /* Mandatory */
 static Bool
-NVEnterVT(int scrnIndex, int flags)
+NVEnterVT(VT_FUNC_ARGS_DECL)
 {
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       SCRN_INFO_PTR(arg);
        NVPtr pNv = NVPTR(pScrn);
        int ret;
 
@@ -355,9 +353,9 @@ NVEnterVT(int scrnIndex, int flags)
 
 /* Mandatory */
 static void
-NVLeaveVT(int scrnIndex, int flags)
+NVLeaveVT(VT_FUNC_ARGS_DECL)
 {
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       SCRN_INFO_PTR(arg);
        NVPtr pNv = NVPTR(pScrn);
        int ret;
 
@@ -379,19 +377,14 @@ NVFlushCallback(CallbackListPtr *list, pointer user_data, 
pointer call_data)
 }
 
 static void 
-NVBlockHandler (
-       int i, 
-       pointer blockData, 
-       pointer pTimeout,
-       pointer pReadmask
-)
+NVBlockHandler (BLOCKHANDLER_ARGS_DECL)
 {
-       ScreenPtr pScreen = screenInfo.screens[i];
-       ScrnInfoPtr pScrn = xf86Screens[i];
+       SCREEN_PTR(arg);
+       ScrnInfoPtr pScrn   = xf86ScreenToScrn(pScreen);
        NVPtr pNv = NVPTR(pScrn);
 
        pScreen->BlockHandler = pNv->BlockHandler;
-       (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+       (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
        pScreen->BlockHandler = NVBlockHandler;
 
        if (pScrn->vtSema && !pNv->NoAccel)
@@ -414,7 +407,7 @@ NVCreateScreenResources(ScreenPtr pScreen)
        pScreen->CreateScreenResources = NVCreateScreenResources;
 
        drmmode_fbcon_copy(pScreen);
-       if (!NVEnterVT(pScrn->scrnIndex, 0))
+       if (!NVEnterVT(VT_FUNC_ARGS(0)))
                return FALSE;
 
        if (!pNv->NoAccel) {
@@ -434,9 +427,9 @@ NVCreateScreenResources(ScreenPtr pScreen)
 
 /* Mandatory */
 static Bool
-NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
+NVCloseScreen(CLOSE_SCREEN_ARGS_DECL)
 {
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
        NVPtr pNv = NVPTR(pScrn);
 
        drmmode_screen_fini(pScreen);
@@ -445,7 +438,7 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
                nouveau_dri2_fini(pScreen);
 
        if (pScrn->vtSema) {
-               NVLeaveVT(scrnIndex, 0);
+               NVLeaveVT(VT_FUNC_ARGS(0));
                pScrn->vtSema = FALSE;
        }
 
@@ -487,21 +480,20 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen)
        pScrn->vtSema = FALSE;
        pScreen->CloseScreen = pNv->CloseScreen;
        pScreen->BlockHandler = pNv->BlockHandler;
-       return (*pScreen->CloseScreen)(scrnIndex, pScreen);
+       return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
 }
 
 /* Free up any persistent data structures */
 
 /* Optional */
 static void
-NVFreeScreen(int scrnIndex, int flags)
+NVFreeScreen(FREE_SCREEN_ARGS_DECL)
 {
        /*
         * This only gets called when a screen is being deleted.  It does not
         * get called routinely at the end of a server generation.
         */
-
-       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       SCRN_INFO_PTR(arg);
        NVPtr pNv = NVPTR(pScrn);
 
        if (!pNv)
@@ -515,7 +507,7 @@ NVFreeScreen(int scrnIndex, int flags)
 
 #define NVPreInitFail(fmt, args...) do {                                    \
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \
-       NVFreeScreen(pScrn->scrnIndex, 0);                                  \
+       NVFreeScreen(FREE_SCREEN_ARGS(pScrn));                  \
        return FALSE;                                                       \
 } while(0)
 
@@ -1062,7 +1054,7 @@ NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int 
*indices,
 
 /* This gets called at the start of each server generation */
 static Bool
-NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+NVScreenInit(SCREEN_INIT_ARGS_DECL)
 {
        ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
        NVPtr pNv = NVPTR(pScrn);
@@ -1166,7 +1158,7 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 
char **argv)
        }
                break;
        default:
-               xf86DrvMsg(scrnIndex, X_ERROR,
+               xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
                           "Internal error: invalid bpp (%d) in NVScreenInit\n",
                           pScrn->bitsPerPixel);
                ret = FALSE;

commit d2e16c62b5054f34a439e504bfa261fb71f5d7de
Author: Dave Airlie <airl...@redhat.com>
Date:   Tue Jun 5 10:57:30 2012 +0100

    nouveau: drop flags arg to adjust frame
    
    Signed-off-by: Dave Airlie <airl...@redhat.com>

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7211427..62838fa 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1205,7 +1205,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
 }
 
 void
-drmmode_adjust_frame(ScrnInfoPtr scrn, int x, int y, int flags)
+drmmode_adjust_frame(ScrnInfoPtr scrn, int x, int y)
 {
        xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
        xf86OutputPtr output = config->output[config->compat_output];
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 4f9c6cb..cdfb25e 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -317,7 +317,7 @@ NVAdjustFrame(int scrnIndex, int x, int y, int flags)
 {
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
-       drmmode_adjust_frame(pScrn, x, y, flags);
+       drmmode_adjust_frame(pScrn, x, y);
 }
 
 /*
diff --git a/src/nv_proto.h b/src/nv_proto.h
index d89e47f..b546ebd 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -3,7 +3,7 @@
 
 /* in drmmode_display.c */
 Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp);
-void drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y, int flags);
+void drmmode_adjust_frame(ScrnInfoPtr pScrn, int x, int y);
 void drmmode_remove_fb(ScrnInfoPtr pScrn);
 Bool drmmode_cursor_init(ScreenPtr pScreen);
 void drmmode_fbcon_copy(ScreenPtr pScreen);

commit fadf83d7b373282ccbf0fa0c01928a35ff717a5e
Author: Ben Skeggs <bske...@redhat.com>
Date:   Thu May 31 15:46:57 2012 +1000

    nvc0/exa: add support for async UTS/DFS copies
    
    Signed-off-by: Ben Skeggs <bske...@redhat.com>

diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index abf1ff8..fb27b1e 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -52,6 +52,10 @@ NVAccelM2MF(NVPtr pNv, int w, int h, int cpp, uint32_t 
srcoff, uint32_t dstoff,
                                       src, srcoff, sd, sp, sh, sx, sy,
                                       dst, dstoff, dd, dp, dh, dx, dy);
        else
+       if (pNv->Architecture >= NV_ARCH_C0 && pNv->NvCopy)
+               return NVC0EXARectCopy(pNv, w, h, cpp,
+                                      src, srcoff, sd, sp, sh, sx, sy,
+                                      dst, dstoff, dd, dp, dh, dx, dy);
        if (pNv->Architecture >= NV_ARCH_C0)
                return NVC0EXARectM2MF(pNv, w, h, cpp,
                                       src, srcoff, sd, sp, sh, sx, sy,
diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
index 30f8beb..57e52ff 100644
--- a/src/nv_accel_common.c
+++ b/src/nv_accel_common.c
@@ -628,6 +628,8 @@ NVAccelCommonInit(ScrnInfoPtr pScrn)
                        INIT_CONTEXT_OBJECT(Copy_NV50);
        } else {
                INIT_CONTEXT_OBJECT(2D_NVC0);
+               if (pNv->ce_enabled)
+                       INIT_CONTEXT_OBJECT(Copy_NVC0);
        }
 
        if (pNv->Architecture < NV_ARCH_50)
diff --git a/src/nv_proto.h b/src/nv_proto.h
index f7e05c6..d89e47f 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -150,6 +150,7 @@ Bool NVAccelInitNV50TCL(ScrnInfoPtr pScrn);
 
 /* in nvc0_accel.c */
 Bool NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn);
+Bool NVAccelInitCopy_NVC0(ScrnInfoPtr pScrn);
 Bool NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn);
 Bool NVAccelInit2D_NVC0(ScrnInfoPtr pScrn);
 Bool NVAccelInit3D_NVC0(ScrnInfoPtr pScrn);
@@ -197,6 +198,9 @@ Bool NVC0EXAUploadSIFC(const char *src, int src_pitch,
 Bool NVC0EXARectM2MF(NVPtr pNv, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int);
+Bool NVC0EXARectCopy(NVPtr pNv, int, int, int,
+                    struct nouveau_bo *, uint32_t, int, int, int, int, int,
+                    struct nouveau_bo *, uint32_t, int, int, int, int, int);
 Bool NVE0EXARectCopy(NVPtr pNv, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int);
diff --git a/src/nvc0_accel.c b/src/nvc0_accel.c
index 1fd2286..c5da0cd 100644
--- a/src/nvc0_accel.c
+++ b/src/nvc0_accel.c
@@ -48,6 +48,27 @@ NVAccelInitM2MF_NVC0(ScrnInfoPtr pScrn)
 }
 
 Bool
+NVAccelInitCopy_NVC0(ScrnInfoPtr pScrn)
+{
+       NVPtr pNv = NVPTR(pScrn);
+       struct nouveau_pushbuf *push = pNv->ce_pushbuf;
+       int ret;
+
+       ret = nouveau_object_new(pNv->ce_channel, 0x000490b5, 0x90b5,
+                                NULL, 0, &pNv->NvCopy);
+       if (ret)
+               return FALSE;
+
+       if (!PUSH_SPACE(push, 2))
+               return FALSE;
+
+       BEGIN_NVC0(push, NV01_SUBC(COPY, OBJECT), 1);
+       PUSH_DATA (push, pNv->NvCopy->handle);
+
+       return TRUE;
+}
+
+Bool
 NVAccelInitP2MF_NVE0(ScrnInfoPtr pScrn)
 {
        NVPtr pNv = NVPTR(pScrn);
diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
index 9d23a91..6a8f1a1 100644
--- a/src/nvc0_exa.c
+++ b/src/nvc0_exa.c
@@ -1017,6 +1017,65 @@ NVC0EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
 }
 
 Bool
+NVC0EXARectCopy(NVPtr pNv, int w, int h, int cpp,
+               struct nouveau_bo *src, uint32_t src_off, int src_dom,
+               int src_pitch, int src_h, int src_x, int src_y,
+               struct nouveau_bo *dst, uint32_t dst_off, int dst_dom,
+               int dst_pitch, int dst_h, int dst_x, int dst_y)
+{
+       struct nouveau_pushbuf *push = pNv->ce_pushbuf;
+       struct nouveau_pushbuf_refn refs[] = {
+               { src, src_dom | NOUVEAU_BO_RD },
+               { dst, dst_dom | NOUVEAU_BO_WR },
+       };
+       unsigned exec;
+
+       if (nouveau_pushbuf_space(push, 64, 0, 0) ||
+           nouveau_pushbuf_refn (push, refs, 2))
+               return FALSE;
+
+       exec = 0x00000000;
+       if (!src->config.nvc0.memtype) {
+               src_off += src_y * src_pitch + src_x * cpp;
+               exec |= 0x00000010;
+       }
+       if (!dst->config.nvc0.memtype) {
+               dst_off += dst_y * dst_pitch + dst_x * cpp;
+               exec |= 0x00000100;
+       }
+
+       BEGIN_NVC0(push, SUBC_COPY(0x0200), 7);
+       PUSH_DATA (push, src->config.nvc0.tile_mode);
+       PUSH_DATA (push, src_pitch);
+       PUSH_DATA (push, src_h);
+       PUSH_DATA (push, 1);
+       PUSH_DATA (push, 0);
+       PUSH_DATA (push, src_x * cpp);
+       PUSH_DATA (push, src_y);
+       BEGIN_NVC0(push, SUBC_COPY(0x0220), 7);
+       PUSH_DATA (push, dst->config.nvc0.tile_mode);
+       PUSH_DATA (push, dst_pitch);
+       PUSH_DATA (push, dst_h);
+       PUSH_DATA (push, 1);
+       PUSH_DATA (push, 0);
+       PUSH_DATA (push, dst_x * cpp);
+       PUSH_DATA (push, dst_y);
+       BEGIN_NVC0(push, SUBC_COPY(0x030c), 8);
+       PUSH_DATA (push, (src->offset + src_off) >> 32);
+       PUSH_DATA (push, (src->offset + src_off));
+       PUSH_DATA (push, (dst->offset + dst_off) >> 32);
+       PUSH_DATA (push, (dst->offset + dst_off));
+       PUSH_DATA (push, src_pitch);
+       PUSH_DATA (push, dst_pitch);
+       PUSH_DATA (push, w * cpp);
+       PUSH_DATA (push, h);
+       BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
+       PUSH_DATA (push, exec);
+
+       return TRUE;
+}
+
+Bool
 NVE0EXARectCopy(NVPtr pNv, int w, int h, int cpp,
                struct nouveau_bo *src, uint32_t src_off, int src_dom,
                int src_pitch, int src_h, int src_x, int src_y,

commit 1600f7f202721c4b29c29e94f7fb69dc313b99dc
Author: Ben Skeggs <bske...@redhat.com>
Date:   Thu May 31 15:40:45 2012 +1000

    nva3/exa: add support for async UTS/DFS copies
    
    Signed-off-by: Ben Skeggs <bske...@redhat.com>

diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index 7b3b086..abf1ff8 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -57,6 +57,11 @@ NVAccelM2MF(NVPtr pNv, int w, int h, int cpp, uint32_t 
srcoff, uint32_t dstoff,
                                       src, srcoff, sd, sp, sh, sx, sy,
                                       dst, dstoff, dd, dp, dh, dx, dy);
        else
+       if (pNv->Architecture >= NV_ARCH_50 && pNv->NvCopy)
+               return NVA3EXARectCopy(pNv, w, h, cpp,
+                                      src, srcoff, sd, sp, sh, sx, sy,
+                                      dst, dstoff, dd, dp, dh, dx, dy);
+       else
        if (pNv->Architecture >= NV_ARCH_50)
                return NV50EXARectM2MF(pNv, w, h, cpp,
                                       src, srcoff, sd, sp, sh, sx, sy,
diff --git a/src/nv50_accel.c b/src/nv50_accel.c
index 16ff643..d7439ab 100644
--- a/src/nv50_accel.c
+++ b/src/nv50_accel.c
@@ -84,6 +84,29 @@ NVAccelInitM2MF_NV50(ScrnInfoPtr pScrn)
 }
 
 Bool
+NVAccelInitCopy_NV50(ScrnInfoPtr pScrn)
+{
+       NVPtr pNv = NVPTR(pScrn);
+       struct nouveau_pushbuf *push = pNv->ce_pushbuf;
+       struct nv04_fifo *fifo = pNv->ce_channel->data;
+
+       if (nouveau_object_new(pNv->ce_channel, 0xbeef85b5, 0x85b5,
+                              NULL, 0, &pNv->NvCopy))
+               return FALSE;
+
+       if (!PUSH_SPACE(push, 8))
+               return FALSE;
+
+       BEGIN_NV04(push, NV01_SUBC(COPY, OBJECT), 1);
+       PUSH_DATA (push, pNv->NvCopy->handle);
+       BEGIN_NV04(push, SUBC_COPY(0x0180), 3);
+       PUSH_DATA (push, fifo->vram);
+       PUSH_DATA (push, fifo->vram);
+       PUSH_DATA (push, fifo->vram);
+       return TRUE;
+}
+
+Bool
 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
 {
        NVPtr pNv = NVPTR(pScrn);
diff --git a/src/nv50_accel.h b/src/nv50_accel.h
index 0f9ed5f..6a09fbe 100644
--- a/src/nv50_accel.h
+++ b/src/nv50_accel.h
@@ -9,7 +9,7 @@
 #include "hwdefs/nv_3ddefs.xml.h"
 #include "hwdefs/nv_m2mf.xml.h"
 
-/* subchannel assignments */
+/* subchannel assignments - graphics channel */
 #define SUBC_M2MF(mthd)  0, (mthd)
 #define NV03_M2MF(mthd)  SUBC_M2MF(NV03_M2MF_##mthd)
 #define NV50_M2MF(mthd)  SUBC_M2MF(NV50_M2MF_##mthd)
@@ -20,6 +20,9 @@
 #define SUBC_3D(mthd)    7, (mthd)
 #define NV50_3D(mthd)    SUBC_3D(NV50_3D_##mthd)
 
+/* subchannel assignments - copy engine channel */
+#define SUBC_COPY(mthd)  2, (mthd)
+
 /* scratch buffer offsets */
 #define PVP_OFFSET  0x00000000 /* Vertex program */
 #define PFP_OFFSET  0x00001000 /* Fragment program */
diff --git a/src/nv50_exa.c b/src/nv50_exa.c
index 1212eb6..2a25e74 100644
--- a/src/nv50_exa.c
+++ b/src/nv50_exa.c
@@ -1010,3 +1010,62 @@ NV50EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
 
        return TRUE;
 }
+
+Bool
+NVA3EXARectCopy(NVPtr pNv, int w, int h, int cpp,
+               struct nouveau_bo *src, uint32_t src_off, int src_dom,
+               int src_pitch, int src_h, int src_x, int src_y,
+               struct nouveau_bo *dst, uint32_t dst_off, int dst_dom,
+               int dst_pitch, int dst_h, int dst_x, int dst_y)
+{
+       struct nouveau_pushbuf *push = pNv->ce_pushbuf;
+       struct nouveau_pushbuf_refn refs[] = {
+               { src, src_dom | NOUVEAU_BO_RD },
+               { dst, dst_dom | NOUVEAU_BO_WR },
+       };
+       unsigned exec;
+
+       if (nouveau_pushbuf_space(push, 64, 0, 0) ||
+           nouveau_pushbuf_refn (push, refs, 2))
+               return FALSE;
+
+       exec = 0x00000000;
+       if (!src->config.nv50.memtype) {
+               src_off += src_y * src_pitch + src_x * cpp;
+               exec |= 0x00000010;
+       }
+       if (!dst->config.nv50.memtype) {
+               dst_off += dst_y * dst_pitch + dst_x * cpp;
+               exec |= 0x00000100;
+       }
+
+       BEGIN_NV04(push, SUBC_COPY(0x0200), 7);
+       PUSH_DATA (push, src->config.nv50.tile_mode);
+       PUSH_DATA (push, src_pitch);
+       PUSH_DATA (push, src_h);
+       PUSH_DATA (push, 1);
+       PUSH_DATA (push, 0);
+       PUSH_DATA (push, src_x * cpp);
+       PUSH_DATA (push, src_y);
+       BEGIN_NV04(push, SUBC_COPY(0x0220), 7);
+       PUSH_DATA (push, dst->config.nv50.tile_mode);
+       PUSH_DATA (push, dst_pitch);
+       PUSH_DATA (push, dst_h);
+       PUSH_DATA (push, 1);
+       PUSH_DATA (push, 0);
+       PUSH_DATA (push, dst_x * cpp);
+       PUSH_DATA (push, dst_y);
+       BEGIN_NV04(push, SUBC_COPY(0x030c), 8);
+       PUSH_DATA (push, (src->offset + src_off) >> 32);
+       PUSH_DATA (push, (src->offset + src_off));
+       PUSH_DATA (push, (dst->offset + dst_off) >> 32);
+       PUSH_DATA (push, (dst->offset + dst_off));
+       PUSH_DATA (push, src_pitch);
+       PUSH_DATA (push, dst_pitch);
+       PUSH_DATA (push, w * cpp);
+       PUSH_DATA (push, h);
+       BEGIN_NV04(push, SUBC_COPY(0x0300), 1);
+       PUSH_DATA (push, exec);
+
+       return TRUE;
+}
diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c
index 7d56093..30f8beb 100644
--- a/src/nv_accel_common.c
+++ b/src/nv_accel_common.c
@@ -624,6 +624,8 @@ NVAccelCommonInit(ScrnInfoPtr pScrn)
        } else
        if (pNv->Architecture < NV_ARCH_C0) {
                INIT_CONTEXT_OBJECT(2D_NV50);
+               if (pNv->ce_enabled)
+                       INIT_CONTEXT_OBJECT(Copy_NV50);
        } else {
                INIT_CONTEXT_OBJECT(2D_NVC0);
        }
diff --git a/src/nv_const.h b/src/nv_const.h
index 5c232d4..1ef45c8 100644
--- a/src/nv_const.h
+++ b/src/nv_const.h
@@ -16,6 +16,7 @@ typedef enum {
     OPTION_ZAPHOD_HEADS,
     OPTION_PAGE_FLIP,
     OPTION_SWAP_LIMIT,
+    OPTION_ASYNC_COPY,
 } NVOpts;
 
 
@@ -30,6 +31,7 @@ static const OptionInfoRec NVOptions[] = {
     { OPTION_ZAPHOD_HEADS,     "ZaphodHeads",  OPTV_STRING,    {0}, FALSE },
     { OPTION_PAGE_FLIP,                "PageFlip",     OPTV_BOOLEAN,   {0}, 
FALSE },
     { OPTION_SWAP_LIMIT,       "SwapLimit",    OPTV_INTEGER,   {0}, FALSE },
+    { OPTION_ASYNC_COPY,       "AsyncUTSDFS",  OPTV_BOOLEAN,   {0}, FALSE },
     { -1,                       NULL,           OPTV_NONE,      {0}, FALSE }
 };
 
diff --git a/src/nv_dma.c b/src/nv_dma.c
index 1757f4d..d2a6d00 100644
--- a/src/nv_dma.c
+++ b/src/nv_dma.c
@@ -79,6 +79,32 @@ NVInitDma(ScrnInfoPtr pScrn)
        }
 
        pNv->pushbuf->user_priv = pNv->bufctx;
+
+       if (pNv->ce_enabled) {
+               ret = nouveau_object_new(device, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
+                                        data, size, &pNv->ce_channel);
+               if (ret) {
+                       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                                  "Error creating CE channel: %d\n", ret);
+                       NVTakedownDma(pScrn);
+                       return FALSE;
+               }
+
+               fifo = pNv->ce_channel->data;
+
+               xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                          "Opened GPU CE channel %d\n", fifo->channel);
+
+               ret = nouveau_pushbuf_new(pNv->client, pNv->ce_channel, 4,
+                                         32 * 1024, true, &pNv->ce_pushbuf);
+               if (ret) {
+                       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                                  "Error allocating CE pushbuf: %d\n", ret);
+                       NVTakedownDma(pScrn);
+                       return FALSE;
+               }
+       }
+
        return TRUE;
 }
 
@@ -86,6 +112,18 @@ void
 NVTakedownDma(ScrnInfoPtr pScrn)
 {
        NVPtr pNv = NVPTR(pScrn);
+
+       if (pNv->ce_channel) {
+               struct nouveau_fifo *fifo = pNv->ce_channel->data;
+               int chid = fifo->channel;
+
+               nouveau_pushbuf_del(&pNv->ce_pushbuf);
+               nouveau_object_del(&pNv->ce_channel);
+
+               xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                          "Closed GPU CE channel %d\n", chid);
+       }
+
        if (pNv->channel) {
                struct nouveau_fifo *fifo = pNv->channel->data;
                int chid = fifo->channel;
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 98486f8..4f9c6cb 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -818,6 +818,9 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
                pNv->tiled_scanout = TRUE;
        }
 
+       pNv->ce_enabled =
+               xf86ReturnOptValBool(pNv->Options, OPTION_ASYNC_COPY, FALSE);
+
        if (!pNv->NoAccel && pNv->dev->chipset >= 0x11) {
                from = X_DEFAULT;
                if (xf86GetOptValBool(pNv->Options, OPTION_GLX_VBLANK,
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 28db773..f7e05c6 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -144,6 +144,7 @@ int NV40SetTexturePortAttribute(ScrnInfoPtr, Atom, INT32, 
pointer);
 /* in nv50_accel.c */
 void NV50SyncToVBlank(PixmapPtr ppix, BoxPtr box);
 Bool NVAccelInitM2MF_NV50(ScrnInfoPtr pScrn);
+Bool NVAccelInitCopy_NV50(ScrnInfoPtr pScrn);
 Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn);
 Bool NVAccelInitNV50TCL(ScrnInfoPtr pScrn);
 
@@ -170,6 +171,9 @@ Bool NV50EXAUploadSIFC(const char *src, int src_pitch,
 Bool NV50EXARectM2MF(NVPtr pNv, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int,
                     struct nouveau_bo *, uint32_t, int, int, int, int, int);
+Bool NVA3EXARectCopy(NVPtr pNv, int, int, int,
+                    struct nouveau_bo *, uint32_t, int, int, int, int, int,
+                    struct nouveau_bo *, uint32_t, int, int, int, int, int);
 
 /* in nvc0_exa.c */
 Bool NVC0AccelUploadM2MF(PixmapPtr pdpix, int x, int y, int w, int h,
diff --git a/src/nv_type.h b/src/nv_type.h
index 49150ba..02fa383 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -82,6 +82,7 @@ typedef struct _NVRec {
 
        /* GPU context */
        struct nouveau_client *client;
+
        struct nouveau_object *channel;
        struct nouveau_pushbuf *pushbuf;
        struct nouveau_bufctx *bufctx;
@@ -104,6 +105,11 @@ typedef struct _NVRec {
        struct nouveau_object *NvSW;
        struct nouveau_bo *scratch;
 
+       Bool ce_enabled;
+       struct nouveau_object *ce_channel;
+       struct nouveau_pushbuf *ce_pushbuf;
+       struct nouveau_object *NvCopy;
+
        /* Acceleration context */
        PixmapPtr pspix, pmpix, pdpix;
        PicturePtr pspict, pmpict;


-- 
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/e1scuk3-0007oj...@vasks.debian.org

Reply via email to