[03/17] mesa: add support for semaphore object creation/import/delete

Submitted by Andres Rodriguez on Nov. 2, 2017, 3:57 a.m.

Details

Message ID 20171102035720.6839-4-andresx7@gmail.com
State New
Headers show
Series "Add support for GL_EXT_semaphore" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Andres Rodriguez Nov. 2, 2017, 3:57 a.m.
Used by EXT_semmaphore and EXT_semaphore_fd

Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
---
 src/mesa/drivers/common/driverfuncs.c |   3 +
 src/mesa/main/dd.h                    |  34 +++++++
 src/mesa/main/externalobjects.c       | 161 +++++++++++++++++++++++++++++++++-
 src/mesa/main/externalobjects.h       |  34 ++++++-
 src/mesa/main/mtypes.h                |   7 ++
 src/mesa/main/shared.c                |  17 ++++
 6 files changed, 254 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index ddb4bb6..1ab1b5d 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -170,6 +170,9 @@  _mesa_init_driver_functions(struct dd_function_table *driver)
    /* memory objects */
    _mesa_init_memory_object_functions(driver);
 
+   /* semaphore objects */
+   _mesa_init_semaphore_object_functions(driver);
+
    driver->NewFramebuffer = _mesa_new_framebuffer;
    driver->NewRenderbuffer = _swrast_new_soft_renderbuffer;
    driver->MapRenderbuffer = _swrast_map_soft_renderbuffer;
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index da03b2e..b089219 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -1126,6 +1126,40 @@  struct dd_function_table {
                                 GLuint64 size,
                                 int fd);
    /*@}*/
+
+   /**
+    * \name GL_EXT_semaphore interface
+    */
+   /*@{*/
+  /**
+    * Called to allocate a new semaphore object. Drivers will usually
+    * allocate/return a subclass of gl_semaphore_object.
+    */
+   struct gl_semaphore_object * (*NewSemaphoreObject)(struct gl_context *ctx,
+                                                      GLuint name);
+   /**
+    * Called to delete/free a semaphore object. Drivers should free the
+    * object and any associated resources.
+    */
+   void (*DeleteSemaphoreObject)(struct gl_context *ctx,
+                                 struct gl_semaphore_object *semObj);
+   /*@}*/
+
+   /**
+    * \name GL_EXT_semaphore_fd interface
+    */
+   /*@{*/
+   /**
+    * Called to import a semaphore object. The caller relinquishes ownership
+    * of fd after the call returns.
+    *
+    * Accessing fd after ImportSemaphoreFd returns results in undefined
+    * behaviour. This is consistent with EXT_semaphore_fd.
+    */
+   void (*ImportSemaphoreFd)(struct gl_context *ctx,
+                                struct gl_semaphore_object *semObj,
+                                int fd);
+   /*@}*/
 };
 
 
diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c
index e70280c..30f5248 100644
--- a/src/mesa/main/externalobjects.c
+++ b/src/mesa/main/externalobjects.c
@@ -547,22 +547,153 @@  _mesa_TextureStorageMem1DEXT(GLuint texture,
                          memory, offset, "glTextureStorageMem1DEXT");
 }
 
+/**
+ * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
+ * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
+ */
+static struct gl_semaphore_object DummySemaphoreObject;
+
+
+/**
+ * Allocate and initialize a new semaphore object.  But don't put it into the
+ * semaphore object hash table.
+ *
+ * Called via ctx->Driver.NewSemaphoreObject, unless overridden by a device
+ * driver.
+ *
+ * \return pointer to new semaphore object.
+ */
+static struct gl_semaphore_object *
+_mesa_new_semaphore_object(struct gl_context *ctx, GLuint name)
+{
+   struct gl_semaphore_object *obj = MALLOC_STRUCT(gl_semaphore_object);
+   if (!obj)
+      return NULL;
+
+   _mesa_initialize_semaphore_object(ctx, obj, name);
+   return obj;
+}
+
+/**
+ * Delete a semaphore object.  Called via ctx->Driver.DeleteSemaphore().
+ * Not removed from hash table here.
+ */
+void
+_mesa_delete_semaphore_object(struct gl_context *ctx,
+                              struct gl_semaphore_object *semObj)
+{
+   free(semObj);
+}
+
+void
+_mesa_init_semaphore_object_functions(struct dd_function_table *driver)
+{
+   driver->NewSemaphoreObject = _mesa_new_semaphore_object;
+   driver->DeleteSemaphoreObject = _mesa_delete_semaphore_object;
+}
+
+/**
+ * Initialize a semaphore object to default values.
+ */
+void
+_mesa_initialize_semaphore_object(struct gl_context *ctx,
+                                  struct gl_semaphore_object *obj,
+                                  GLuint name)
+{
+   memset(obj, 0, sizeof(struct gl_semaphore_object));
+   obj->Name = name;
+}
+
 void GLAPIENTRY
 _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   const char *func = "glGenSemaphoresEXT";
