diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h index f53c5c8ea..4fdce5292 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 def72334b..821dc183a 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);