[Mesa-dev] [PATCH 03/17] mesa: add support for semaphore object creation/import/delete
Andres Rodriguez
andresx7 at gmail.com
Thu Nov 2 03:57:06 UTC 2017
Used by EXT_semmaphore and EXT_semaphore_fd
Signed-off-by: Andres Rodriguez <andresx7 at 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;
+}
+
+/**
+ * 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);
--
2.9.3
More information about the mesa-dev
mailing list