xf86-video-amdgpu: Branch 'master' - 5 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Feb 22 16:51:29 UTC 2019


 src/amdgpu_drv.h     |    1 
 src/amdgpu_kms.c     |  218 ++++++++++++++++++++++++++++++++++++---------------
 src/amdgpu_present.c |    2 
 3 files changed, 158 insertions(+), 63 deletions(-)

New commits:
commit bd090f389f19f1f4a3f662ffdd891345a3899539
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 12 17:57:17 2019 +0100

    Call amdgpu_present_set_screen_vrr from amdgpu_vrr_property_update
    
    If the window is currently flipping.
    
    This might make a difference when the property gets disabled: Variable
    refresh will now be disabled immediately in that case, instead of only
    when the window can no longer use page flipping at all.
    
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>

diff --git a/src/amdgpu_drv.h b/src/amdgpu_drv.h
index 7b3bace..0ae171f 100644
--- a/src/amdgpu_drv.h
+++ b/src/amdgpu_drv.h
@@ -361,6 +361,7 @@ void AMDGPUWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
 				   );
 
 /* amdgpu_present.c */
+void amdgpu_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
 Bool amdgpu_present_screen_init(ScreenPtr screen);
 
 /* amdgpu_sync.c */
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index e50c6d1..458d2d0 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -102,7 +102,14 @@ static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
 static void
 amdgpu_vrr_property_update(WindowPtr window, Bool variable_refresh)
 {
+	ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
+	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
+
 	get_window_priv(window)->variable_refresh = variable_refresh;
+
+	if (info->flip_window == window &&
+	    info->drmmode.present_flipping)
+		amdgpu_present_set_screen_vrr(scrn, variable_refresh);
 }
 
 /* Wrapper for xserver/dix/property.c:ProcChangeProperty */
diff --git a/src/amdgpu_present.c b/src/amdgpu_present.c
index 5a4b9c0..2fbcd25 100644
--- a/src/amdgpu_present.c
+++ b/src/amdgpu_present.c
@@ -90,7 +90,7 @@ amdgpu_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
 /*
  * Changes the variable refresh state for every CRTC on the screen.
  */
-static void
+void
 amdgpu_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled)
 {
 	xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
commit d9be5d712d469595e1e610f7294bc670ca3b1985
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 12 12:26:25 2019 +0100

    Make use of property request wrappers for VRR property
    
    Instead of scanning for PropertyNotify events. Reasons:
    
    * Works even if no client listens to PropertyNotify events for the
      window.
    * No overhead on delivery of unrelated events, and no overhead at all
      if Option "VariableRefresh" is disabled.
    
    v2:
    * Use shorter variable name amdgpu_vrr_atom.
    * Call MakeAtom regardless of info->instance_id, for robustness vs VRR
      being enabled in some but not all AMDGPU screens.
    
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index a870027..e50c6d1 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -66,6 +66,7 @@ static DevPrivateKeyRec amdgpu_window_private_key;
 static DevScreenPrivateKeyRec amdgpu_client_private_key;
 DevScreenPrivateKeyRec amdgpu_device_private_key;
 
+static Atom amdgpu_vrr_atom;
 static Bool amdgpu_property_vectors_wrapped;
 static Bool restore_property_vector;
 static int (*saved_change_property) (ClientPtr client);
@@ -94,17 +95,47 @@ const OptionInfoRec *AMDGPUOptionsWeak(void)
 	return AMDGPUOptions_KMS;
 }
 
+static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
+	return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
+}
+
+static void
+amdgpu_vrr_property_update(WindowPtr window, Bool variable_refresh)
+{
+	get_window_priv(window)->variable_refresh = variable_refresh;
+}
+
 /* Wrapper for xserver/dix/property.c:ProcChangeProperty */
 static int
 amdgpu_change_property(ClientPtr client)
 {
+	WindowPtr window;
 	int ret;
 
+	REQUEST(xChangePropertyReq);
+
 	client->requestVector[X_ChangeProperty] = saved_change_property;
 	ret = saved_change_property(client);
 
-	if (!restore_property_vector)
-		client->requestVector[X_ChangeProperty] = amdgpu_change_property;
+	if (restore_property_vector)
+		return ret;
+
+	client->requestVector[X_ChangeProperty] = amdgpu_change_property;
+
+	if (ret != Success)
+		return ret;
+
+	ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
+	if (ret != Success)
+		return ret;
+
+	if (stuff->property == amdgpu_vrr_atom &&
+	    xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
+	    AMDGPUPreInit_KMS && stuff->format == 32 && stuff->nUnits == 1) {
+		uint32_t *value = (uint32_t*)(stuff + 1);
+
+		amdgpu_vrr_property_update(window, *value != 0);
+	}
 
 	return ret;
 }