+
+   if (MESA_VERBOSE & (VERBOSE_API))
+      _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores);
+
+   if (!ctx->Extensions.EXT_semaphore) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+      return;
+   }
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
+      return;
+   }
+
+   if (!semaphores)
+      return;
 
+   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
+   GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SemaphoreObjects, n);
+   if (first) {
+      for (GLsizei i = 0; i < n; i++) {
+         semaphores[i] = first + i;
+         _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects,
+                                semaphores[i], &DummySemaphoreObject);
+      }
+   }
+
+   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
 }
 
 void GLAPIENTRY
 _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   const char *func = "glDeleteSemaphoresEXT";
 
+   if (MESA_VERBOSE & (VERBOSE_API)) {
+      _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
+   }
+
+   if (!ctx->Extensions.EXT_semaphore) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+      return;
+   }
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
+      return;
+   }
+
+   if (!semaphores)
+      return;
+
+   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
+   for (GLint i = 0; i < n; i++) {
+      if (semaphores[i] > 0) {
+         struct gl_semaphore_object *delObj
+            = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]);
+
+         if (delObj) {
+            _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects,
+                                   semaphores[i]);
+            ctx->Driver.DeleteSemaphoreObject(ctx, delObj);
+         }
+      }
+   }
+   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
 }
 
 GLboolean GLAPIENTRY
 _mesa_IsSemaphoreEXT(GLuint semaphore)
 {
-   return GL_FALSE;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (!ctx->Extensions.EXT_semaphore) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)");
+      return GL_FALSE;
+   }
+
+   struct gl_semaphore_object *obj =
+      _mesa_lookup_semaphore_object(ctx, semaphore);
+
+   return obj ? GL_TRUE : GL_FALSE;
 }
 
 void GLAPIENTRY
@@ -636,5 +767,33 @@  _mesa_ImportSemaphoreFdEXT(GLuint semaphore,
                            GLenum handleType,
                            GLint fd)
 {
+   GET_CURRENT_CONTEXT(ctx);
+
+   const char *func = "glImportSemaphoreFdEXT";
+
+   if (!ctx->Extensions.EXT_semaphore_fd) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+      return;
+   }
+
+   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "%s(handleType=%u)", func, handleType);
+      return;
+   }
+
+   struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
+                                                                      semaphore);
+   if (!semObj)
+      return;
+
+   if (semObj == &DummySemaphoreObject) {
+      semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore);
+      if (!semObj) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
+         return;
+      }
+      _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj);
+   }
 
+   ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd);
 }
diff --git a/src/mesa/main/externalobjects.h b/src/mesa/main/externalobjects.h
index a9a12b8..f2139d4 100644
--- a/src/mesa/main/externalobjects.h
+++ b/src/mesa/main/externalobjects.h
@@ -57,6 +57,26 @@  _mesa_lookup_memory_object_locked(struct gl_context *ctx, GLuint memory)
       _mesa_HashLookupLocked(ctx->Shared->MemoryObjects, memory);
 }
 
