mesa: add support for semaphore object creation/import/delete v3
Used by EXT_semmaphore and EXT_semaphore_fd v2: Removed unnecessary dummy callback initialization v3: Fixed attempting to free the DummySemaphoreObject Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com>
This commit is contained in:
parent
8e635f7d65
commit
67d5d08682
|
@ -1133,6 +1133,40 @@ struct dd_function_table {
|
||||||
struct gl_shader_program *shProg,
|
struct gl_shader_program *shProg,
|
||||||
struct gl_program *prog);
|
struct gl_program *prog);
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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);
|
||||||
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -545,22 +545,126 @@ _mesa_TextureStorageMem1DEXT(GLuint texture,
|
||||||
memory, offset, "glTextureStorageMem1DEXT");
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
if (semObj != &DummySemaphoreObject)
|
||||||
|
free(semObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
void GLAPIENTRY
|
||||||
_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
|
_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
|
void GLAPIENTRY
|
||||||
_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
|
_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
|
GLboolean GLAPIENTRY
|
||||||
_mesa_IsSemaphoreEXT(GLuint semaphore)
|
_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
|
void GLAPIENTRY
|
||||||
|
@ -634,5 +738,33 @@ _mesa_ImportSemaphoreFdEXT(GLuint semaphore,
|
||||||
GLenum handleType,
|
GLenum handleType,
|
||||||
GLint fd)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,26 @@ _mesa_lookup_memory_object_locked(struct gl_context *ctx, GLuint memory)
|
||||||
_mesa_HashLookupLocked(ctx->Shared->MemoryObjects, 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
|
extern void
|
||||||
_mesa_init_memory_object_functions(struct dd_function_table *driver);
|
_mesa_init_memory_object_functions(struct dd_function_table *driver);
|
||||||
|
|
||||||
|
@ -65,7 +85,16 @@ _mesa_initialize_memory_object(struct gl_context *ctx,
|
||||||
struct gl_memory_object *obj,
|
struct gl_memory_object *obj,
|
||||||
GLuint name);
|
GLuint name);
|
||||||
extern void
|
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_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
|
extern void GLAPIENTRY
|
||||||
_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
|
_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects);
|
||||||
|
|
|
@ -3339,6 +3339,9 @@ struct gl_shared_state
|
||||||
/** EXT_external_objects */
|
/** EXT_external_objects */
|
||||||
struct _mesa_HashTable *MemoryObjects;
|
struct _mesa_HashTable *MemoryObjects;
|
||||||
|
|
||||||
|
/** EXT_semaphore */
|
||||||
|
struct _mesa_HashTable *SemaphoreObjects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some context in this share group was affected by a disjoint
|
* Some context in this share group was affected by a disjoint
|
||||||
* operation. This operation can be anything that has effects on
|
* operation. This operation can be anything that has effects on
|
||||||
|
@ -4720,6 +4723,11 @@ struct gl_memory_object
|
||||||
GLboolean Dedicated; /**< import memory from a dedicated allocation */
|
GLboolean Dedicated; /**< import memory from a dedicated allocation */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct gl_semaphore_object
|
||||||
|
{
|
||||||
|
GLuint Name; /**< hash table ID/name */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mesa rendering context.
|
* Mesa rendering context.
|
||||||
*
|
*
|
||||||
|
|
|
@ -136,6 +136,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
|
||||||
_mesa_key_pointer_equal);
|
_mesa_key_pointer_equal);
|
||||||
|
|
||||||
shared->MemoryObjects = _mesa_NewHashTable();
|
shared->MemoryObjects = _mesa_NewHashTable();
|
||||||
|
shared->SemaphoreObjects = _mesa_NewHashTable();
|
||||||
|
|
||||||
return shared;
|
return shared;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -316,6 +318,16 @@ delete_memory_object_cb(GLuint id, void *data, void *userData)
|
||||||
ctx->Driver.DeleteMemoryObject(ctx, memObj);
|
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.
|
* 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);
|
_mesa_DeleteHashTable(shared->MemoryObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shared->SemaphoreObjects) {
|
||||||
|
_mesa_HashDeleteAll(shared->SemaphoreObjects, delete_semaphore_object_cb, ctx);
|
||||||
|
_mesa_DeleteHashTable(shared->SemaphoreObjects);
|
||||||
|
}
|
||||||
|
|
||||||
simple_mtx_destroy(&shared->Mutex);
|
simple_mtx_destroy(&shared->Mutex);
|
||||||
mtx_destroy(&shared->TexMutex);
|
mtx_destroy(&shared->TexMutex);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue