From: Michel Dänzer <michel.daen...@amd.com>

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---

The corresponding kernel changes have landed in Linus' tree.

 include/drm/drm.h      |  1 +
 include/drm/drm_mode.h | 39 ++++++++++++++++++++++++++++++++++++---
 xf86drmMode.c          | 16 ++++++++++++++++
 xf86drmMode.h          |  3 +++
 4 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/include/drm/drm.h b/include/drm/drm.h
index b4ebaa9..3c5181d 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -636,6 +636,7 @@ struct drm_gem_open {
 #define DRM_CAP_CURSOR_WIDTH           0x8
 #define DRM_CAP_CURSOR_HEIGHT          0x9
 #define DRM_CAP_ADDFB2_MODIFIERS       0x10
+#define DRM_CAP_PAGE_FLIP_TARGET       0x11

 /** DRM_IOCTL_GET_CAP ioctl argument type */
 struct drm_get_cap {
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 7a7856e..e15a74d 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -514,7 +514,13 @@ struct drm_color_lut {

 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
-#define DRM_MODE_PAGE_FLIP_FLAGS 
(DRM_MODE_PAGE_FLIP_EVENT|DRM_MODE_PAGE_FLIP_ASYNC)
+#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
+#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8
+#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \
+                                  DRM_MODE_PAGE_FLIP_TARGET_RELATIVE)
+#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \
+                                 DRM_MODE_PAGE_FLIP_ASYNC | \
+                                 DRM_MODE_PAGE_FLIP_TARGET)

 /*
  * Request a page flip on the specified crtc.
@@ -537,8 +543,7 @@ struct drm_color_lut {
  * 'as soon as possible', meaning that it not delay waiting for vblank.
  * This may cause tearing on the screen.
  *
- * The reserved field must be zero until we figure out something
- * clever to use it for.
+ * The reserved field must be zero.
  */

 struct drm_mode_crtc_page_flip {
@@ -549,6 +554,34 @@ struct drm_mode_crtc_page_flip {
        __u64 user_data;
 };

+/*
+ * Request a page flip on the specified crtc.
+ *
+ * Same as struct drm_mode_crtc_page_flip, but supports new flags and
+ * re-purposes the reserved field:
+ *
+ * The sequence field must be zero unless either of the
+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When
+ * the ABSOLUTE flag is specified, the sequence field denotes the absolute
+ * vblank sequence when the flip should take effect. When the RELATIVE
+ * flag is specified, the sequence field denotes the relative (to the
+ * current one when the ioctl is called) vblank sequence when the flip
+ * should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to
+ * make sure the vblank sequence before the target one has passed before
+ * calling this ioctl. The purpose of the
+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify
+ * the target for when code dealing with a page flip runs during a
+ * vertical blank period.
+ */
+
+struct drm_mode_crtc_page_flip_target {
+       __u32 crtc_id;
+       __u32 fb_id;
+       __u32 flags;
+       __u32 sequence;
+       __u64 user_data;
+};
+
 /* create a dumb scanout buffer */
 struct drm_mode_create_dumb {
        __u32 height;
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 228c6e4..fb22f68 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -948,6 +948,22 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t 
fb_id,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
 }

+int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
+                         uint32_t flags, void *user_data,
+                         uint32_t target_vblank)
+{
+       struct drm_mode_crtc_page_flip_target flip_target;
+
+       memclear(flip_target);
+       flip_target.fb_id = fb_id;
+       flip_target.crtc_id = crtc_id;
+       flip_target.user_data = VOID2U64(user_data);
+       flip_target.flags = flags;
+       flip_target.sequence = target_vblank;
+
+       return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip_target);
+}
+
 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,
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 1a02fed..b684967 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -473,6 +473,9 @@ 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 int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
+                                uint32_t flags, void *user_data,
+                                uint32_t target_vblank);

 extern drmModePlaneResPtr drmModeGetPlaneResources(int fd);
 extern drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id);
-- 
2.9.3

Reply via email to