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 <[email protected]> --- 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
