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: