The first 4 patches of this series at least (including this one) work well on i915 when combined with the pending i915 patches for mesa, libdrm and kernel.
Tested-by: Rafael Antognolli <rafael.antogno...@intel.com> On Fri, Nov 18, 2016 at 08:39:33AM -0500, Rob Clark wrote: > From: Rob Clark <robcl...@freedesktop.org> > > With fixes from Chad squashed in, plus fixes for issues that Rafael > found while writing piglit tests. > > Cc: Chad Versace <chadvers...@chromium.org> > Cc: Rafael Antognolli <rafael.antogno...@intel.com> > Signed-off-by: Rob Clark <robcl...@freedesktop.org> > --- > src/egl/drivers/dri2/egl_dri2.c | 58 > ++++++++++++++++++++++++++++++++++++++++- > src/egl/main/eglapi.c | 38 ++++++++++++++++++++++++--- > src/egl/main/eglapi.h | 2 ++ > src/egl/main/egldisplay.h | 1 + > src/egl/main/eglfallbacks.c | 1 + > src/egl/main/eglsync.c | 22 ++++++++++++++-- > src/egl/main/eglsync.h | 1 + > 7 files changed, 117 insertions(+), 6 deletions(-) > > diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c > index f18e9fb..52fbdff 100644 > --- a/src/egl/drivers/dri2/egl_dri2.c > +++ b/src/egl/drivers/dri2/egl_dri2.c > @@ -658,6 +658,12 @@ dri2_setup_screen(_EGLDisplay *disp) > disp->Extensions.KHR_wait_sync = EGL_TRUE; > if (dri2_dpy->fence->get_fence_from_cl_event) > disp->Extensions.KHR_cl_event2 = EGL_TRUE; > + if (dri2_dpy->fence->base.version >= 2) { > + unsigned capabilities = > + dri2_dpy->fence->get_capabilities(dri2_dpy->dri_screen); > + disp->Extensions.ANDROID_native_fence_sync = > + (capabilities & __DRI_FENCE_CAP_NATIVE_FD) != 0; > + } > } > > disp->Extensions.KHR_reusable_sync = EGL_TRUE; > @@ -2511,8 +2517,17 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, > struct dri2_egl_sync *dri2_sync) > { > if (p_atomic_dec_zero(&dri2_sync->refcount)) { > - if (dri2_sync->base.Type == EGL_SYNC_REUSABLE_KHR) > + switch (dri2_sync->base.Type) { > + case EGL_SYNC_REUSABLE_KHR: > cnd_destroy(&dri2_sync->cond); > + break; > + case EGL_SYNC_NATIVE_FENCE_ANDROID: > + if (dri2_sync->base.SyncFd != EGL_NO_NATIVE_FENCE_FD_ANDROID) > + close(dri2_sync->base.SyncFd); > + break; > + default: > + break; > + } > > if (dri2_sync->fence) > dri2_dpy->fence->destroy_fence(dri2_dpy->dri_screen, > dri2_sync->fence); > @@ -2603,6 +2618,19 @@ dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, > /* initial status of reusable sync must be "unsignaled" */ > dri2_sync->base.SyncStatus = EGL_UNSIGNALED_KHR; > break; > + > + case EGL_SYNC_NATIVE_FENCE_ANDROID: > + if (dri2_dpy->fence->create_fence_fd) { > + dri2_sync->fence = dri2_dpy->fence->create_fence_fd( > + dri2_ctx->dri_context, > + dri2_sync->base.SyncFd); > + } > + if (!dri2_sync->fence) { > + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); > + free(dri2_sync); > + return NULL; > + } > + break; > } > > p_atomic_set(&dri2_sync->refcount, 1); > @@ -2632,12 +2660,38 @@ dri2_destroy_sync(_EGLDriver *drv, _EGLDisplay *dpy, > _EGLSync *sync) > ret = EGL_FALSE; > } > } > + > dri2_egl_unref_sync(dri2_dpy, dri2_sync); > > return ret; > } > > static EGLint > +dri2_dup_native_fence_fd(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync) > +{ > + struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); > + struct dri2_egl_sync *dri2_sync = dri2_egl_sync(sync); > + > + assert(sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID); > + > + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { > + /* try to retrieve the actual native fence fd.. if rendering is > + * not flushed this will just return -1, aka NO_NATIVE_FENCE_FD: > + */ > + sync->SyncFd = dri2_dpy->fence->get_fence_fd(dri2_dpy->dri_screen, > + dri2_sync->fence); > + } > + > + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { > + /* if native fence fd still not created, return an error: */ > + _eglError(EGL_BAD_PARAMETER, "eglDupNativeFenceFDANDROID"); > + return EGL_NO_NATIVE_FENCE_FD_ANDROID; > + } > + > + return dup(sync->SyncFd); > +} > + > +static EGLint > dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, > EGLint flags, EGLTime timeout) > { > @@ -2667,6 +2721,7 @@ dri2_client_wait_sync(_EGLDriver *drv, _EGLDisplay > *dpy, _EGLSync *sync, > > switch (sync->Type) { > case EGL_SYNC_FENCE_KHR: > + case EGL_SYNC_NATIVE_FENCE_ANDROID: > case EGL_SYNC_CL_EVENT_KHR: > if (dri2_dpy->fence->client_wait_sync(dri2_ctx ? dri2_ctx->dri_context > : NULL, > dri2_sync->fence, wait_flags, > @@ -2922,6 +2977,7 @@ _eglBuiltInDriverDRI2(const char *args) > dri2_drv->base.API.DestroySyncKHR = dri2_destroy_sync; > dri2_drv->base.API.GLInteropQueryDeviceInfo = > dri2_interop_query_device_info; > dri2_drv->base.API.GLInteropExportObject = dri2_interop_export_object; > + dri2_drv->base.API.DupNativeFenceFDANDROID = dri2_dup_native_fence_fd; > > dri2_drv->base.Name = "DRI2"; > dri2_drv->base.Unload = dri2_unload; > diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c > index 4a44315..a13130f 100644 > --- a/src/egl/main/eglapi.c > +++ b/src/egl/main/eglapi.c > @@ -474,6 +474,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) > /* Please keep these sorted alphabetically. */ > _EGL_CHECK_EXTENSION(ANDROID_framebuffer_target); > _EGL_CHECK_EXTENSION(ANDROID_image_native_buffer); > + _EGL_CHECK_EXTENSION(ANDROID_native_fence_sync); > _EGL_CHECK_EXTENSION(ANDROID_recordable); > > _EGL_CHECK_EXTENSION(CHROMIUM_sync_control); > @@ -1630,6 +1631,10 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const > EGLAttrib *attrib_list, > if (!disp->Extensions.KHR_cl_event2) > RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); > break; > + case EGL_SYNC_NATIVE_FENCE_ANDROID: > + if (!disp->Extensions.ANDROID_native_fence_sync) > + RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); > + break; > default: > RETURN_EGL_ERROR(disp, invalid_type_error, EGL_NO_SYNC_KHR); > } > @@ -1702,7 +1707,8 @@ eglDestroySync(EGLDisplay dpy, EGLSync sync) > > _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); > assert(disp->Extensions.KHR_reusable_sync || > - disp->Extensions.KHR_fence_sync); > + disp->Extensions.KHR_fence_sync || > + disp->Extensions.ANDROID_native_fence_sync); > > _eglUnlinkSync(s); > ret = drv->API.DestroySyncKHR(drv, disp, s); > @@ -1723,7 +1729,8 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint > flags, EGLTime timeout) > > _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); > assert(disp->Extensions.KHR_reusable_sync || > - disp->Extensions.KHR_fence_sync); > + disp->Extensions.KHR_fence_sync || > + disp->Extensions.ANDROID_native_fence_sync); > > if (s->SyncStatus == EGL_SIGNALED_KHR) > RETURN_EGL_EVAL(disp, EGL_CONDITION_SATISFIED_KHR); > @@ -1822,7 +1829,8 @@ _eglGetSyncAttribCommon(_EGLDisplay *disp, _EGLSync *s, > EGLint attribute, EGLAtt > > _EGL_CHECK_SYNC(disp, s, EGL_FALSE, drv); > assert(disp->Extensions.KHR_reusable_sync || > - disp->Extensions.KHR_fence_sync); > + disp->Extensions.KHR_fence_sync || > + disp->Extensions.ANDROID_native_fence_sync); > ret = drv->API.GetSyncAttrib(drv, disp, s, attribute, value); > > RETURN_EGL_EVAL(disp, ret); > @@ -1865,6 +1873,29 @@ eglGetSyncAttribKHR(EGLDisplay dpy, EGLSync sync, > EGLint attribute, EGLint *valu > return result; > } > > +static EGLint EGLAPIENTRY > +eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) > +{ > + _EGLDisplay *disp = _eglLockDisplay(dpy); > + _EGLSync *s = _eglLookupSync(sync, disp); > + _EGLDriver *drv; > + EGLBoolean ret; > + > + _EGL_FUNC_START(disp, EGL_OBJECT_SYNC_KHR, s, EGL_FALSE); > + > + /* the spec doesn't seem to specify what happens if the fence > + * type is not EGL_SYNC_NATIVE_FENCE_ANDROID, but this seems > + * sensible: > + */ > + if (!(s && (s->Type == EGL_SYNC_NATIVE_FENCE_ANDROID))) > + RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, > EGL_NO_NATIVE_FENCE_FD_ANDROID); > + > + _EGL_CHECK_SYNC(disp, s, EGL_NO_NATIVE_FENCE_FD_ANDROID, drv); > + assert(disp->Extensions.ANDROID_native_fence_sync); > + ret = drv->API.DupNativeFenceFDANDROID(drv, disp, s); > + > + RETURN_EGL_EVAL(disp, ret); > +} > > static EGLBoolean EGLAPIENTRY > eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface, > @@ -2340,6 +2371,7 @@ eglGetProcAddress(const char *procname) > { "eglLabelObjectKHR", (_EGLProc) eglLabelObjectKHR }, > { "eglDebugMessageControlKHR", (_EGLProc) eglDebugMessageControlKHR }, > { "eglQueryDebugKHR", (_EGLProc) eglQueryDebugKHR }, > + { "eglDupNativeFenceFDANDROID", (_EGLProc) eglDupNativeFenceFDANDROID > }, > { NULL, NULL } > }; > EGLint i; > diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h > index b9bcc8e..2dc89fc 100644 > --- a/src/egl/main/eglapi.h > +++ b/src/egl/main/eglapi.h > @@ -146,6 +146,8 @@ struct _egl_api > EGLBoolean (*GetSyncAttrib)(_EGLDriver *drv, _EGLDisplay *dpy, > _EGLSync *sync, EGLint attribute, > EGLAttrib *value); > + EGLint (*DupNativeFenceFDANDROID)(_EGLDriver *drv, _EGLDisplay *dpy, > + _EGLSync *sync); > > EGLBoolean (*SwapBuffersRegionNOK)(_EGLDriver *drv, _EGLDisplay *disp, > _EGLSurface *surf, EGLint numRects, > diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h > index 62d9a11..4e0d717 100644 > --- a/src/egl/main/egldisplay.h > +++ b/src/egl/main/egldisplay.h > @@ -94,6 +94,7 @@ struct _egl_extensions > /* Please keep these sorted alphabetically. */ > EGLBoolean ANDROID_framebuffer_target; > EGLBoolean ANDROID_image_native_buffer; > + EGLBoolean ANDROID_native_fence_sync; > EGLBoolean ANDROID_recordable; > > EGLBoolean CHROMIUM_sync_control; > diff --git a/src/egl/main/eglfallbacks.c b/src/egl/main/eglfallbacks.c > index d0fce8c..017d337 100644 > --- a/src/egl/main/eglfallbacks.c > +++ b/src/egl/main/eglfallbacks.c > @@ -92,6 +92,7 @@ _eglInitDriverFallbacks(_EGLDriver *drv) > drv->API.WaitSyncKHR = NULL; > drv->API.SignalSyncKHR = NULL; > drv->API.GetSyncAttrib = _eglGetSyncAttrib; > + drv->API.DupNativeFenceFDANDROID = NULL; > > drv->API.CreateDRMImageMESA = NULL; > drv->API.ExportDRMImageMESA = NULL; > diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c > index 7b2c882..cb931b8 100644 > --- a/src/egl/main/eglsync.c > +++ b/src/egl/main/eglsync.c > @@ -59,6 +59,14 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLAttrib > *attrib_list) > err = EGL_BAD_ATTRIBUTE; > } > break; > + case EGL_SYNC_NATIVE_FENCE_FD_ANDROID: > + if (sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID) { > + /* we take ownership of the native fd, so no dup(): */ > + sync->SyncFd = val; > + } else { > + err = EGL_BAD_ATTRIBUTE; > + } > + break; > default: > err = EGL_BAD_ATTRIBUTE; > break; > @@ -83,6 +91,7 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, > _eglInitResource(&sync->Resource, sizeof(*sync), dpy); > sync->Type = type; > sync->SyncStatus = EGL_UNSIGNALED_KHR; > + sync->SyncFd = EGL_NO_NATIVE_FENCE_FD_ANDROID; > > err = _eglParseSyncAttribList(sync, attrib_list); > > @@ -90,6 +99,12 @@ _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum > type, > case EGL_SYNC_CL_EVENT_KHR: > sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR; > break; > + case EGL_SYNC_NATIVE_FENCE_ANDROID: > + if (sync->SyncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) > + sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; > + else > + sync->SyncCondition = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; > + break; > default: > sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; > } > @@ -117,17 +132,20 @@ _eglGetSyncAttrib(_EGLDriver *drv, _EGLDisplay *dpy, > _EGLSync *sync, > if (sync->SyncStatus != EGL_SIGNALED_KHR && > (sync->Type == EGL_SYNC_FENCE_KHR || > sync->Type == EGL_SYNC_CL_EVENT_KHR || > - sync->Type == EGL_SYNC_REUSABLE_KHR)) > + sync->Type == EGL_SYNC_REUSABLE_KHR || > + sync->Type == EGL_SYNC_NATIVE_FENCE_ANDROID)) > drv->API.ClientWaitSyncKHR(drv, dpy, sync, 0, 0); > > *value = sync->SyncStatus; > break; > case EGL_SYNC_CONDITION_KHR: > if (sync->Type != EGL_SYNC_FENCE_KHR && > - sync->Type != EGL_SYNC_CL_EVENT_KHR) > + sync->Type != EGL_SYNC_CL_EVENT_KHR && > + sync->Type != EGL_SYNC_NATIVE_FENCE_ANDROID) > return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); > *value = sync->SyncCondition; > break; > + > default: > return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); > break; > diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h > index 83b6f72..5ac76f3 100644 > --- a/src/egl/main/eglsync.h > +++ b/src/egl/main/eglsync.h > @@ -48,6 +48,7 @@ struct _egl_sync > EGLenum SyncStatus; > EGLenum SyncCondition; > EGLAttrib CLEvent; > + EGLint SyncFd; > }; > > > -- > 2.7.4 > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev