kmsdrm: enable vrr on displays that support it
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h
index f53c5c8..4fdce52 100644
--- a/src/video/kmsdrm/SDL_kmsdrmsym.h
+++ b/src/video/kmsdrm/SDL_kmsdrmsym.h
@@ -80,6 +80,9 @@ SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value)
SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
SDL_KMSDRM_SYM(drmModeObjectPropertiesPtr,drmModeObjectGetProperties,(int fd,uint32_t object_id,uint32_t object_type))
+SDL_KMSDRM_SYM(int,drmModeObjectSetProperty,(int fd, uint32_t object_id,
+ uint32_t object_type, uint32_t property_id,
+ uint64_t value))
SDL_KMSDRM_SYM(drmModePropertyPtr,drmModeGetProperty,(int fd, uint32_t propertyId))
SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr))
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index def7233..821dc18 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -534,6 +534,93 @@ KMSDRM_DeinitDisplays (_THIS) {
}
}
+static uint32_t
+KMSDRM_CrtcGetPropId(uint32_t drm_fd,
+ drmModeObjectPropertiesPtr props,
+ char const* name)
+{
+ uint32_t i, prop_id = 0;
+
+ for (i = 0; !prop_id && i < props->count_props; ++i) {
+ drmModePropertyPtr drm_prop =
+ KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+
+ if (!drm_prop)
+ continue;
+
+ if (strcmp(drm_prop->name, name) == 0)
+ prop_id = drm_prop->prop_id;
+
+ KMSDRM_drmModeFreeProperty(drm_prop);
+ }
+
+ return prop_id;
+}
+
+static uint32_t KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id) {
+ drmModeObjectPropertiesPtr drm_props;
+ uint32_t vrr_prop_id;
+
+ drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
+ crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+
+ if (!drm_props)
+ exit(-1);
+
+ vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
+ drm_props,
+ "VRR_ENABLED");
+
+ KMSDRM_drmModeFreeObjectProperties(drm_props);
+
+ return vrr_prop_id;
+}
+
+static SDL_bool
+KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd,
+ uint32_t output_id,
+ char const* name)
+{
+ uint32_t i;
+ Bool found = SDL_FALSE;
+ uint64_t prop_value = 0;
+
+
+ drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd,
+ output_id,
+ DRM_MODE_OBJECT_CONNECTOR);
+
+ for (i = 0; !found && i < props->count_props; ++i) {
+ drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+
+ if (!drm_prop)
+ continue;
+
+ if (strcasecmp(drm_prop->name, name) == 0) {
+ prop_value = props->prop_values[i];
+ found = SDL_TRUE;
+ }
+
+ KMSDRM_drmModeFreeProperty(drm_prop);
+ }
+ if(found)
+ return prop_value ? SDL_TRUE: SDL_FALSE;
+
+ return SDL_FALSE;
+}
+
+void
+KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, Bool enabled)
+{
+ uint32_t vrr_prop_id = KMSDRM_VrrPropId(drm_fd, crtc_id);
+
+ KMSDRM_drmModeObjectSetProperty(drm_fd,
+ crtc_id,
+ DRM_MODE_OBJECT_CRTC,
+ vrr_prop_id,
+ enabled);
+}
/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
list of SDL Displays in _this->displays[] */
static void
@@ -701,6 +788,12 @@ KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
/* Add the display to the list of SDL displays. */
SDL_AddVideoDisplay(&display, SDL_FALSE);
+ /* try to enable vrr */
+ if(KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
+ KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, SDL_TRUE);
+ }
+
cleanup:
if (encoder)
KMSDRM_drmModeFreeEncoder(encoder);