From: Hawking Zhang <Hawking.Zhang@xxxxxxx> v2: fix ddx build warning unused var The change supports the following scenario when freesync enabled for steam game 1). use Alt+Tab to run-time switch between windowed mode and fullscreen mode 2). use option setting to switch between windowed mode and fullscreen mode Also verified on unigine heaven via setting check/un-check fullscreen Signed-off-by: Hawking Zhang <Hawking.Zhang at amd.com> Reviewed-by: Flora Cui <Flora.Cui at amd.com> --- src/amdgpu_dri2.c | 9 ++++++--- src/amdgpu_drv.h | 8 ++++++-- src/amdgpu_extension.c | 25 +++++++++++++++---------- src/amdgpu_kms.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/amdgpu_present.c | 3 ++- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/amdgpu_dri2.c b/src/amdgpu_dri2.c index 8c601c8..c14ffb1 100644 --- a/src/amdgpu_dri2.c +++ b/src/amdgpu_dri2.c @@ -528,7 +528,8 @@ amdgpu_dri2_schedule_flip(xf86CrtcPtr crtc, ClientPtr client, xf86DrvMsgVerb(scrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, "%s:%d fevent[%p]\n", __func__, __LINE__, flip_info); - if (info->freesync_capable_client && + if (info->allow_freesync && + info->freesync_client && info->freesync_enabled == FALSE) { AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE)) @@ -720,7 +721,8 @@ static void amdgpu_dri2_frame_event_handler(xf86CrtcPtr crtc, uint32_t seq, } /* else fall through to exchange/blit */ case DRI2_SWAP: - if (info->freesync_capable_client && + if (info->allow_freesync && + info->freesync_client && info->freesync_enabled == TRUE) { if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE)) info->freesync_enabled = FALSE; @@ -1266,7 +1268,8 @@ static int amdgpu_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, return TRUE; blit_fallback: - if (info->freesync_capable_client && + if (info->allow_freesync && + info->freesync_client && info->freesync_enabled == TRUE) { if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE)) info->freesync_enabled = FALSE; diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h index 91bb829..71274d1 100644 --- a/src/amdgpu_drv.h +++ b/src/amdgpu_drv.h @@ -248,6 +248,8 @@ typedef struct { uint32_t family; struct gbm_device *gbm; + ClipNotifyProcPtr ClipNotify; + Bool(*CloseScreen) (ScreenPtr pScreen); void (*BlockHandler) (BLOCKHANDLER_ARGS_DECL); @@ -304,9 +306,11 @@ typedef struct { Bool allowPageFlip; /* freesync */ - ClientPtr freesync_capable_client; - uint32_t client_resource_id; + ClientPtr freesync_client; + DrawablePtr freesync_drawable; + XID freesync_client_id; Bool freesync_enabled; + Bool allow_freesync; /* cursor size */ int cursor_w; diff --git a/src/amdgpu_extension.c b/src/amdgpu_extension.c index ab7d6e3..33c8987 100644 --- a/src/amdgpu_extension.c +++ b/src/amdgpu_extension.c @@ -62,15 +62,17 @@ static int ProcAMDGPUFreesyncCapability(ClientPtr client) client, 0, DixReadAccess); if (!ret && - info->freesync_capable_client == NULL && pDrawable->x == pDrawable->pScreen->x && pDrawable->y == pDrawable->pScreen->y && pDrawable->width == pDrawable->pScreen->width && pDrawable->height == pDrawable->pScreen->height) { - info->freesync_capable_client = client; - cliResId = FakeClientID(client->index); - if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn)) - info->client_resource_id = cliResId; + if (!info->freesync_client) { + info->freesync_client = client; + cliResId = FakeClientID(client->index); + if (AddResource(cliResId, RT_AMDGPUCLIENT, (void *)pScrn)) + info->freesync_client_id = cliResId; + } + info->freesync_drawable = pDrawable; } return client->noClientException; @@ -162,8 +164,8 @@ void AMDGPUFreeResourceByType(ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); AMDGPUInfoPtr info = AMDGPUPTR(pScrn); - if (info->client_resource_id) - FreeResourceByType(info->client_resource_id, + if (info->freesync_client_id) + FreeResourceByType(info->freesync_client_id, RT_AMDGPUCLIENT, FALSE); return; } @@ -174,9 +176,10 @@ int AMDGPUClientGone(void *data, XID id) AMDGPUInfoPtr info = AMDGPUPTR(pScrn); AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); - if (id == (XID)info->client_resource_id) { - info->client_resource_id = None; - info->freesync_capable_client = NULL; + if (id == info->freesync_client_id) { + info->freesync_client_id = None; + info->freesync_client = NULL; + info->freesync_drawable = NULL; } if (info->freesync_enabled == TRUE) { @@ -184,5 +187,7 @@ int AMDGPUClientGone(void *data, XID id) info->freesync_enabled = FALSE; } + info->allow_freesync = FALSE; + return 1; } diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c index dc98473..88af2fa 100644 --- a/src/amdgpu_kms.c +++ b/src/amdgpu_kms.c @@ -1722,6 +1722,42 @@ static Bool AMDGPUCloseScreen_KMS(ScreenPtr pScreen) return pScreen->CloseScreen(pScreen); } +static void AMDGPUClipNotify(WindowPtr win, int dx, int dy) +{ + ScreenPtr pScreen = win->drawable.pScreen; + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); + AMDGPUInfoPtr info = AMDGPUPTR(pScrn); + AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(pScrn); + ClientPtr client = wClient(win); + + if (info->ClipNotify) { + pScreen->ClipNotify = info->ClipNotify; + pScreen->ClipNotify(win, dx, dy); + info->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = AMDGPUClipNotify; + } + + if (!info->freesync_client) + return; + + if (client == info->freesync_client && + win->drawable.id == info->freesync_drawable->id) { + if (win->drawable.x == pScreen->x && + win->drawable.y == pScreen->y && + win->drawable.width == pScreen->width && + win->drawable.height == pScreen->height) { + info->allow_freesync = TRUE; + } else { + info->allow_freesync = FALSE; + if (info->freesync_enabled == TRUE && + !AMDGPUFreesyncControl(pAMDGPUEnt->fd, FALSE)) + info->freesync_enabled = FALSE; + } + } + + return; +} + void AMDGPUFreeScreen_KMS(ScrnInfoPtr pScrn) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG, @@ -1946,6 +1982,11 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv) pScreen->SyncSharedPixmap = amdgpu_sync_shared_pixmap; #endif + if (!info->shadow_fb) { + info->ClipNotify = pScreen->ClipNotify; + pScreen->ClipNotify = AMDGPUClipNotify; + } + if (!xf86CrtcScreenInit(pScreen)) return FALSE; diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c index 8b70b38..66d264c 100644 --- a/src/amdgpu_present.c +++ b/src/amdgpu_present.c @@ -322,7 +322,8 @@ amdgpu_present_flip(RRCrtcPtr crtc, uint64_t event_id, uint64_t target_msc, if (!amdgpu_present_check_flip(crtc, screen->root, pixmap, sync_flip)) return ret; - if (info->freesync_capable_client && + if (info->allow_freesync && + info->freesync_client && info->freesync_enabled == FALSE) { AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn); if (!AMDGPUFreesyncControl(pAMDGPUEnt->fd, TRUE)) -- 2.18.0