[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-nouveau: Changes to 'upstream-unstable'



 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ý <noviktor@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ý <noviktor@seznam.cz>
    Reviewed-by: Marcin Slusarz <marcin.slusarz@gmail.com>
    Signed-off-by: Ben Skeggs <bskeggs@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 <airlied@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 <airlied@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 <airlied@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 <airlied@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 <airlied@redhat.com>
Date:   Tue Jun 5 10:57:30 2012 +0100

    nouveau: drop flags arg to adjust frame
    
    Signed-off-by: Dave Airlie <airlied@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 <bskeggs@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 <bskeggs@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 <bskeggs@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 <bskeggs@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;


Reply to: