[RFC v2 10/12] modesetting: Check if DMA fences are supported
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Wed Sep 27 05:20:01 UTC 2017
Modesetting/glamor can handle DMA fences if extensions EGL_KHR_wait_sync and
EGL_ANDROID_native_fence_sync are available and if IN_FENCE_FD
and OUT_FENCE_PTR DRM properties are implemented.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
glamor/glamor.c | 16 ++++++++++++++
glamor/glamor.h | 16 ++++++++++++++
glamor/glamor_egl.c | 10 +++++++++
glamor/glamor_egl_ext.h | 28 ++++++++++++++++++++++++
glamor/glamor_priv.h | 1 +
hw/xfree86/drivers/modesetting/drmmode_display.c | 23 +++++++++++++++++++
hw/xfree86/drivers/modesetting/drmmode_display.h | 4 ++++
hw/xfree86/drivers/modesetting/present.c | 3 +++
8 files changed, 101 insertions(+)
diff --git a/glamor/glamor.c b/glamor/glamor.c
index eacc28759..35b3cbeed 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -804,6 +804,22 @@ glamor_supports_pixmap_import_export(ScreenPtr screen)
return glamor_priv->dri3_enabled;
}
+void
+glamor_enable_dma_fences(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ glamor_priv->dma_fences_enabled = TRUE;
+}
+
+Bool
+glamor_supports_dma_fences(ScreenPtr screen)
+{
+ glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
+
+ return glamor_priv->dma_fences_enabled;
+}
+
_X_EXPORT void
glamor_set_drawable_modifiers_func(ScreenPtr screen,
GetDrawableModifiersFuncPtr func)
diff --git a/glamor/glamor.h b/glamor/glamor.h
index 5475aedbb..600ccf98b 100644
--- a/glamor/glamor.h
+++ b/glamor/glamor.h
@@ -143,6 +143,7 @@ extern _X_EXPORT void glamor_pixmap_exchange_fbos(PixmapPtr front,
/* The DDX is not supposed to call these three functions */
extern _X_EXPORT void glamor_enable_dri3(ScreenPtr screen);
+extern _X_EXPORT void glamor_enable_dma_fences(ScreenPtr screen);
extern _X_EXPORT int glamor_egl_fds_from_pixmap(ScreenPtr, PixmapPtr, int *,
uint32_t *, uint32_t *,
uint64_t *);
@@ -166,6 +167,21 @@ extern _X_EXPORT struct gbm_device *glamor_egl_get_gbm_device(ScreenPtr screen);
* */
extern _X_EXPORT Bool glamor_supports_pixmap_import_export(ScreenPtr screen);
+/* @glamor_supports_dma_fences: Returns Glamor can wait on
+ * DMA in-fences and create DMA out-fences.
+ *
+ * @screen: Current screen pointer.
+ *
+ * To have DMA fences support enabled, glamor and glamor_egl need
+ * to be initialized.
+ *
+ * The EGL layer needs to have the following extensions working:
+ *
+ * .EGL_ANDROID_native_fence_sync
+ * .EGL_KHR_wait_sync
+ * */
+extern _X_EXPORT Bool glamor_supports_dma_fences(ScreenPtr screen);
+
/* @glamor_fds_from_pixmap: Get a dma-buf fd from a pixmap.
*
* @screen: Current screen pointer.
diff --git a/glamor/glamor_egl.c b/glamor/glamor_egl.c
index 6626b577d..5ee972708 100644
--- a/glamor/glamor_egl.c
+++ b/glamor/glamor_egl.c
@@ -57,6 +57,7 @@ struct glamor_egl_screen_private {
int fd;
struct gbm_device *gbm;
int dmabuf_capable;
+ int dmafence_capable;
CloseScreenProcPtr saved_close_screen;
DestroyPixmapProcPtr saved_destroy_pixmap;
@@ -765,6 +766,9 @@ glamor_egl_screen_init(ScreenPtr screen, struct glamor_context *glamor_ctx)
*/
glamor_enable_dri3(screen);
+ if (glamor_egl->dmafence_capable)
+ glamor_enable_dma_fences(screen);
+
/* If the driver wants to do its own auth dance (e.g. Xwayland
* on pre-3.15 kernels that don't have render nodes and thus
* has the wayland compositor as a master), then it needs us
@@ -940,6 +944,12 @@ glamor_egl_init(ScrnInfoPtr scrn, int fd)
glamor_egl->dmabuf_capable = TRUE;
#endif
+ if (epoxy_has_egl_extension(glamor_egl->display,
+ "EGL_ANDROID_native_fence_sync") &&
+ epoxy_has_egl_extension(glamor_egl->display,
+ "EGL_KHR_wait_sync"))
+ glamor_egl->dmafence_capable = TRUE;
+
glamor_egl->saved_free_screen = scrn->FreeScreen;
scrn->FreeScreen = glamor_egl_free_screen;
return TRUE;
diff --git a/glamor/glamor_egl_ext.h b/glamor/glamor_egl_ext.h
index 436e52137..a8d29f9e7 100644
--- a/glamor/glamor_egl_ext.h
+++ b/glamor/glamor_egl_ext.h
@@ -62,4 +62,32 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dp
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers);
#endif
+/* Define tokens from EGL_KHR_fence_sync */
+#ifndef EGL_KHR_fence_sync
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+#ifdef KHRONOS_SUPPORT_INT64
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
+#define EGL_SYNC_CONDITION_KHR 0x30F8
+#define EGL_SYNC_FENCE_KHR 0x30F9
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif /* KHRONOS_SUPPORT_INT64 */
+#endif /* EGL_KHR_fence_sync */
+
+/* Define tokens from EGL_KHR_wait_sync */
+#ifndef EGL_KHR_wait_sync
+typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
+#endif /* EGL_KHR_wait_sync */
+
+/* Define tokens from EGL_ANDROID_native_fence_sync */
+#ifndef EGL_ANDROID_native_fence_sync
+#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
+#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
+#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
+#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
+typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+#endif /* EGL_ANDROID_native_fence_sync */
+
#endif /* GLAMOR_EGL_EXT_H */
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
index 0cbf92e9f..8296a0859 100644
--- a/glamor/glamor_priv.h
+++ b/glamor/glamor_priv.h
@@ -286,6 +286,7 @@ typedef struct glamor_screen_private {
int flags;
ScreenPtr screen;
int dri3_enabled;
+ int dma_fences_enabled;
Bool suppress_gl_out_of_memory_logging;
Bool logged_any_fbo_allocation_failure;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 92091e204..8db516754 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1760,6 +1760,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
},
[DRMMODE_PLANE_FB_ID] = { .name = "FB_ID", },
[DRMMODE_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
+ [DRMMODE_PLANE_IN_FENCE_FD] = { .name = "IN_FENCE_FD", },
[DRMMODE_PLANE_IN_FORMATS] = { .name = "IN_FORMATS", },
[DRMMODE_PLANE_SRC_X] = { .name = "SRC_X", },
[DRMMODE_PLANE_SRC_Y] = { .name = "SRC_Y", },
@@ -1875,6 +1876,27 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
}
#endif
+Bool
+drmmode_support_dma_fences(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ if (!crtc->enabled)
+ continue;
+
+ if (drmmode_crtc->props_plane[DRMMODE_PLANE_IN_FENCE_FD].prop_id == 0 ||
+ drmmode_crtc->props[DRMMODE_CRTC_OUT_FENCE_PTR].prop_id == 0)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static unsigned int
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
{
@@ -1886,6 +1908,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
static const drmmode_prop_info_rec crtc_props[] = {
[DRMMODE_CRTC_ACTIVE] = { .name = "ACTIVE" },
[DRMMODE_CRTC_MODE_ID] = { .name = "MODE_ID" },
+ [DRMMODE_CRTC_OUT_FENCE_PTR] = { .name = "OUT_FENCE_PTR" },
};
#endif
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index b80f98765..8a6698e0d 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -39,6 +39,7 @@ struct gbm_device;
enum drmmode_plane_property {
DRMMODE_PLANE_TYPE = 0,
DRMMODE_PLANE_FB_ID,
+ DRMMODE_PLANE_IN_FENCE_FD,
DRMMODE_PLANE_IN_FORMATS,
DRMMODE_PLANE_CRTC_ID,
DRMMODE_PLANE_SRC_X,
@@ -70,6 +71,7 @@ enum drmmode_connector_property {
enum drmmode_crtc_property {
DRMMODE_CRTC_ACTIVE,
DRMMODE_CRTC_MODE_ID,
+ DRMMODE_CRTC_OUT_FENCE_PTR,
DRMMODE_CRTC__COUNT
};
@@ -277,6 +279,8 @@ void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
int drmmode_crtc_set_fb(xf86CrtcPtr crtc, DisplayModePtr mode, uint32_t fb_id,
int x, int y, uint32_t flags, void *data);
+Bool drmmode_support_dma_fences(ScrnInfoPtr pScrn);
+
#ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
#define DRM_CAP_DUMB_PREFERRED_DEPTH 3
#endif
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 3946c1e26..af995adac 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -405,5 +405,8 @@ ms_present_screen_init(ScreenPtr screen)
if (ret == 0 && value == 1)
ms_present_screen_info.capabilities |= PresentCapabilityAsync;
+ if (drmmode_support_dma_fences(scrn) && glamor_supports_dma_fences(screen))
+ ms_present_screen_info.capabilities |= PresentCapabilityIdleFence;
+
return present_screen_init(screen, &ms_present_screen_info);
}
--
2.13.0
More information about the xorg-devel
mailing list