diff options
author | Mario Kleiner <mario.kleiner.de@gmail.com> | 2014-03-14 18:23:04 +0100 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-21 17:04:44 +1000 |
commit | 54dfbb2fed393b65d846e6ed9672acb47e0f19de (patch) | |
tree | 5c276b0c7cb6eeab183953164892fc54b1afbbbf | |
parent | 303402e00d55b5296311738184cd61f4aadab74d (diff) |
dri2: Fix double-sync of pageflips on Linux 3.13+ - Part I
Linux 3.13 and later sync kms pageflips to vblank in the kms
driver, so we must not emit a sync to vblank pushbuf in the ddx
on such kernels, or maximum framerate will be cut into half!
A sync-to-vblank-pushbuf is emitted for copyswaps as in the past,
also for older kernels which don't support async_pageflip's and
don't sync by themselves.
This adds the implementation, but not the detection logic for
async_pageflip support in the kernel.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | src/nouveau_dri2.c | 17 | ||||
-rw-r--r-- | src/nv_type.h | 1 |
2 files changed, 15 insertions, 3 deletions
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c index 5848966..a9851cb 100644 --- a/src/nouveau_dri2.c +++ b/src/nouveau_dri2.c @@ -619,7 +619,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, struct nouveau_pushbuf *push = pNv->pushbuf; RegionRec reg; int type, ret; - Bool front_updated; + Bool front_updated, will_exchange; REGION_INIT(0, ®, (&(BoxRec){ 0, 0, draw->width, draw->height }), 0); REGION_TRANSLATE(0, ®, draw->x, draw->y); @@ -648,7 +648,18 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, /* Throttle on the previous frame before swapping */ nouveau_bo_wait(dst_bo, NOUVEAU_BO_RD, push->client); - if (can_sync_to_vblank(draw)) { + /* Swap by buffer exchange possible? */ + will_exchange = front_updated && can_exchange(draw, dst_pix, src_pix); + + /* Only emit a wait for vblank pushbuf here if this is a copy-swap, or + * if it is a kms pageflip-swap on an old kernel. Pure exchange swaps + * don't need sync to vblank. kms pageflip-swaps on Linux 3.13+ are + * synced to vblank in the kms driver, so we must not sync here, or + * framerate will be cut in half! + */ + if (can_sync_to_vblank(draw) && + (!will_exchange || + (!pNv->has_async_pageflip && nouveau_exa_pixmap_is_onscreen(dst_pix)))) { /* Reference the back buffer to sync it to vblank */ nouveau_pushbuf_refn(push, &(struct nouveau_pushbuf_refn) { src_bo, @@ -666,7 +677,7 @@ nouveau_dri2_finish_swap(DrawablePtr draw, unsigned int frame, nouveau_pushbuf_kick(push, push->channel); } - if (front_updated && can_exchange(draw, dst_pix, src_pix)) { + if (will_exchange) { type = DRI2_EXCHANGE_COMPLETE; DamageRegionAppend(draw, ®); diff --git a/src/nv_type.h b/src/nv_type.h index 3c52e4e..b4889bf 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -63,6 +63,7 @@ typedef struct _NVRec { Bool wfb_enabled; Bool tiled_scanout; Bool glx_vblank; + Bool has_async_pageflip; Bool has_pageflip; int swap_limit; int max_swap_limit; |