+static inline struct gl_semaphore_object *
+_mesa_lookup_semaphore_object(struct gl_context *ctx, GLuint semaphore)
+{
+   if (!semaphore)
+      return NULL;
+
+   return (struct gl_semaphore_object *)
+      _mesa_HashLookup(ctx->Shared->SemaphoreObjects, semaphore);
+}
+
+static inline struct gl_semaphore_object *
+_mesa_lookup_semaphore_object_locked(struct gl_context *ctx, GLuint semaphore)
+{
+   if (!semaphore)
+      return NULL;
+
+   return (struct gl_semaphore_object *)
+      _mesa_HashLookupLocked(ctx->Shared->SemaphoreObjects, semaphore);
+}
+
 extern void
 _mesa_init_memory_object_functions(struct dd_function_table *driver);
 
@@ -65,7 +85,19 @@  _mesa_initialize_memory_object(struct gl_context *ctx,
                                struct gl_memory_object *obj,
                                GLuint name);
 extern void
-_mesa_delete_memory_object(struct gl_context *ctx, struct gl_memory_object *mo);
+_mesa_delete_memory_object(struct gl_context *ctx,
+                           struct gl_memory_object *semObj);
+
+extern void
+_mesa_init_semaphore_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_initialize_semaphore_object(struct gl_context *ctx,
+                                  struct gl_semaphore_object *obj,
+                                  GLuint name);
+extern void
+_mesa_delete_semaphore_object(struct gl_context *ctx,
+                              struct gl_semaphore_object *semObj);
 
 extern void GLAPIENTRY
 _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 2894243..ffbb83f 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -3289,6 +3289,8 @@  struct gl_shared_state
    /** EXT_external_objects */
    struct _mesa_HashTable *MemoryObjects;
 
+   /** EXT_semaphore */
+   struct _mesa_HashTable *SemaphoreObjects;
 };
 
 
@@ -4656,6 +4658,11 @@  struct gl_memory_object
    GLboolean Dedicated;    /**< import memory from a dedicated allocation */
 };
 
+struct gl_semaphore_object
+{
+   GLuint Name;            /**< hash table ID/name */
+};
+
 /**
  * Mesa rendering context.
  *
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index 53b8597..1234ab5 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -136,6 +136,8 @@  _mesa_alloc_shared_state(struct gl_context *ctx)
                                           _mesa_key_pointer_equal);
 
    shared->MemoryObjects = _mesa_NewHashTable();
+   shared->SemaphoreObjects = _mesa_NewHashTable();
+
    return shared;
 
 fail:
@@ -316,6 +318,16 @@  delete_memory_object_cb(GLuint id, void *data, void *userData)
    ctx->Driver.DeleteMemoryObject(ctx, memObj);
 }
 
+/**
+ * Callback for deleting a memory object.  Called by _mesa_HashDeleteAll().
+ */
+static void
+delete_semaphore_object_cb(GLuint id, void *data, void *userData)
+{
+   struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data;
+   struct gl_context *ctx = (struct gl_context *) userData;
+   ctx->Driver.DeleteSemaphoreObject(ctx, semObj);
+}
 
 /**
  * Deallocate a shared state object and all children structures.
@@ -435,6 +447,11 @@  free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared)
       _mesa_DeleteHashTable(shared->MemoryObjects);
    }
 
+   if (shared->SemaphoreObjects) {
+      _mesa_HashDeleteAll(shared->SemaphoreObjects, delete_semaphore_object_cb, ctx);
+      _mesa_DeleteHashTable(shared->SemaphoreObjects);
+   }
+
    mtx_destroy(&shared->Mutex);
    mtx_destroy(&shared->TexMutex);
 

Comments

On Thu, Nov 2, 2017 at 4:57 AM, Andres Rodriguez <andresx7@gmail.com> wrote:
> Used by EXT_semmaphore and EXT_semaphore_fd
>
> Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
> ---
>  src/mesa/drivers/common/driverfuncs.c |   3 +
>  src/mesa/main/dd.h                    |  34 +++++++
>  src/mesa/main/externalobjects.c       | 161 +++++++++++++++++++++++++++++++++-
>  src/mesa/main/externalobjects.h       |  34 ++++++-
>  src/mesa/main/mtypes.h                |   7 ++
>  src/mesa/main/shared.c                |  17 ++++
>  6 files changed, 254 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
> index ddb4bb6..1ab1b5d 100644
> --- a/src/mesa/drivers/common/driverfuncs.c
> +++ b/src/mesa/drivers/common/driverfuncs.c
> @@ -170,6 +170,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
>     /* memory objects */
>     _mesa_init_memory_object_functions(driver);
>
> +   /* semaphore objects */
> +   _mesa_init_semaphore_object_functions(driver);
> +
>     driver->NewFramebuffer = _mesa_new_framebuffer;
>     driver->NewRenderbuffer = _swrast_new_soft_renderbuffer;
>     driver->MapRenderbuffer = _swrast_map_soft_renderbuffer;
> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
> index da03b2e..b089219 100644
> --- a/src/mesa/main/dd.h
> +++ b/src/mesa/main/dd.h
> @@ -1126,6 +1126,40 @@ struct dd_function_table {
>                                  GLuint64 size,
>                                  int fd);
>     /*@}*/
> +
> +   /**
> +    * \name GL_EXT_semaphore interface
> +    */
> +   /*@{*/
> +  /**
> +    * Called to allocate a new semaphore object. Drivers will usually
> +    * allocate/return a subclass of gl_semaphore_object.
> +    */
> +   struct gl_semaphore_object * (*NewSemaphoreObject)(struct gl_context *ctx,
> +                                                      GLuint name);
> +   /**
> +    * Called to delete/free a semaphore object. Drivers should free the
> +    * object and any associated resources.
> +    */
> +   void (*DeleteSemaphoreObject)(struct gl_context *ctx,
> +                                 struct gl_semaphore_object *semObj);
> +   /*@}*/
> +
> +   /**
> +    * \name GL_EXT_semaphore_fd interface
> +    */
> +   /*@{*/
> +   /**
> +    * Called to import a semaphore object. The caller relinquishes ownership
> +    * of fd after the call returns.
> +    *
> +    * Accessing fd after ImportSemaphoreFd returns results in undefined
> +    * behaviour. This is consistent with EXT_semaphore_fd.
> +    */
> +   void (*ImportSemaphoreFd)(struct gl_context *ctx,
> +                                struct gl_semaphore_object *semObj,
> +                                int fd);
> +   /*@}*/
>  };
>
>
> diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c
> index e70280c..30f5248 100644
> --- a/src/mesa/main/externalobjects.c
> +++ b/src/mesa/main/externalobjects.c
> @@ -547,22 +547,153 @@ _mesa_TextureStorageMem1DEXT(GLuint texture,
>                           memory, offset, "glTextureStorageMem1DEXT");
>  }
>
> +/**
> + * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
> + * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
> + */
> +static struct gl_semaphore_object DummySemaphoreObject;
> +
> +
> +/**
> + * Allocate and initialize a new semaphore object.  But don't put it into the
> + * semaphore object hash table.
> + *
> + * Called via ctx->Driver.NewSemaphoreObject, unless overridden by a device
> + * driver.
> + *
> + * \return pointer to new semaphore object.
> + */
> +static struct gl_semaphore_object *
> +_mesa_new_semaphore_object(struct gl_context *ctx, GLuint name)
> +{
> +   struct gl_semaphore_object *obj = MALLOC_STRUCT(gl_semaphore_object);
> +   if (!obj)
> +      return NULL;
> +
> +   _mesa_initialize_semaphore_object(ctx, obj, name);
> +   return obj;
> +}
> +
> +/**
> + * Delete a semaphore object.  Called via ctx->Driver.DeleteSemaphore().
> + * Not removed from hash table here.
> + */
> +void
> +_mesa_delete_semaphore_object(struct gl_context *ctx,
> +                              struct gl_semaphore_object *semObj)
> +{
> +   free(semObj);
> +}
> +
> +void
> +_mesa_init_semaphore_object_functions(struct dd_function_table *driver)
> +{
> +   driver->NewSemaphoreObject = _mesa_new_semaphore_object;
> +   driver->DeleteSemaphoreObject = _mesa_delete_semaphore_object;

It's not necessary to set dummy callbacks. Keeping NULL is OK.

Marek