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