Message ID | 20161221001333.21941-1-hoegsberg@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 16-12-20 16:13:32, Kristian H. Kristensen wrote: >From: "Kristian H. Kristensen" <hoegsberg@chromium.org> > >This adds support for the new DRM_IOCTL_MODE_GETPLANE2 ioctl. For older >kernels drmModeGetPlane2() falls back to DRM_IOCTL_MODE_GETPLANE and >return the new, bigger drmModePlaneRec, reporting 0 modifiers. > >BUG=chrome-os-partner:56407 >TEST=modetest with next commit reports modifiers > >Change-Id: I9cf9979c0b72933bad661fd03b9beebb36120dfd >--- > include/drm/drm.h | 1 + > include/drm/drm_mode.h | 27 +++++++++++++++++++++++++++ > xf86drmMode.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- > xf86drmMode.h | 4 ++++ > 4 files changed, 76 insertions(+), 5 deletions(-) > >diff --git a/include/drm/drm.h b/include/drm/drm.h >index f6fd5c2..09d4262 100644 >--- a/include/drm/drm.h >+++ b/include/drm/drm.h >@@ -799,6 +799,7 @@ extern "C" { > #define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) > #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) > #define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) >+#define DRM_IOCTL_MODE_GETPLANE2 DRM_IOWR(0xB6, struct drm_mode_get_plane2) > #define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) > #define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) > #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) >diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h >index df0e350..ce773fa 100644 >--- a/include/drm/drm_mode.h >+++ b/include/drm/drm_mode.h >@@ -193,6 +193,33 @@ struct drm_mode_get_plane { > __u64 format_type_ptr; > }; > >+struct drm_format_modifier { >+ /* Bitmask of formats in get_plane format list this info >+ * applies to. */ >+ __u64 formats; >+ >+ /* This modifier can be used with the format for this plane. */ >+ __u64 modifier; >+}; >+ >+struct drm_mode_get_plane2 { >+ __u32 plane_id; >+ >+ __u32 crtc_id; >+ __u32 fb_id; >+ >+ __u32 possible_crtcs; >+ __u32 gamma_size; >+ >+ __u32 count_format_types; >+ __u64 format_type_ptr; >+ >+ /* New in v2 */ >+ __u32 count_format_modifiers; >+ __u32 flags; >+ __u64 format_modifier_ptr; >+}; >+ > struct drm_mode_get_plane_res { > __u64 plane_id_ptr; > __u32 count_planes; >diff --git a/xf86drmMode.c b/xf86drmMode.c >index fb22f68..298d502 100644 >--- a/xf86drmMode.c >+++ b/xf86drmMode.c >@@ -990,15 +990,15 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, > return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); > } > >-drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) >+static drmModePlanePtr get_plane(unsigned long cmd, int fd, uint32_t plane_id) > { >- struct drm_mode_get_plane ovr, counts; >+ struct drm_mode_get_plane2 ovr, counts; > drmModePlanePtr r = 0; > > retry: > memclear(ovr); > ovr.plane_id = plane_id; >- if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) >+ if (drmIoctl(fd, cmd, &ovr)) > return 0; > > counts = ovr; >@@ -1010,11 +1010,21 @@ retry: > goto err_allocs; > } > >- if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) >+ if (ovr.count_format_modifiers) { >+ ovr.format_modifier_ptr = >+ VOID2U64(drmMalloc(ovr.count_format_modifiers * >+ sizeof(struct drm_format_modifier))); >+ if (!ovr.format_modifier_ptr) >+ goto err_allocs; >+ } >+ >+ if (drmIoctl(fd, cmd, &ovr)) > goto err_allocs; > >- if (counts.count_format_types < ovr.count_format_types) { >+ if (counts.count_format_types < ovr.count_format_types || >+ counts.count_format_modifiers < ovr.count_format_modifiers) { > drmFree(U642VOID(ovr.format_type_ptr)); >+ drmFree(U642VOID(ovr.format_modifier_ptr)); > goto retry; > } > >@@ -1022,6 +1032,7 @@ retry: > goto err_allocs; > > r->count_formats = ovr.count_format_types; >+ r->count_format_modifiers = ovr.count_format_modifiers; > r->plane_id = ovr.plane_id; > r->crtc_id = ovr.crtc_id; > r->fb_id = ovr.fb_id; >@@ -1033,20 +1044,48 @@ retry: > drmFree(r->formats); > drmFree(r); > r = 0; >+ goto err_allocs; >+ } >+ >+ r->format_modifiers = >+ drmAllocCpy(U642VOID(ovr.format_modifier_ptr), >+ ovr.count_format_modifiers, >+ sizeof(struct drm_format_modifier)); >+ if (ovr.count_format_modifiers && !r->format_modifiers) { >+ drmFree(r->formats); >+ drmFree(r); >+ r = 0; > } > > err_allocs: > drmFree(U642VOID(ovr.format_type_ptr)); >+ drmFree(U642VOID(ovr.format_modifier_ptr)); > > return r; > } > >+drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id) >+{ >+ drmModePlanePtr r = get_plane(DRM_IOCTL_MODE_GETPLANE2, fd, plane_id); >+ >+ if (r || errno != EINVAL) >+ return r; >+ >+ return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); >+} >+ IMO, it should be up to the client to fallback to drmModeGetPlane if DRM_IOCTL_MODE_GETPLANE2 doesn't exist. However, as long as the modifiers are returned as 0, it should work fine. Reviewed-by: Ben Widawsky <ben@bwidawsk.net> >+drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) >+{ >+ return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); >+} >+ > void drmModeFreePlane(drmModePlanePtr ptr) > { > if (!ptr) > return; > > drmFree(ptr->formats); >+ drmFree(ptr->format_modifiers); > drmFree(ptr); > } > >diff --git a/xf86drmMode.h b/xf86drmMode.h >index b684967..044f38e 100644 >--- a/xf86drmMode.h >+++ b/xf86drmMode.h >@@ -328,6 +328,9 @@ typedef struct _drmModePlane { > > uint32_t possible_crtcs; > uint32_t gamma_size; >+ >+ uint32_t count_format_modifiers; >+ struct drm_format_modifier *format_modifiers; > } drmModePlane, *drmModePlanePtr; > > typedef struct _drmModePlaneRes { >@@ -479,6 +482,7 @@ extern int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id, > > extern drmModePlaneResPtr drmModeGetPlaneResources(int fd); > extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id); >+extern drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id); > extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, > uint32_t fb_id, uint32_t flags, > int32_t crtc_x, int32_t crtc_y, >-- >2.9.3 >
diff --git a/include/drm/drm.h b/include/drm/drm.h index f6fd5c2..09d4262 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -799,6 +799,7 @@ extern "C" { #define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) #define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) #define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) +#define DRM_IOCTL_MODE_GETPLANE2 DRM_IOWR(0xB6, struct drm_mode_get_plane2) #define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) #define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) #define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index df0e350..ce773fa 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -193,6 +193,33 @@ struct drm_mode_get_plane { __u64 format_type_ptr; }; +struct drm_format_modifier { + /* Bitmask of formats in get_plane format list this info + * applies to. */ + __u64 formats; + + /* This modifier can be used with the format for this plane. */ + __u64 modifier; +}; + +struct drm_mode_get_plane2 { + __u32 plane_id; + + __u32 crtc_id; + __u32 fb_id; + + __u32 possible_crtcs; + __u32 gamma_size; + + __u32 count_format_types; + __u64 format_type_ptr; + + /* New in v2 */ + __u32 count_format_modifiers; + __u32 flags; + __u64 format_modifier_ptr; +}; + struct drm_mode_get_plane_res { __u64 plane_id_ptr; __u32 count_planes; diff --git a/xf86drmMode.c b/xf86drmMode.c index fb22f68..298d502 100644 --- a/xf86drmMode.c +++ b/xf86drmMode.c @@ -990,15 +990,15 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); } -drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) +static drmModePlanePtr get_plane(unsigned long cmd, int fd, uint32_t plane_id) { - struct drm_mode_get_plane ovr, counts; + struct drm_mode_get_plane2 ovr, counts; drmModePlanePtr r = 0; retry: memclear(ovr); ovr.plane_id = plane_id; - if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) + if (drmIoctl(fd, cmd, &ovr)) return 0; counts = ovr; @@ -1010,11 +1010,21 @@ retry: goto err_allocs; } - if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) + if (ovr.count_format_modifiers) { + ovr.format_modifier_ptr = + VOID2U64(drmMalloc(ovr.count_format_modifiers * + sizeof(struct drm_format_modifier))); + if (!ovr.format_modifier_ptr) + goto err_allocs; + } + + if (drmIoctl(fd, cmd, &ovr)) goto err_allocs; - if (counts.count_format_types < ovr.count_format_types) { + if (counts.count_format_types < ovr.count_format_types || + counts.count_format_modifiers < ovr.count_format_modifiers) { drmFree(U642VOID(ovr.format_type_ptr)); + drmFree(U642VOID(ovr.format_modifier_ptr)); goto retry; } @@ -1022,6 +1032,7 @@ retry: goto err_allocs; r->count_formats = ovr.count_format_types; + r->count_format_modifiers = ovr.count_format_modifiers; r->plane_id = ovr.plane_id; r->crtc_id = ovr.crtc_id; r->fb_id = ovr.fb_id; @@ -1033,20 +1044,48 @@ retry: drmFree(r->formats); drmFree(r); r = 0; + goto err_allocs; + } + + r->format_modifiers = + drmAllocCpy(U642VOID(ovr.format_modifier_ptr), + ovr.count_format_modifiers, + sizeof(struct drm_format_modifier)); + if (ovr.count_format_modifiers && !r->format_modifiers) { + drmFree(r->formats); + drmFree(r); + r = 0; } err_allocs: drmFree(U642VOID(ovr.format_type_ptr)); + drmFree(U642VOID(ovr.format_modifier_ptr)); return r; } +drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id) +{ + drmModePlanePtr r = get_plane(DRM_IOCTL_MODE_GETPLANE2, fd, plane_id); + + if (r || errno != EINVAL) + return r; + + return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); +} + +drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) +{ + return get_plane(DRM_IOCTL_MODE_GETPLANE, fd, plane_id); +} + void drmModeFreePlane(drmModePlanePtr ptr) { if (!ptr) return; drmFree(ptr->formats); + drmFree(ptr->format_modifiers); drmFree(ptr); } diff --git a/xf86drmMode.h b/xf86drmMode.h index b684967..044f38e 100644 --- a/xf86drmMode.h +++ b/xf86drmMode.h @@ -328,6 +328,9 @@ typedef struct _drmModePlane { uint32_t possible_crtcs; uint32_t gamma_size; + + uint32_t count_format_modifiers; + struct drm_format_modifier *format_modifiers; } drmModePlane, *drmModePlanePtr; typedef struct _drmModePlaneRes { @@ -479,6 +482,7 @@ extern int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id, extern drmModePlaneResPtr drmModeGetPlaneResources(int fd); extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id); +extern drmModePlanePtr drmModeGetPlane2(int fd, uint32_t plane_id); extern int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, int32_t crtc_x, int32_t crtc_y,
From: "Kristian H. Kristensen" <hoegsberg@chromium.org> This adds support for the new DRM_IOCTL_MODE_GETPLANE2 ioctl. For older kernels drmModeGetPlane2() falls back to DRM_IOCTL_MODE_GETPLANE and return the new, bigger drmModePlaneRec, reporting 0 modifiers. BUG=chrome-os-partner:56407 TEST=modetest with next commit reports modifiers Change-Id: I9cf9979c0b72933bad661fd03b9beebb36120dfd --- include/drm/drm.h | 1 + include/drm/drm_mode.h | 27 +++++++++++++++++++++++++++ xf86drmMode.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- xf86drmMode.h | 4 ++++ 4 files changed, 76 insertions(+), 5 deletions(-)