summaryrefslogtreecommitdiff
path: root/src/amdgpu_kms.c
diff options
context:
space:
mode:
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>2018-10-04 09:51:40 -0400
committerMichel Daenzer <michel@daenzer.net>2018-11-30 15:40:34 +0000
commitb11ee02c4596ddee3c9ff2141be5c91815efacc3 (patch)
tree189e9e301e3c2144a7ad385523bbf68b65682fdb /src/amdgpu_kms.c
parent2d18b37159edc526c73a36143fe9b5d6b75e610a (diff)
Support CRTC variable refresh for windows using Present flips
This patch adds support for setting the CRTC variable refresh property for suitable windows flipping via the Present extension. The "VariableRefresh" Option is added to AMDGPU in this patch. This option defaults to false, and must be set to "true" in an X conf file for variable refresh support in the driver. In order for a window to be suitable for variable refresh it must have the _VARIABLE_REFRESH property with a 32-bit CARDINAL value of 1. Then the window must pass the checks required to be suitable for Present extension flips - it must cover the entire X screen and no other window may already be flipping. With these conditions met every CRTC for the X screen will have their variable refresh property set to true. Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Diffstat (limited to 'src/amdgpu_kms.c')
-rw-r--r--src/amdgpu_kms.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/amdgpu_kms.c b/src/amdgpu_kms.c
index 2622409..92782de 100644
--- a/src/amdgpu_kms.c
+++ b/src/amdgpu_kms.c
@@ -62,6 +62,7 @@
#include <gbm.h>
+static DevPrivateKeyRec amdgpu_window_private_key;
static DevScreenPrivateKeyRec amdgpu_client_private_key;
DevScreenPrivateKeyRec amdgpu_device_private_key;
@@ -79,6 +80,7 @@ const OptionInfoRec AMDGPUOptions_KMS[] = {
{OPTION_SHADOW_PRIMARY, "ShadowPrimary", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_TEAR_FREE, "TearFree", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DELETE_DP12, "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_VARIABLE_REFRESH, "VariableRefresh", OPTV_BOOLEAN, {0}, FALSE },
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -154,6 +156,58 @@ 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);
+
+ return priv->variable_refresh;
+}
+
static void *amdgpuShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset,
int mode, CARD32 * size, void *closure)
{
@@ -195,6 +249,17 @@ 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;
@@ -300,6 +365,11 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen)
}
}
+ if (!dixRegisterPrivateKey(&amdgpu_window_private_key,
+ PRIVATE_WINDOW,
+ sizeof(struct amdgpu_window_priv)))
+ return FALSE;
+
return TRUE;
}
@@ -1415,6 +1485,12 @@ 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;
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
+ info->vrr_support ? "en" : "dis");
}
if (!pScrn->is_gpu) {