@@ -113,13 +144,30 @@ amdgpu_change_property(ClientPtr client)
 static int
 amdgpu_delete_property(ClientPtr client)
 {
+	WindowPtr window;
 	int ret;
 
+	REQUEST(xDeletePropertyReq);
+
 	client->requestVector[X_DeleteProperty] = saved_delete_property;
 	ret = saved_delete_property(client);
 
-	if (!restore_property_vector)
-		client->requestVector[X_DeleteProperty] = amdgpu_delete_property;
+	if (restore_property_vector)
+		return ret;
+
+	client->requestVector[X_DeleteProperty] = amdgpu_delete_property;
+
+	if (ret != Success)
+		return ret;
+
+	ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
+	if (ret != Success)
+		return ret;
+
+	if (stuff->property == amdgpu_vrr_atom &&
+	    xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
+	    AMDGPUPreInit_KMS)
+		amdgpu_vrr_property_update(window, FALSE);
 
 	return ret;
 }
@@ -236,51 +284,6 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
 	free(pEnt);
 }
 
-static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
-	return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
-}
-
-static void
-amdgpu_property_notify(ClientPtr client,
-		       XID id,
-		       int state,
-		       ATOM property_name)
-{
-	WindowPtr win;
-	PropertyPtr prop;
-	struct amdgpu_window_priv *priv;
-	const char* str;
-	int res;
-
-	res = dixLookupWindow(&win, id, client, DixReadAccess);
-	if (res != Success)
-		return;
-
-	str = NameForAtom(property_name);
-	if (str == NULL)
-		return;
-
-	if (strcmp(str, "_VARIABLE_REFRESH") != 0)
-		return;
-
-	priv = get_window_priv(win);
-	if (!priv)
-		return;
-
-	priv->variable_refresh = 0;
-
-	res = dixLookupProperty(&prop,
-				win,
-				property_name,
-				client,
-				DixReadAccess);
-
-	if (res == Success && prop->format == 32 && prop->size == 1) {
-		uint32_t value = *(uint32_t*)prop->data;
-		priv->variable_refresh = (value != 0);
-	}
-}
-
 Bool amdgpu_window_has_variable_refresh(WindowPtr win) {
 	struct amdgpu_window_priv *priv = get_window_priv(win);
 
@@ -328,17 +331,6 @@ amdgpu_event_callback(CallbackListPtr *list,
 	AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
 	int i;
 
-	if (info->vrr_support) {
-		for (i = 0; i < eventinfo->count; i++) {
-			xEventPtr ev = &eventinfo->events[i];
-			if (ev->u.u.type == PropertyNotify)
-				amdgpu_property_notify(eventinfo->client,
-						       ev->u.property.window,
-						       ev->u.property.state,
-						       ev->u.property.atom);
-		}
-	}
-
 	if (callback_needs_flush(info, client_priv) ||
 	    callback_needs_flush(info, server_priv))
 		return;
@@ -2182,6 +2174,9 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
 			ProcVector[X_DeleteProperty] = amdgpu_delete_property;
 			amdgpu_property_vectors_wrapped = TRUE;
 		}
+
+		amdgpu_vrr_atom = MakeAtom("_VARIABLE_REFRESH",
+					   strlen("_VARIABLE_REFRESH"), TRUE);
 	}
 
 	drmmode_init(pScrn, &info->drmmode);
commit ef8fbe33b7d97f7fb5518db9c0e4d2dcbf2fab6f
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Thu Jan 17 18:41:11 2019 +0100

    Wrap change/delete window property request handlers
    
    Preparation for the following change.
    
    v2:
    * Add comments explaining what the wrappers are wrapping.
    * Use global amdgpu_property_vectors_wrapped to keep track of whether
      the vectors need to be (un)wrapped, for robustness against VRR being
      enabled in some but not all AMDGPU screens.
    
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 3c83702..a870027 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -66,6 +66,11 @@ static DevPrivateKeyRec amdgpu_window_private_key;
 static DevScreenPrivateKeyRec amdgpu_client_private_key;
 DevScreenPrivateKeyRec amdgpu_device_private_key;
 
+static Bool amdgpu_property_vectors_wrapped;
+static Bool restore_property_vector;
+static int (*saved_change_property) (ClientPtr client);
+static int (*saved_delete_property) (ClientPtr client);
+
 static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen);
 
 const OptionInfoRec AMDGPUOptions_KMS[] = {
@@ -89,6 +94,80 @@ const OptionInfoRec *AMDGPUOptionsWeak(void)
 	return AMDGPUOptions_KMS;
 }
 
