* DEALINGS IN THE SOFTWARE.
*/
+#include "macros.h"
+#include "mtypes.h"
+#include "bufferobj.h"
+#include "context.h"
#include "externalobjects.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "glformats.h"
+#include "texstorage.h"
+#include "util/u_memory.h"
+
+/**
+ * Allocate and initialize a new memory object. But don't put it into the
+ * memory object hash table.
+ *
+ * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
+ * driver.
+ *
+ * \return pointer to new memory object.
+ */
+static struct gl_memory_object *
+_mesa_new_memory_object(struct gl_context *ctx, GLuint name)
+{
+ struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object);
+ if (!obj)
+ return NULL;
+
+ _mesa_initialize_memory_object(ctx, obj, name);
+ return obj;
+}
+
+/**
+ * Delete a memory object. Called via ctx->Driver.DeleteMemory().
+ * Not removed from hash table here.
+ */
+void
+_mesa_delete_memory_object(struct gl_context *ctx,
+ struct gl_memory_object *memObj)
+{
+ free(memObj);
+}
+
+void
+_mesa_init_memory_object_functions(struct dd_function_table *driver)
+{
+ driver->NewMemoryObject = _mesa_new_memory_object;
+ driver->DeleteMemoryObject = _mesa_delete_memory_object;
+}
+
+/**
+ * Initialize a buffer object to default values.
+ */
+void
+_mesa_initialize_memory_object(struct gl_context *ctx,
+ struct gl_memory_object *obj,
+ GLuint name)
+{
+ memset(obj, 0, sizeof(struct gl_memory_object));
+ obj->Name = name;
+ obj->Dedicated = GL_FALSE;
+}
void GLAPIENTRY
_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
{
-
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API)) {
+ _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
+ memoryObjects);
+ }
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDeleteMemoryObjectsEXT(unsupported)");
+ return;
+ }
+
+ if (n < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
+ return;
+ }
+
+ if (!memoryObjects)
+ return;
+
+ _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
+ for (GLint i = 0; i < n; i++) {
+ if (memoryObjects[i] > 0) {
+ struct gl_memory_object *delObj
+ = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
+
+ if (delObj) {
+ _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
+ memoryObjects[i]);
+ ctx->Driver.DeleteMemoryObject(ctx, delObj);
+ }
+ }
+ }
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
}
GLboolean GLAPIENTRY
_mesa_IsMemoryObjectEXT(GLuint memoryObject)
{
- return GL_FALSE;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glIsMemoryObjectEXT(unsupported)");
+ return GL_FALSE;
+ }
+
+ struct gl_memory_object *obj =
+ _mesa_lookup_memory_object(ctx, memoryObject);
+
+ return obj ? GL_TRUE : GL_FALSE;
}
void GLAPIENTRY
_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
{
-
+ GET_CURRENT_CONTEXT(ctx);
+
+ const char *func = "glCreateMemoryObjectsEXT";
+
+ if (MESA_VERBOSE & (VERBOSE_API))
+ _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _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 (!memoryObjects)
+ return;
+
+ _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
+ GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->MemoryObjects, n);
+ if (first) {
+ for (GLsizei i = 0; i < n; i++) {
+ struct gl_memory_object *memObj;
+
+ memoryObjects[i] = first + i;
+
+ /* allocate memory object */
+ memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
+ if (!memObj) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
+ return;
+ }
+
+ /* insert into hash table */
+ _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
+ memoryObjects[i],
+ memObj);
+ }
+ }
+
+ _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
}
void GLAPIENTRY
GLenum pname,
const GLint *params)
{
-
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_memory_object *memObj;
+
+ const char *func = "glMemoryObjectParameterivEXT";
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ memObj = _mesa_lookup_memory_object(ctx, memoryObject);
+ if (!memObj)
+ return;
+
+ if (memObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
+ return;
+ }
+
+ switch (pname) {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ memObj->Dedicated = (GLboolean) params[0];
+ break;
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ /* EXT_protected_textures not supported */
+ goto invalid_pname;
+ default:
+ goto invalid_pname;
+ }
+ return;
+
+invalid_pname:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
}
void GLAPIENTRY
GLenum pname,
GLint *params)
{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_memory_object *memObj;
+
+ const char *func = "glMemoryObjectParameterivEXT";
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ memObj = _mesa_lookup_memory_object(ctx, memoryObject);
+ if (!memObj)
+ return;
+
+ switch (pname) {
+ case GL_DEDICATED_MEMORY_OBJECT_EXT:
+ *params = (GLint) memObj->Dedicated;
+ break;
+ case GL_PROTECTED_MEMORY_OBJECT_EXT:
+ /* EXT_protected_textures not supported */
+ goto invalid_pname;
+ default:
+ goto invalid_pname;
+ }
+ return;
+
+invalid_pname:
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
+}
+
+static struct gl_memory_object *
+lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
+ const char* func)
+{
+ if (memory == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
+ return NULL;
+ }
+
+ struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
+ if (!memObj)
+ return NULL;
+
+ if (!memObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
+ func);
+ return NULL;
+ }
+
+ return memObj;
+}
+
+/**
+ * Helper used by _mesa_TexStorageMem1/2/3DEXT().
+ */
+static void
+texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLuint memory, GLuint64 offset,
+ const char *func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
+ levels, internalFormat,
+ width, height, depth, offset, false);
+}
+
+static void
+texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations,
+ GLuint memory, GLuint64 offset, const char* func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_get_current_tex_object(ctx, target);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
+ internalFormat, width, height, depth,
+ fixedSampleLocations, offset, func);
+}
+
+/**
+ * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
+ */
+static void
+texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLuint memory, GLuint64 offset,
+ const char *func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
+ levels, internalFormat,
+ width, height, depth, offset, true);
+}
+
+static void
+texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
+ GLenum internalFormat, GLsizei width, GLsizei height,
+ GLsizei depth, GLboolean fixedSampleLocations,
+ GLuint memory, GLuint64 offset, const char* func)
+{
+ struct gl_texture_object *texObj;
+ struct gl_memory_object *memObj;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_memory_object) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (!texObj)
+ return;
+
+ memObj = lookup_memory_object_err(ctx, memory, func);
+ if (!memObj)
+ return;
+
+ _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
+ samples, internalFormat, width, height,
+ depth, fixedSampleLocations, offset, func);
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texstorage_memory(2, target, levels, internalFormat, width, height, 1,
+ memory, offset, "glTexStorageMem2DEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
+ fixedSampleLocations, memory, offset,
+ "glTexStorageMem2DMultisampleEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texstorage_memory(3, target, levels, internalFormat, width, height, depth,
+ memory, offset, "glTexStorageMem3DEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texstorage_memory_ms(3, target, samples, internalFormat, width, height,
+ depth, fixedSampleLocations, memory, offset,
+ "glTexStorageMem3DMultisampleEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
+ memory, offset, "glTexureStorageMem2DEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
+ 1, fixedSampleLocations, memory, offset,
+ "glTextureStorageMem2DMultisampleEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texturestorage_memory(3, texture, levels, internalFormat, width, height,
+ depth, memory, offset, "glTextureStorageMem3DEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
+ depth, fixedSampleLocations, memory, offset,
+ "glTextureStorageMem3DMultisampleEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
-
+ texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
+ offset, "glTexStorageMem1DEXT");
}
void GLAPIENTRY
GLuint memory,
GLuint64 offset)
{
+ texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
+ 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
_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;
+}
+
+/**
+ * Helper that outputs the correct error status for parameter
+ * calls where no pnames are defined
+ */
+static void
+semaphore_parameter_stub(const char* func, GLenum pname)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.EXT_semaphore) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ /* EXT_semaphore and EXT_semaphore_fd define no parameters */
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
}
void GLAPIENTRY
GLenum pname,
const GLuint64 *params)
{
+ const char *func = "glSemaphoreParameterui64vEXT";
+ semaphore_parameter_stub(func, pname);
}
void GLAPIENTRY
GLenum pname,
GLuint64 *params)
{
+ const char *func = "glGetSemaphoreParameterui64vEXT";
+ semaphore_parameter_stub(func, pname);
}
void GLAPIENTRY
const GLuint *textures,
const GLenum *srcLayouts)
{
-
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_semaphore_object *semObj = NULL;
+ struct gl_buffer_object **bufObjs = NULL;
+ struct gl_texture_object **texObjs = NULL;
+
+ const char *func = "glWaitSemaphoreEXT";
+
+ if (!ctx->Extensions.EXT_semaphore) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
+ if (!semObj)
+ return;
+
+ FLUSH_VERTICES(ctx, 0);
+
+ bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
+ if (!bufObjs) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
+ func, numBufferBarriers);
+ goto end;
+ }
+
+ for (unsigned i = 0; i < numBufferBarriers; i++) {
+ bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
+ }
+
+ texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
+ if (!texObjs) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
+ func, numTextureBarriers);
+ goto end;
+ }
+
+ for (unsigned i = 0; i < numTextureBarriers; i++) {
+ texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
+ }
+
+ ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj,
+ numBufferBarriers, bufObjs,
+ numTextureBarriers, texObjs,
+ srcLayouts);
+
+end:
+ free(bufObjs);
+ free(texObjs);
}
void GLAPIENTRY
const GLuint *textures,
const GLenum *dstLayouts)
{
-
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_semaphore_object *semObj = NULL;
+ struct gl_buffer_object **bufObjs = NULL;
+ struct gl_texture_object **texObjs = NULL;
+
+ const char *func = "glSignalSemaphoreEXT";
+
+ if (!ctx->Extensions.EXT_semaphore) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
+ if (!semObj)
+ return;
+
+ FLUSH_VERTICES(ctx, 0);
+
+ bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
+ if (!bufObjs) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
+ func, numBufferBarriers);
+ goto end;
+ }
+
+ for (unsigned i = 0; i < numBufferBarriers; i++) {
+ bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
+ }
+
+ texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
+ if (!texObjs) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
+ func, numTextureBarriers);
+ goto end;
+ }
+
+ for (unsigned i = 0; i < numTextureBarriers; i++) {
+ texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
+ }
+
+ ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj,
+ numBufferBarriers, bufObjs,
+ numTextureBarriers, texObjs,
+ dstLayouts);
+
+end:
+ free(bufObjs);
+ free(texObjs);
}
void GLAPIENTRY
GLenum handleType,
GLint fd)
{
+ GET_CURRENT_CONTEXT(ctx);
+
+ const char *func = "glImportMemoryFdEXT";
+
+ if (!ctx->Extensions.EXT_memory_object_fd) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
+ return;
+ }
+ if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
+ return;
+ }
+
+ struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
+ if (!memObj)
+ return;
+
+ ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
+ memObj->Immutable = GL_TRUE;
}
void GLAPIENTRY
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_ENUM, "%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);
}