From 290a3eb7507f7f2949753a77c425ed2bb6fd0dd1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 10 Apr 2015 13:16:30 +0200 Subject: [PATCH] egl/dri2: implement EGL_KHR_cl_event2 (v2) v2: fix the SYNC_CONDITION query --- src/egl/drivers/dri2/egl_dri2.c | 25 +++++++++++-- src/egl/main/eglapi.c | 30 ++++++++++++++-- src/egl/main/eglapi.h | 2 +- src/egl/main/egldisplay.h | 1 + src/egl/main/eglsync.c | 62 ++++++++++++++++++++++++++++++--- src/egl/main/eglsync.h | 3 +- 6 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index e096a7df282..34d6bfeefac 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -531,6 +531,8 @@ dri2_setup_screen(_EGLDisplay *disp) if (dri2_dpy->fence) { disp->Extensions.KHR_fence_sync = EGL_TRUE; 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->image) { @@ -2207,7 +2209,8 @@ dri2_egl_unref_sync(struct dri2_egl_display *dri2_dpy, static _EGLSync * dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, - EGLenum type, const EGLint *attrib_list) + EGLenum type, const EGLint *attrib_list, + const EGLAttribKHR *attrib_list64) { _EGLContext *ctx = _eglGetCurrentContext(); struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy); @@ -2220,7 +2223,8 @@ dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, return NULL; } - if (!_eglInitSync(&dri2_sync->base, dpy, type, attrib_list)) { + if (!_eglInitSync(&dri2_sync->base, dpy, type, attrib_list, + attrib_list64)) { free(dri2_sync); return NULL; } @@ -2229,6 +2233,23 @@ dri2_create_sync(_EGLDriver *drv, _EGLDisplay *dpy, case EGL_SYNC_FENCE_KHR: dri2_sync->fence = dri2_dpy->fence->create_fence(dri2_ctx->dri_context); break; + + case EGL_SYNC_CL_EVENT_KHR: + dri2_sync->fence = dri2_dpy->fence->get_fence_from_cl_event( + dri2_dpy->dri_screen, + dri2_sync->base.CLEvent); + /* this can only happen if the cl_event passed in is invalid. */ + if (!dri2_sync->fence) { + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + free(dri2_sync); + return NULL; + } + + /* the initial status must be "signaled" if the cl_event is signaled */ + if (dri2_dpy->fence->client_wait_sync(dri2_ctx->dri_context, + dri2_sync->fence, 0, 0)) + dri2_sync->base.SyncStatus = EGL_SIGNALED_KHR; + break; } p_atomic_set(&dri2_sync->refcount, 1); diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 65a730abb5e..ec41aa3f15b 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -407,6 +407,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy) _EGL_CHECK_EXTENSION(KHR_reusable_sync); _EGL_CHECK_EXTENSION(KHR_fence_sync); _EGL_CHECK_EXTENSION(KHR_wait_sync); + _EGL_CHECK_EXTENSION(KHR_cl_event2); _EGL_CHECK_EXTENSION(KHR_surfaceless_context); _EGL_CHECK_EXTENSION(KHR_create_context); @@ -1215,6 +1216,7 @@ eglGetProcAddress(const char *procname) { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR }, { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR }, { "eglCreateSyncKHR", (_EGLProc) eglCreateSyncKHR }, + { "eglCreateSync64KHR", (_EGLProc) eglCreateSync64KHR }, { "eglDestroySyncKHR", (_EGLProc) eglDestroySyncKHR }, { "eglClientWaitSyncKHR", (_EGLProc) eglClientWaitSyncKHR }, { "eglWaitSyncKHR", (_EGLProc) eglWaitSyncKHR }, @@ -1655,8 +1657,9 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) } -EGLSyncKHR EGLAPIENTRY -eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +static EGLSyncKHR +_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, + const EGLAttribKHR *attrib_list64, EGLBoolean is64) { _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); @@ -1666,6 +1669,9 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) _EGL_CHECK_DISPLAY(disp, EGL_NO_SYNC_KHR, drv); + if (!disp->Extensions.KHR_cl_event2 && is64) + RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR); + /* return an error if the client API doesn't support GL_OES_EGL_sync */ if (!ctx || ctx->Resource.Display != dpy || ctx->ClientAPI != EGL_OPENGL_ES_API) @@ -1680,17 +1686,35 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) if (!disp->Extensions.KHR_reusable_sync) RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); break; + case EGL_SYNC_CL_EVENT_KHR: + if (!disp->Extensions.KHR_cl_event2) + RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); + break; default: RETURN_EGL_ERROR(disp, EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); } - sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list); + sync = drv->API.CreateSyncKHR(drv, disp, type, attrib_list, attrib_list64); ret = (sync) ? _eglLinkSync(sync) : EGL_NO_SYNC_KHR; RETURN_EGL_EVAL(disp, ret); } +EGLSyncKHR EGLAPIENTRY +eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE); +} + + +EGLSyncKHR EGLAPIENTRY +eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list) +{ + return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE); +} + + EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) { diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index 7462b35d3ba..52268867382 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -102,7 +102,7 @@ typedef _EGLImage *(*CreateImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLCo typedef EGLBoolean (*DestroyImageKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *image); -typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list); +typedef _EGLSync *(*CreateSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum type, const EGLint *attrib_list, const EGLAttribKHR *attrib_list64); typedef EGLBoolean (*DestroySyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); typedef EGLint (*ClientWaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, EGLint flags, EGLTimeKHR timeout); typedef EGLint (*WaitSyncKHR_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync); diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 70381bcfe51..b6b9ed8e278 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -107,6 +107,7 @@ struct _egl_extensions EGLBoolean KHR_reusable_sync; EGLBoolean KHR_fence_sync; EGLBoolean KHR_wait_sync; + EGLBoolean KHR_cl_event2; EGLBoolean KHR_surfaceless_context; EGLBoolean KHR_create_context; diff --git a/src/egl/main/eglsync.c b/src/egl/main/eglsync.c index 9d0067caa2d..3b4a88902fd 100644 --- a/src/egl/main/eglsync.c +++ b/src/egl/main/eglsync.c @@ -65,25 +65,76 @@ _eglParseSyncAttribList(_EGLSync *sync, const EGLint *attrib_list) } +static EGLint +_eglParseSyncAttribList64(_EGLSync *sync, const EGLAttribKHR *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + + if (!attrib_list) + return EGL_SUCCESS; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + case EGL_CL_EVENT_HANDLE_KHR: + if (sync->Type == EGL_SYNC_CL_EVENT_KHR) { + sync->CLEvent = val; + break; + } + /* fall through */ + default: + (void) val; + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_DEBUG, "bad sync attribute 0x%04x", attr); + break; + } + } + + return err; +} + + EGLBoolean _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, - const EGLint *attrib_list) + const EGLint *attrib_list, const EGLAttribKHR *attrib_list64) { EGLint err; if (!(type == EGL_SYNC_REUSABLE_KHR && dpy->Extensions.KHR_reusable_sync) && - !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync)) + !(type == EGL_SYNC_FENCE_KHR && dpy->Extensions.KHR_fence_sync) && + !(type == EGL_SYNC_CL_EVENT_KHR && dpy->Extensions.KHR_cl_event2 && + attrib_list64)) return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); _eglInitResource(&sync->Resource, sizeof(*sync), dpy); sync->Type = type; sync->SyncStatus = EGL_UNSIGNALED_KHR; - sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; - err = _eglParseSyncAttribList(sync, attrib_list); + switch (type) { + case EGL_SYNC_CL_EVENT_KHR: + sync->SyncCondition = EGL_SYNC_CL_EVENT_COMPLETE_KHR; + break; + default: + sync->SyncCondition = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; + } + + if (attrib_list64) + err = _eglParseSyncAttribList64(sync, attrib_list64); + else + err = _eglParseSyncAttribList(sync, attrib_list); + if (err != EGL_SUCCESS) return _eglError(err, "eglCreateSyncKHR"); + if (type == EGL_SYNC_CL_EVENT_KHR && !sync->CLEvent) + return _eglError(EGL_BAD_ATTRIBUTE, "eglCreateSyncKHR"); + return EGL_TRUE; } @@ -103,7 +154,8 @@ _eglGetSyncAttribKHR(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, *value = sync->SyncStatus; break; case EGL_SYNC_CONDITION_KHR: - if (sync->Type != EGL_SYNC_FENCE_KHR) + if (sync->Type != EGL_SYNC_FENCE_KHR && + sync->Type != EGL_SYNC_CL_EVENT_KHR) return _eglError(EGL_BAD_ATTRIBUTE, "eglGetSyncAttribKHR"); *value = sync->SyncCondition; break; diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h index c6cf8c6479e..1d2eb11a7a0 100644 --- a/src/egl/main/eglsync.h +++ b/src/egl/main/eglsync.h @@ -47,12 +47,13 @@ struct _egl_sync EGLenum Type; EGLenum SyncStatus; EGLenum SyncCondition; + EGLAttribKHR CLEvent; }; extern EGLBoolean _eglInitSync(_EGLSync *sync, _EGLDisplay *dpy, EGLenum type, - const EGLint *attrib_list); + const EGLint *attrib_list, const EGLAttribKHR *attrib_list64); extern EGLBoolean -- 2.30.2