glsl: lower mediump temporaries to 16 bits except structures (v2)
[mesa.git] / src / mesa / main / externalobjects.c
index 3843c9492e912aeafc47774e8fbc812469e63078..777a5dd5acd0c799a570106a1be590d476347bd1 100644 (file)
 
 #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
@@ -90,6 +93,12 @@ _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
                   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;
@@ -118,6 +127,13 @@ GLboolean GLAPIENTRY
 _mesa_IsMemoryObjectEXT(GLuint memoryObject)
 {
    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);
 
@@ -134,6 +150,11 @@ _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
    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;
@@ -176,13 +197,19 @@ _mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
    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,
-                  "glMemoryObjectParameterivEXT(memoryObject is immutable");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
       return;
    }
 
@@ -199,8 +226,7 @@ _mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
    return;
 
 invalid_pname:
-   _mesa_error(ctx, GL_INVALID_ENUM,
-               "glMemoryObjectParameterivEXT(pname=0x%x)", pname);
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
 }
 
 void GLAPIENTRY
@@ -211,6 +237,13 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
    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;
@@ -228,8 +261,7 @@ _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
    return;
 
 invalid_pname:
-   _mesa_error(ctx, GL_INVALID_ENUM,
-               "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
 }
 
 static struct gl_memory_object *
@@ -268,6 +300,11 @@ texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
 
    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;
@@ -285,9 +322,29 @@ 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)
+                     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);
 }
 
 /**
@@ -304,6 +361,11 @@ texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
 
    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;
@@ -321,9 +383,29 @@ 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)
+                         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
@@ -350,7 +432,8 @@ _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
                                     GLuint64 offset)
 {
    texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
-                        fixedSampleLocations, memory, offset);
+                        fixedSampleLocations, memory, offset,
+                        "glTexStorageMem2DMultisampleEXT");
 }
 
 void GLAPIENTRY
@@ -379,7 +462,8 @@ _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
                                     GLuint64 offset)
 {
    texstorage_memory_ms(3, target, samples, internalFormat, width, height,
-                        depth, fixedSampleLocations, memory, offset);
+                        depth, fixedSampleLocations, memory, offset,
+                        "glTexStorageMem3DMultisampleEXT");
 }
 
 void GLAPIENTRY
@@ -406,7 +490,8 @@ _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
                                         GLuint64 offset)
 {
    texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
-                            1, fixedSampleLocations, memory, offset);
+                            1, fixedSampleLocations, memory, offset,
+                            "glTextureStorageMem2DMultisampleEXT");
 }
 
 void GLAPIENTRY
@@ -435,7 +520,8 @@ _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
                                         GLuint64 offset)
 {
    texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
-                            depth, fixedSampleLocations, memory, offset);
+                            depth, fixedSampleLocations, memory, offset,
+                            "glTextureStorageMem3DMultisampleEXT");
 }
 
 void GLAPIENTRY
@@ -462,22 +548,144 @@ _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;
+
+/**
+ * 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
@@ -485,7 +693,9 @@ _mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
                                  GLenum pname,
                                  const GLuint64 *params)
 {
+   const char *func = "glSemaphoreParameterui64vEXT";
 
+   semaphore_parameter_stub(func, pname);
 }
 
 void GLAPIENTRY
@@ -493,7 +703,9 @@ _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
                                     GLenum pname,
                                     GLuint64 *params)
 {
+   const char *func = "glGetSemaphoreParameterui64vEXT";
 
+   semaphore_parameter_stub(func, pname);
 }
 
 void GLAPIENTRY
@@ -504,7 +716,56 @@ _mesa_WaitSemaphoreEXT(GLuint semaphore,
                        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
@@ -515,7 +776,56 @@ _mesa_SignalSemaphoreEXT(GLuint semaphore,
                          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
@@ -526,9 +836,15 @@ _mesa_ImportMemoryFdEXT(GLuint memory,
 {
    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_VALUE, "glImportMemoryFdEXT(handleType=%u)",
-                  handleType);
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
       return;
    }
 
@@ -545,5 +861,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_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);
 }