+/* Wrapper for xserver/dix/property.c:ProcChangeProperty */
+static int
+amdgpu_change_property(ClientPtr client)
+{
+	int ret;
+
+	client->requestVector[X_ChangeProperty] = saved_change_property;
+	ret = saved_change_property(client);
+
+	if (!restore_property_vector)
+		client->requestVector[X_ChangeProperty] = amdgpu_change_property;
+
+	return ret;
+}
+
+/* Wrapper for xserver/dix/property.c:ProcDeleteProperty */
+static int
+amdgpu_delete_property(ClientPtr client)
+{
+	int ret;
+
+	client->requestVector[X_DeleteProperty] = saved_delete_property;
+	ret = saved_delete_property(client);
+
+	if (!restore_property_vector)
+		client->requestVector[X_DeleteProperty] = amdgpu_delete_property;
+
+	return ret;
+}
+
+static void
+amdgpu_unwrap_property_requests(ScrnInfoPtr scrn)
+{
+	int i;
+
+	if (!amdgpu_property_vectors_wrapped)
+		return;
+
+	if (ProcVector[X_ChangeProperty] == amdgpu_change_property)
+		ProcVector[X_ChangeProperty] = saved_change_property;
+	else
+		restore_property_vector = TRUE;
+
+	if (ProcVector[X_DeleteProperty] == amdgpu_delete_property)
+		ProcVector[X_DeleteProperty] = saved_delete_property;
+	else
+		restore_property_vector = TRUE;
+
+	for (i = 0; i < currentMaxClients; i++) {
+		if (clients[i]->requestVector[X_ChangeProperty] ==
+		    amdgpu_change_property) {
+			clients[i]->requestVector[X_ChangeProperty] =
+				saved_change_property;
+		} else {
+			restore_property_vector = TRUE;
+		}
+
+		if (clients[i]->requestVector[X_DeleteProperty] ==
+		    amdgpu_delete_property) {
+			clients[i]->requestVector[X_DeleteProperty] =
+				saved_delete_property;
+		} else {
+			restore_property_vector = TRUE;
+		}
+	}
+
+	if (restore_property_vector) {
+		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+			   "Couldn't unwrap some window property request vectors\n");
+	}
+
+	amdgpu_property_vectors_wrapped = FALSE;
+}
+
 extern _X_EXPORT int gAMDGPUEntityIndex;
 
 static int getAMDGPUEntityIndex(void)
@@ -146,6 +225,7 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
 		pAMDGPUEnt = pPriv->ptr;
 		pAMDGPUEnt->fd_ref--;
 		if (!pAMDGPUEnt->fd_ref) {
+			amdgpu_unwrap_property_requests(pScrn);
 			amdgpu_device_deinitialize(pAMDGPUEnt->pDev);
 			amdgpu_kernel_close_fd(pAMDGPUEnt);
 			free(pPriv->ptr);
@@ -156,7 +236,6 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
 	free(pEnt);
 }
 
-
 static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
 	return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
 }
@@ -2095,6 +2174,16 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
 	if (serverGeneration == 1)
 		xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
+	if (info->vrr_support) {
+		if (!amdgpu_property_vectors_wrapped) {
+			saved_change_property = ProcVector[X_ChangeProperty];
+			ProcVector[X_ChangeProperty] = amdgpu_change_property;
+			saved_delete_property = ProcVector[X_DeleteProperty];
+			ProcVector[X_DeleteProperty] = amdgpu_delete_property;
+			amdgpu_property_vectors_wrapped = TRUE;
+		}
+	}
+
 	drmmode_init(pScrn, &info->drmmode);
 
 	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
commit 09a45ff8fe3ac07bafa3a0822b1598c41f9ca200
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 12 13:01:04 2019 +0100

    Don't enable the VRR support code for GPU screens
    
    Windows aren't associated with GPU screens, and amdgpu_present_flip is
    never called for them, so VRR can never actually be enabled for them.
    
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index ea11ba8..3c83702 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -1551,11 +1551,13 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
 		if (info->shadow_primary)
 			xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
 
-		from = xf86GetOptValBool(info->Options, OPTION_VARIABLE_REFRESH,
-					 &info->vrr_support) ? X_CONFIG : X_DEFAULT;
+		if (!pScrn->is_gpu) {
+			from = xf86GetOptValBool(info->Options, OPTION_VARIABLE_REFRESH,
+						 &info->vrr_support) ? X_CONFIG : X_DEFAULT;
 
-		xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
-			   info->vrr_support ? "en" : "dis");
+			xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
+				   info->vrr_support ? "en" : "dis");
+		}
 	}
 
 	if (!pScrn->is_gpu) {
commit 2a3d00dc7ed2b4fca698e2d699e1b94da6d0ddb8
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Tue Feb 12 18:12:23 2019 +0100

    Don't register a window private if VRR is disabled
    
    It's not used in that case.
    
    Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas at amd.com>

diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 05becb2..ea11ba8 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -365,7 +365,8 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen)
 		}
 	}
 
-	if (!dixRegisterPrivateKey(&amdgpu_window_private_key,
+	if (info->vrr_support &&
+	    !dixRegisterPrivateKey(&amdgpu_window_private_key,
 				   PRIVATE_WINDOW,
 				   sizeof(struct amdgpu_window_priv)))
 		return FALSE;


More information about the xorg-commit mailing list