Re: [Mesa-dev] [PATCH 04/10] egl: add EGL_ANDROID_native_fence_sync
On Fri 18 Nov 2016, Rob Clark wrote: > From: Rob Clark> > With fixes from Chad squashed in, plus fixes for issues that Rafael > found while writing piglit tests. > > Cc: Chad Versace > Cc: Rafael Antognolli > Signed-off-by: Rob Clark > --- > 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(-) > @@ -1630,6 +1631,10 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const > EGLAttrib *attrib_list, A small fix is needed here, in _eglCreateSync above the switch statement, to avoid a segfault in Rafael's Piglit test 'eglCreateSyncKHR_native_no_current_context'. Credit goes to Rafael, who has this hunk as a fixup patch in his tree. /* If type is EGL_SYNC_FENCE and no context is current for the bound API * (i.e., eglGetCurrentContext returns EGL_NO_CONTEXT ), an EGL_BAD_MATCH * error is generated. */ - if (!ctx && type == EGL_SYNC_FENCE_KHR) + if (!ctx && + (type == EGL_SYNC_FENCE_KHR || type == EGL_SYNC_NATIVE_FENCE_ANDROID)) RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR); [...] >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) Thanks for squashing my fixes in. With Rafael's hunk squashed in too, patch 4 is Reviewed-by: Chad Versace Tested-by: Chad Versace Rafael, I'll resubmit my i965 patches after ickle's kernel patches land in an upstream tree. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 04/10] egl: add EGL_ANDROID_native_fence_sync
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 AntognolliOn Fri, Nov 18, 2016 at 08:39:33AM -0500, Rob Clark wrote: > From: Rob Clark > > With fixes from Chad squashed in, plus fixes for issues that Rafael > found while writing piglit tests. > > Cc: Chad Versace > Cc: Rafael Antognolli > Signed-off-by: Rob Clark > --- > 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(_sync->refcount)) { > - if (dri2_sync->base.Type == EGL_SYNC_REUSABLE_KHR) > + switch (dri2_sync->base.Type) { > + case EGL_SYNC_REUSABLE_KHR: > cnd_destroy(_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(_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, >
[Mesa-dev] [PATCH 04/10] egl: add EGL_ANDROID_native_fence_sync
From: Rob ClarkWith fixes from Chad squashed in, plus fixes for issues that Rafael found while writing piglit tests. Cc: Chad Versace Cc: Rafael Antognolli Signed-off-by: Rob Clark --- 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(_sync->refcount)) { - if (dri2_sync->base.Type == EGL_SYNC_REUSABLE_KHR) + switch (dri2_sync->base.Type) { + case EGL_SYNC_REUSABLE_KHR: cnd_destroy(_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(_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