diff mbox

[RFC] Updated DRM plane handling patches

Message ID 20110721101554.77ca3134@jbarnes-desktop (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes July 21, 2011, 5:15 p.m. UTC
On Thu, 21 Jul 2011 19:15:24 +0900
Joonyoung Shim <dofmind@gmail.com> wrote:

> Hi,
> 
> 2011/6/16 Jesse Barnes <jbarnes@virtuousgeek.org>:
> > On Tue,  7 Jun 2011 13:07:38 -0700
> > Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> >
> >> This patchset updates the previous one, incorporating the feedback I
> >> received:
> >>   1) uses the v4l fourcc codes to communicate pixel format
> >>   2) adds a new addfb ioctl that takes a format
> >>   3) adds working SNB support for the new code
> >>
> >> Comments welcome.  I'll be pushing intel-gpu-tools testdisplay support
> >> for this shortly if people want to play around with it.  Next step is to
> >> incorporate it into X and Wayland to see if the API is rich enough for
> >> our needs.
> >
> > And here's a very early & hackish DDX patch for this code in case other
> > people want to test things out.  I still have to update it with the
> > scaling stuff we talked about and support various things (disabling
> > planes, controlling attributes, etc) but it's enough to get bits on the
> > screen at least.
> >
> 
> Could you share libdrm patch for drm plane?
> 

Sure, see below.  You'll also need to update the copy of the libdrm
headers from the patched sources.
diff mbox

Patch

diff --git a/include/drm/drm.h b/include/drm/drm.h
index cd384f2..bb2dea8 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -718,9 +718,10 @@  struct drm_get_cap {
 #define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb)
 #define DRM_IOCTL_MODE_MAP_DUMB    DRM_IOWR(0xB3, struct drm_mode_map_dumb)
 #define DRM_IOCTL_MODE_DESTROY_DUMB    DRM_IOWR(0xB4, struct drm_mode_destroy_dumb)
-#define DRM_IOCTL_MODE_GETOVERLAYRESOURCES DRM_IOWR(0xB5, struct drm_mode_get_overlay_res)
-#define DRM_IOCTL_MODE_GETOVERLAY	DRM_IOWR(0xB6, struct drm_mode_get_overlay)
-#define DRM_IOCTL_MODE_SETOVERLAY	DRM_IOWR(0xB7, struct drm_mode_set_overlay)
+#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_SETPLANE	DRM_IOWR(0xB7, struct drm_mode_set_plane)
+#define DRM_IOCTL_MODE_ADDFB2		DRM_IOWR(0xB8, struct drm_mode_fb_cmd2)
 
 /**
  * Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 349052a..4c5f01f 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -120,14 +120,9 @@  struct drm_mode_crtc {
 	struct drm_mode_modeinfo mode;
 };
 
-#define DRM_MODE_OVERLAY_FORMAT_YUV422		1 /* YUV 4:2:2 packed */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX101010	2 /* RGB 10bpc, ign. alpha */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX888		3 /* Standard x:8:8:8 RGB */
-#define DRM_MODE_OVERLAY_FORMAT_RGBX161616	4 /* x:16:16:16 float RGB */
-
-/* Overlays blend with or override other bits on the CRTC */
-struct drm_mode_set_overlay {
-	__u32 overlay_id;
+/* Planes blend with or override other bits on the CRTC */
+struct drm_mode_set_plane {
+	__u32 plane_id;
 	__u32 crtc_id;
 	__u32 fb_id; /* contains surface format type */
 
@@ -137,9 +132,9 @@  struct drm_mode_set_overlay {
 	/* FIXME: color key/mask, scaling, z-order, other? */
 };
 
-struct drm_mode_get_overlay {
+struct drm_mode_get_plane {
 	__u64 format_type_ptr;
-	__u32 overlay_id;
+	__u32 plane_id;
 
 	__u32 crtc_id;
 	__u32 fb_id;
@@ -154,9 +149,9 @@  struct drm_mode_get_overlay {
 };
 
 
-struct drm_mode_get_overlay_res {
-	__u64 overlay_id_ptr;
-	__u32 count_overlays;
+struct drm_mode_get_plane_res {
+	__u64 plane_id_ptr;
+	__u32 count_planes;
 };
 
 #define DRM_MODE_ENCODER_NONE	0
@@ -268,6 +263,18 @@  struct drm_mode_fb_cmd {
 	__u32 handle;
 };
 
+/* For addfb2 ioctl, contains format info */
+struct drm_mode_fb_cmd2 {
+	__u32 fb_id;
+	__u32 width, height;
+	__u32 pitch;
+	__u32 bpp;
+	__u32 depth;
+	__u32 pixel_format; /* fourcc code from videodev2.h */
+	/* driver specific handle */
+	__u32 handle;
+};
+
 #define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01
 #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02
 #define DRM_MODE_FB_DIRTY_FLAGS         0x03
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 0d268fc..cf62412 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -255,6 +255,28 @@  int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
 	return 0;
 }
 
+int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+		  uint32_t pixel_format, uint8_t depth, uint8_t bpp,
+		  uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id)
+{
+	struct drm_mode_fb_cmd2 f;
+	int ret;
+
+	f.width  = width;
+	f.height = height;
+	f.pitch  = pitch;
+	f.bpp    = bpp;
+	f.depth  = depth;
+	f.pixel_format = pixel_format;
+	f.handle = bo_handle;
+
+	if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f)))
+		return ret;
+
+	*buf_id = f.fb_id;
+	return 0;
+}
+
 int drmModeRmFB(int fd, uint32_t bufferId)
 {
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
@@ -806,3 +828,129 @@  int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
 
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
 }
+
+int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+		      uint32_t fb_id, uint32_t crtc_x, uint32_t crtc_y,
+		      uint32_t x, uint32_t y)
+
+{
+	struct drm_mode_set_plane s;
+
+	s.plane_id = plane_id;
+	s.crtc_id = crtc_id;
+	s.fb_id = fb_id;
+	s.crtc_x = crtc_x;
+	s.crtc_y = crtc_y;
+	s.x = x;
+	s.y = y;
+
+	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
+}
+
+
+drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+{
+	struct drm_mode_get_plane ovr, counts;
+	drmModePlanePtr r = 0;
+
+retry:
+	memset(&ovr, 0, sizeof(struct drm_mode_get_plane));
+	ovr.plane_id = plane_id;
+	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+		return 0;
+
+	counts = ovr;
+
+	if (ovr.count_format_types) {
+		ovr.format_type_ptr = VOID2U64(drmMalloc(ovr.count_format_types *
+							 sizeof(uint32_t)));
+		if (!ovr.format_type_ptr)
+			goto err_allocs;
+	}
+
+	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr))
+		goto err_allocs;
+
+	if (counts.count_format_types < ovr.count_format_types) {
+		drmFree(U642VOID(ovr.format_type_ptr));
+		goto retry;
+	}
+
+	if (!(r = drmMalloc(sizeof(*r))))
+		goto err_allocs;
+
+	r->count_formats = ovr.count_format_types;
+	r->plane_id = ovr.plane_id;
+	r->crtc_id = ovr.crtc_id;
+	r->fb_id = ovr.fb_id;
+	r->crtc_x = ovr.crtc_x;
+	r->crtc_y = ovr.crtc_y;
+	r->x = ovr.x;
+	r->y = ovr.y;
+	r->possible_crtcs = ovr.possible_crtcs;
+	r->gamma_size = ovr.gamma_size;
+	r->formats = drmAllocCpy(U642VOID(ovr.format_type_ptr),
+				 ovr.count_format_types, sizeof(uint32_t));
+	if (ovr.count_format_types && !r->formats) {
+		drmFree(r->formats);
+		r = 0;
+	}
+
+err_allocs:
+	drmFree(U642VOID(ovr.format_type_ptr));
+
+	return r;
+}
+
+void drmModeFreePlane(drmModePlanePtr ptr)
+{
+	if (!ptr)
+		return;
+
+	drmFree(ptr->formats);
+	drmFree(ptr);
+}
+
+drmModePlaneResPtr drmModeGetPlaneResources(int fd)
+{
+	struct drm_mode_get_plane_res res, counts;
+	drmModePlaneResPtr r = 0;
+
+retry:
+	memset(&res, 0, sizeof(struct drm_mode_get_plane_res));
+	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
+		return 0;
+
+	counts = res;
+
+	if (res.count_planes) {
+		res.plane_id_ptr = VOID2U64(drmMalloc(res.count_planes *
+							sizeof(uint32_t)));
+		if (!res.plane_id_ptr)
+			goto err_allocs;
+	}
+
+	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res))
+		goto err_allocs;
+
+	if (counts.count_planes < res.count_planes) {
+		drmFree(U642VOID(res.plane_id_ptr));
+		goto retry;
+	}
+
+	if (!(r = drmMalloc(sizeof(*r))))
+		goto err_allocs;
+
+	r->count_planes = res.count_planes;
+	r->planes = drmAllocCpy(U642VOID(res.plane_id_ptr),
+				  res.count_planes, sizeof(uint32_t));
+	if (res.count_planes && !r->planes) {
+		drmFree(r->planes);
+		r = 0;
+	}
+
+err_allocs:
+	drmFree(U642VOID(res.plane_id_ptr));
+
+	return r;
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index ee7c454..5d36ba5 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -33,6 +33,7 @@ 
  *
  */
 
+#include <linux/videodev2.h>
 #include <drm.h>
 
 /*
@@ -274,7 +275,25 @@  typedef struct _drmModeConnector {
 	uint32_t *encoders; /**< List of encoder ids */
 } drmModeConnector, *drmModeConnectorPtr;
 
+typedef struct _drmModePlane {
+	uint32_t count_formats;
+	uint32_t *formats;
+	uint32_t plane_id;
 
+	uint32_t crtc_id;
+	uint32_t fb_id;
+
+	uint32_t crtc_x, crtc_y;
+	uint32_t x, y;
+
+	uint32_t possible_crtcs;
+	uint32_t gamma_size;
+} drmModePlane, *drmModePlanePtr;
+
+typedef struct _drmModePlaneRes {
+	uint32_t count_planes;
+	uint32_t *planes;
+} drmModePlaneRes, *drmModePlaneResPtr;
 
 extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr );
 extern void drmModeFreeResources( drmModeResPtr ptr );
@@ -282,6 +301,7 @@  extern void drmModeFreeFB( drmModeFBPtr ptr );
 extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );
 extern void drmModeFreeConnector( drmModeConnectorPtr ptr );
 extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
+extern void drmModeFreePlane( drmModePlanePtr ptr );
 
 /**
  * Retrives all of the resources associated with a card.
@@ -303,6 +323,10 @@  extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
 extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
 			uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
 			uint32_t *buf_id);
+/* ...with a specific pixel format */
+extern int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+			 uint32_t pixel_format, uint8_t depth, uint8_t bpp,
+			 uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id);
 /**
  * Destroies the given framebuffer.
  */
@@ -386,3 +410,8 @@  extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
 			       uint16_t *red, uint16_t *green, uint16_t *blue);
 extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
 			   uint32_t flags, void *user_data);
+extern drmModePlaneResPtr drmModeGetPlaneResources(int fd);
+extern drmModePlanePtr drmModeGetPlane(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 crtc_x, uint32_t crtc_y,
+			     uint32_t x, uint32_t y);