nvc0: Add and enable vblank support
PATCH 1/1 nvc0: Add and enable vblank support
Based on the original patch by Christoph Bumiller, but since it depends on kernel support patched I cannot push it yet.
The changes are that I enable vblank by default, and offset takes OFFSET_HIGH/LOW instead of something relative to notifier_bo.
---
man/nouveau.man +1 -1
@@ -79,7 +79,7 @@ Enable or disable wfb, only affects nv50+. Useful for some legacy configurations .BI "Option \*qGLXVBlank\*q \*q" boolean \*q Synchronize GLX clients to VBlank. Useful where tearing is a problem, harmful if the GPU isn't fast enough to keep up with the monitor -refresh rate. Default: off. +refresh rate. Default: on. .TP .BI "Option \*qZaphodHeads\*q \*q" string \*q Specify the randr output(s) to use with zaphod mode for a particular driver
src/nouveau_dri2.c +3 -0
@@ -316,6 +316,9 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,NOUVEAU_BO_VRAM |NOUVEAU_BO_RD }, 1); +if (pNv->Architecture >=NV_ARCH_C0 ) +NVC0SyncToVBlank (dst_pix,REGION_EXTENTS (0 , ®)); +else if (pNv->Architecture >=NV_ARCH_50 )NV50SyncToVBlank (dst_pix,REGION_EXTENTS (0 , ®));else
src/nv_dma.c +12 -0
@@ -63,6 +63,18 @@ NVInitDma(ScrnInfoPtr pScrn)xf86DrvMsg (pScrn->scrnIndex,X_INFO ,"Opened GPU channel %d\n" , fifo->channel); +if (pNv->Architecture >=NV_ARCH_C0 ) { +struct nvc0_fifo *data = (struct nvc0_fifo *)fifo; + ret =nouveau_bo_wrap (pNv->dev, data->notify, + &pNv->notifier_bo); +if (ret) { +xf86DrvMsg (pScrn->scrnIndex,X_ERROR , +"Failed to obtain notifier bo: %d\n" , ret); +NVTakedownDma (pScrn); +return FALSE; + } + } + ret =nouveau_pushbuf_new (pNv->client, pNv->channel,4 ,32 *1024 , true, &pNv->pushbuf);if (ret) {
src/nv_driver.c +1 -0
@@ -815,6 +815,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)if (!pNv->NoAccel && pNv->dev->chipset >=0x11 ) { from =X_DEFAULT ; + pNv->glx_vblank = TRUE;if (xf86GetOptValBool (pNv->Options,OPTION_GLX_VBLANK , &pNv->glx_vblank)) from =X_CONFIG ;
src/nv_proto.h +1 -0
@@ -149,6 +149,7 @@ Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn);Bool NVAccelInitNV50TCL (ScrnInfoPtr pScrn);/* in nvc0_accel.c */ +void NVC0SyncToVBlank (PixmapPtr ppix,BoxPtr box);Bool NVAccelInitM2MF_NVC0 (ScrnInfoPtr pScrn);Bool NVAccelInitCopy_NVC0 (ScrnInfoPtr pScrn);Bool NVAccelInitP2MF_NVE0 (ScrnInfoPtr pScrn);
src/nv_type.h +1 -0
@@ -102,6 +102,7 @@ typedef struct _NVRec {struct nouveau_object *Nv2D;struct nouveau_object *Nv3D;struct nouveau_object *NvSW; +struct nouveau_bo *notifier_bo;struct nouveau_bo *scratch;Bool ce_enabled;
src/nvc0_accel.c +45 -0
63 lines not on this page · raw message
src/nvc0_xv.c +2 -3
@@ -221,9 +221,8 @@ nvc0_xv_image_put(ScrnInfoPtr pScrn,PUSH_DATAf (push,1.0 / width);PUSH_DATAf (push,1.0 / height); -if (0 && pPriv->SyncToVBlank) { -NV50SyncToVBlank (ppix, dstBox); - } +if (pPriv->SyncToVBlank) +NVC0SyncToVBlank (ppix, dstBox);/* These are fixed point values in the 16.16 format. */ X1 = (float )(x1>>16 )+(float )(x1&0xFFFF )/(float )0x10000 ;
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 2 lines · Maarten Lankhorst
Based on the original patch by Christoph Bumiller, but since it depends on kernel support patched I cannot push it yet.
Hey Maarten,
I've pushed support for sync-to-vblank on fermi and up (tested on NVC0, NVD9 and NVE7) to the DRM (in the rework code) and the DDX.
There's a few differences to your code, mostly for NVC0 where we use PFIFO SWMTHD rather than PGRAPH ILLEGAL_CLASS for the software traps.
Also, I tracked down (on NVD9) an issue where we get far more vblank interrupts than expected, turns out vblank is a sub-status of what you were using.
Let me know if there's any issues.
Ben.
Quoted 183 lines
The changes are that I enable vblank by default, and offset takes OFFSET_HIGH/LOW instead of something relative to
notifier_bo.Signed-off-by Maarten Lankhorst <[email protected]>---
man/nouveau.man +1
-1@@ -79,7 +79,7 @@ Enable or disable wfb, only affects nv50+. Useful for some legacy configurations .BI "Option \*qGLXVBlank\*q \*q" boolean \*q Synchronize GLX clients to VBlank. Useful where tearing is a problem, harmful if the GPU isn't fast enough to keep up with the monitor -refresh rate. Default: off. +refresh rate. Default: on. .TP .BI "Option \*qZaphodHeads\*q \*q" string \*q Specify the randr output(s) to use with zaphod mode for a particular driversrc/nouveau_dri2.c +3
-0@@ -316,6 +316,9 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame,NOUVEAU_BO_VRAM |NOUVEAU_BO_RD }, 1); +if (pNv->Architecture >=NV_ARCH_C0 ) +NVC0SyncToVBlank (dst_pix,REGION_EXTENTS (0 , ®)); +else if (pNv->Architecture >=NV_ARCH_50 )NV50SyncToVBlank (dst_pix,REGION_EXTENTS (0 , ®));else src/nv_dma.c +12
-0@@ -63,6 +63,18 @@ NVInitDma(ScrnInfoPtr pScrn)xf86DrvMsg (pScrn->scrnIndex,X_INFO ,"Opened GPU channel %d\n" , fifo->channel); +if (pNv->Architecture >=NV_ARCH_C0 ) { +struct nvc0_fifo *data = (struct nvc0_fifo *)fifo; + ret =nouveau_bo_wrap (pNv->dev, data->notify, + &pNv->notifier_bo); +if (ret) { +xf86DrvMsg (pScrn->scrnIndex,X_ERROR , +"Failed to obtain notifier bo: %d\n" , ret); +NVTakedownDma (pScrn); +return FALSE; + } + } + ret =nouveau_pushbuf_new (pNv->client, pNv->channel,4 ,32 *1024 , true, &pNv->pushbuf);if (ret) {src/nv_driver.c +1
-0@@ -815,6 +815,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)if (!pNv->NoAccel && pNv->dev->chipset >=0x11 ) { from =X_DEFAULT ; + pNv->glx_vblank = TRUE;if (xf86GetOptValBool (pNv->Options,OPTION_GLX_VBLANK , &pNv->glx_vblank)) from =X_CONFIG ;src/nv_proto.h +1
-0@@ -149,6 +149,7 @@ Bool NVAccelInit2D_NV50(ScrnInfoPtr pScrn);Bool NVAccelInitNV50TCL (ScrnInfoPtr pScrn);/* in nvc0_accel.c */ +void NVC0SyncToVBlank (PixmapPtr ppix,BoxPtr box);Bool NVAccelInitM2MF_NVC0 (ScrnInfoPtr pScrn);Bool NVAccelInitCopy_NVC0 (ScrnInfoPtr pScrn);Bool NVAccelInitP2MF_NVE0 (ScrnInfoPtr pScrn);src/nv_type.h +1
-0@@ -102,6 +102,7 @@ typedef struct _NVRec {struct nouveau_object *Nv2D;struct nouveau_object *Nv3D;struct nouveau_object *NvSW; +struct nouveau_bo *notifier_bo;struct nouveau_bo *scratch;Bool ce_enabled;src/nvc0_accel.c +45
-0@@ -25,6 +25,36 @@#include "nvc0_shader.h" #include "nve0_shader.h" +void +NVC0SyncToVBlank (PixmapPtr ppix,BoxPtr box) +{ +ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum]; +NVPtr pNv =NVPTR (pScrn); +struct nouveau_pushbuf *push = pNv->pushbuf; +int crtcs; + +if (!nouveau_exa_pixmap_is_onscreen (ppix)) +return ; + + crtcs =nv_window_belongs_to_crtc (pScrn, box->x1, box->y1, + box->x2 - box->x1, + box->y2 - box->y1); +if (!crtcs) +return ; + +BEGIN_NVC0 (push,SUBC_NVSW (NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH ),4 ); +PUSH_DATA (push, pNv->notifier_bo->offset >>32 ); +PUSH_DATA (push, pNv->notifier_bo->offset); +PUSH_DATA (push,0x22222222 ); +PUSH_DATA (push,NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG ); +BEGIN_NVC0 (push,SUBC_NVSW (0x0208 ),2 ); +PUSH_DATA (push,0x11111111 ); +PUSH_DATA (push,ffs (crtcs) -1 ); +BEGIN_NVC0 (push,SUBC_NVSW (NV84_SUBCHAN_SEMAPHORE_SEQUENCE ),2 ); +PUSH_DATA (push,0x11111111 ); +PUSH_DATA (push,NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL ); +} +Bool NVAccelInitM2MF_NVC0 (ScrnInfoPtr pScrn) {@@ -153,12 +183,27 @@ NVAccelInit3D_NVC0(ScrnInfoPtr pScrn)if (ret)return FALSE; + ret =nouveau_object_new (pNv->channel,0x906e ,0x906e , +NULL ,0 , &pNv->NvSW); +if (nouveau_pushbuf_space (push,512 ,0 ,0 ) ||nouveau_pushbuf_refn (push, &(struct nouveau_pushbuf_refn ) { pNv->scratch,NOUVEAU_BO_VRAM |NOUVEAU_BO_WR },1 ))return FALSE; +if (!ret) { +BEGIN_NVC0 (push,NV01_SUBC (NVSW ,OBJECT ),1 ); +PUSH_DATA (push, pNv->NvSW->handle); +BEGIN_NVC0 (push,SUBC_NVSW (0x0200 ),2 );/* VBLSEM_OFFSET */ +PUSH_DATA (push, pNv->notifier_bo->offset >>32 ); +PUSH_DATA (push, pNv->notifier_bo->offset); + }else if (pNv->glx_vblank) { +xf86DrvMsg (pScrn->scrnIndex,X_WARNING , +"No kernel support for GLX sync to VBlank.\n" ); + pNv->glx_vblank = false; + } +BEGIN_NVC0 (push,NV01_SUBC (3D ,OBJECT ),1 );PUSH_DATA (push, pNv->Nv3D->handle);BEGIN_NVC0 (push,NVC0_3D (COND_MODE ),1 );src/nvc0_xv.c +2
-3@@ -221,9 +221,8 @@ nvc0_xv_image_put(ScrnInfoPtr pScrn,PUSH_DATAf (push,1.0 / width);PUSH_DATAf (push,1.0 / height); -if (0 && pPriv->SyncToVBlank) { -NV50SyncToVBlank (ppix, dstBox); - } +if (pPriv->SyncToVBlank) +NVC0SyncToVBlank (ppix, dstBox);/* These are fixed point values in the 16.16 format. */ X1 = (float )(x1>>16 )+(float )(x1&0xFFFF )/(float )0x10000 ;_______________________________________________
Nouveau mailing list [email protected]
http://lists.freedesktop.org/mailman/listinfo/nouveau