modesetting: Parse the IN_FORMATS_ASYNC blob

The kernel has gained another format/modifier blob to indicate
which formats/modifiers support async flips since Linux 6.16. Parse it.

Signed-off-by: notbabaisyou <though-went-some-simple@proton.me>
This commit is contained in:
Ville Syrjälä 2025-06-24 22:48:35 +02:00 committed by notbabaisyou
parent 787286c946
commit c5a23ada0e
3 changed files with 40 additions and 13 deletions

View File

@ -114,8 +114,18 @@ get_opaque_format(uint32_t format)
} }
} }
static drmmode_format_ptr get_format(drmmode_crtc_private_ptr drmmode_crtc,
Bool async_flip, int i)
{
if (async_flip && drmmode_crtc->formats_async)
return &drmmode_crtc->formats_async[i];
else
return &drmmode_crtc->formats[i];
}
Bool Bool
drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, uint64_t modifier) drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format,
uint64_t modifier, Bool async_flip)
{ {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int c, i, j; int c, i, j;
@ -135,7 +145,7 @@ drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, uint64_t modifier
continue; continue;
for (i = 0; i < drmmode_crtc->num_formats; i++) { for (i = 0; i < drmmode_crtc->num_formats; i++) {
drmmode_format_ptr iter = &drmmode_crtc->formats[i]; drmmode_format_ptr iter = get_format(drmmode_crtc, async_flip, i);
if (iter->format != format) if (iter->format != format)
continue; continue;
@ -166,7 +176,7 @@ drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, uint64_t modifier
#ifdef GBM_BO_WITH_MODIFIERS #ifdef GBM_BO_WITH_MODIFIERS
static uint32_t static uint32_t
get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers, get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers,
Bool enabled_crtc_only, Bool exclude_multiplane) Bool enabled_crtc_only, Bool exclude_multiplane, Bool async_flip)
{ {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
modesettingPtr ms = modesettingPTR(scrn); modesettingPtr ms = modesettingPTR(scrn);
@ -186,7 +196,7 @@ get_modifiers_set(ScrnInfoPtr scrn, uint32_t format, uint64_t **modifiers,
continue; continue;
for (i = 0; i < drmmode_crtc->num_formats; i++) { for (i = 0; i < drmmode_crtc->num_formats; i++) {
drmmode_format_ptr iter = &drmmode_crtc->formats[i]; drmmode_format_ptr iter = get_format(drmmode_crtc, async_flip, i);
if (iter->format != format) if (iter->format != format)
continue; continue;
@ -241,7 +251,8 @@ get_drawable_modifiers(DrawablePtr draw, uint32_t format,
return TRUE; return TRUE;
} }
*num_modifiers = get_modifiers_set(scrn, format, modifiers, TRUE, FALSE); *num_modifiers = get_modifiers_set(scrn, format, modifiers,
TRUE, FALSE, FALSE);
return TRUE; return TRUE;
} }
#endif #endif
@ -2295,7 +2306,7 @@ is_plane_assigned(ScrnInfoPtr scrn, int plane_id)
*/ */
static Bool static Bool
populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane, populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
uint32_t blob_id) drmmode_format_rec *formats, uint32_t blob_id)
{ {
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode; drmmode_ptr drmmode = drmmode_crtc->drmmode;
@ -2341,9 +2352,9 @@ populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
modifiers[num_modifiers - 1] = mod->modifier; modifiers[num_modifiers - 1] = mod->modifier;
} }
drmmode_crtc->formats[i].format = blob_formats[i]; formats[i].format = blob_formats[i];
drmmode_crtc->formats[i].modifiers = modifiers; formats[i].modifiers = modifiers;
drmmode_crtc->formats[i].num_modifiers = num_modifiers; formats[i].num_modifiers = num_modifiers;
} }
drmModeFreePropertyBlob(blob); drmModeFreePropertyBlob(blob);
@ -2359,7 +2370,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
drmModePlaneRes *kplane_res; drmModePlaneRes *kplane_res;
drmModePlane *kplane, *best_kplane = NULL; drmModePlane *kplane, *best_kplane = NULL;
drmModeObjectProperties *props; drmModeObjectProperties *props;
uint32_t i, type, blob_id; uint32_t i, type, blob_id, async_blob_id;
int current_crtc, best_plane = 0; int current_crtc, best_plane = 0;
static drmmode_prop_enum_info_rec plane_type_enums[] = { static drmmode_prop_enum_info_rec plane_type_enums[] = {
@ -2382,6 +2393,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
[DRMMODE_PLANE_FB_ID] = { .name = "FB_ID", }, [DRMMODE_PLANE_FB_ID] = { .name = "FB_ID", },
[DRMMODE_PLANE_CRTC_ID] = { .name = "CRTC_ID", }, [DRMMODE_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
[DRMMODE_PLANE_IN_FORMATS] = { .name = "IN_FORMATS", }, [DRMMODE_PLANE_IN_FORMATS] = { .name = "IN_FORMATS", },
[DRMMODE_PLANE_IN_FORMATS_ASYNC] = { .name = "IN_FORMATS_ASYNC", },
[DRMMODE_PLANE_SRC_X] = { .name = "SRC_X", }, [DRMMODE_PLANE_SRC_X] = { .name = "SRC_X", },
[DRMMODE_PLANE_SRC_Y] = { .name = "SRC_Y", }, [DRMMODE_PLANE_SRC_Y] = { .name = "SRC_Y", },
[DRMMODE_PLANE_SRC_W] = { .name = "SRC_W", }, [DRMMODE_PLANE_SRC_W] = { .name = "SRC_W", },
@ -2456,6 +2468,8 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
best_kplane = kplane; best_kplane = kplane;
blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS], blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS],
props, 0); props, 0);
async_blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS_ASYNC],
props, 0);
drmmode_prop_info_copy(drmmode_crtc->props_plane, tmp_props, drmmode_prop_info_copy(drmmode_crtc->props_plane, tmp_props,
DRMMODE_PLANE__COUNT, 1); DRMMODE_PLANE__COUNT, 1);
drmModeFreeObjectProperties(props); drmModeFreeObjectProperties(props);
@ -2467,6 +2481,8 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
best_kplane = kplane; best_kplane = kplane;
blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS], blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS],
props, 0); props, 0);
async_blob_id = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_IN_FORMATS_ASYNC],
props, 0);
drmmode_prop_info_copy(drmmode_crtc->props_plane, tmp_props, drmmode_prop_info_copy(drmmode_crtc->props_plane, tmp_props,
DRMMODE_PLANE__COUNT, 1); DRMMODE_PLANE__COUNT, 1);
} else { } else {
@ -2481,9 +2497,18 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
drmmode_crtc->num_formats = best_kplane->count_formats; drmmode_crtc->num_formats = best_kplane->count_formats;
drmmode_crtc->formats = calloc(best_kplane->count_formats, drmmode_crtc->formats = calloc(best_kplane->count_formats,
sizeof(drmmode_format_rec)); sizeof(drmmode_format_rec));
if (!populate_format_modifiers(crtc, best_kplane, blob_id)) { if (!populate_format_modifiers(crtc, best_kplane,
drmmode_crtc->formats, blob_id)) {
for (i = 0; i < best_kplane->count_formats; i++) for (i = 0; i < best_kplane->count_formats; i++)
drmmode_crtc->formats[i].format = best_kplane->formats[i]; drmmode_crtc->formats[i].format = best_kplane->formats[i];
} else {
drmmode_crtc->formats_async = calloc(best_kplane->count_formats,
sizeof(drmmode_format_rec));
if (!populate_format_modifiers(crtc, best_kplane,
drmmode_crtc->formats_async, async_blob_id)) {
free(drmmode_crtc->formats_async);
drmmode_crtc->formats_async = NULL;
}
} }
drmModeFreePlane(best_kplane); drmModeFreePlane(best_kplane);
} }

