summaryrefslogtreecommitdiff
path: root/src/amdgpu_kms.c
diff options
context:
space:
mode:
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) {