[Mesa-dev,06/10] egl/dri2: implement EGL_KHR_cl_event2

Submitted by Marek Olšák on April 14, 2015, 10:19 p.m.

Details

Message ID 1429049995-21768-7-git-send-email-maraeo@gmail.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Marek Olšák April 14, 2015, 10:19 p.m.
From: Marek Olšák <marek.olsak@amd.com>

---
 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          | 59 ++++++++++++++++++++++++++++++++++++++---
 src/egl/main/eglsync.h          |  3 ++-
 6 files changed, 109 insertions(+), 11 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index e096a7d..34d6bfe 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 aff2921..4cf5302 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 e689012..5ccdf58 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 70381bc..b6b9ed8 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 9d0067c..ae3af4f 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;
 }
 
diff --git a/src/egl/main/eglsync.h b/src/egl/main/eglsync.h
index c6cf8c6..1d2eb11 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