View File

@ -42,6 +42,7 @@ enum drmmode_plane_property {
DRMMODE_PLANE_TYPE = 0, DRMMODE_PLANE_TYPE = 0,
DRMMODE_PLANE_FB_ID, DRMMODE_PLANE_FB_ID,
DRMMODE_PLANE_IN_FORMATS, DRMMODE_PLANE_IN_FORMATS,
DRMMODE_PLANE_IN_FORMATS_ASYNC,
DRMMODE_PLANE_CRTC_ID, DRMMODE_PLANE_CRTC_ID,
DRMMODE_PLANE_SRC_X, DRMMODE_PLANE_SRC_X,
DRMMODE_PLANE_SRC_Y, DRMMODE_PLANE_SRC_Y,
@ -198,6 +199,7 @@ typedef struct {
drmmode_mode_ptr current_mode; drmmode_mode_ptr current_mode;
uint32_t num_formats; uint32_t num_formats;
drmmode_format_rec *formats; drmmode_format_rec *formats;
drmmode_format_rec *formats_async;
drmmode_bo rotate_bo; drmmode_bo rotate_bo;
unsigned rotate_fb_id; unsigned rotate_fb_id;
@ -293,7 +295,7 @@ typedef struct _msSpritePriv {
extern miPointerSpriteFuncRec drmmode_sprite_funcs; extern miPointerSpriteFuncRec drmmode_sprite_funcs;
Bool drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format, Bool drmmode_is_format_supported(ScrnInfoPtr scrn, uint32_t format,
uint64_t modifier); uint64_t modifier, Bool async_flip);
int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo, int drmmode_bo_import(drmmode_ptr drmmode, drmmode_bo *bo,
uint32_t *fb_id); uint32_t *fb_id);
int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo); int drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo);

View File

@ -294,7 +294,7 @@ ms_present_check_unflip(RRCrtcPtr crtc,
modifier = gbm_bo_get_modifier(gbm); modifier = gbm_bo_get_modifier(gbm);
gbm_bo_destroy(gbm); gbm_bo_destroy(gbm);
if (!drmmode_is_format_supported(scrn, format, modifier)) { if (!drmmode_is_format_supported(scrn, format, modifier, FALSE)) {
if (reason) if (reason)
*reason = PRESENT_FLIP_REASON_BUFFER_FORMAT; *reason = PRESENT_FLIP_REASON_BUFFER_FORMAT;
return FALSE; return FALSE;