externalobjects.c revision 7ec681f3
101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2016 Red Hat.
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#include "macros.h"
2501e04c3fSmrg#include "mtypes.h"
2601e04c3fSmrg#include "bufferobj.h"
2701e04c3fSmrg#include "context.h"
2801e04c3fSmrg#include "externalobjects.h"
2901e04c3fSmrg#include "teximage.h"
3001e04c3fSmrg#include "texobj.h"
3101e04c3fSmrg#include "glformats.h"
3201e04c3fSmrg#include "texstorage.h"
337ec681f3Smrg#include "util/u_memory.h"
3401e04c3fSmrg
3501e04c3fSmrg/**
3601e04c3fSmrg * Allocate and initialize a new memory object.  But don't put it into the
3701e04c3fSmrg * memory object hash table.
3801e04c3fSmrg *
3901e04c3fSmrg * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
4001e04c3fSmrg * driver.
4101e04c3fSmrg *
4201e04c3fSmrg * \return pointer to new memory object.
4301e04c3fSmrg */
4401e04c3fSmrgstatic struct gl_memory_object *
4501e04c3fSmrg_mesa_new_memory_object(struct gl_context *ctx, GLuint name)
4601e04c3fSmrg{
4701e04c3fSmrg   struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object);
4801e04c3fSmrg   if (!obj)
4901e04c3fSmrg      return NULL;
5001e04c3fSmrg
5101e04c3fSmrg   _mesa_initialize_memory_object(ctx, obj, name);
5201e04c3fSmrg   return obj;
5301e04c3fSmrg}
5401e04c3fSmrg
5501e04c3fSmrg/**
5601e04c3fSmrg * Delete a memory object.  Called via ctx->Driver.DeleteMemory().
5701e04c3fSmrg * Not removed from hash table here.
5801e04c3fSmrg */
5901e04c3fSmrgvoid
6001e04c3fSmrg_mesa_delete_memory_object(struct gl_context *ctx,
6101e04c3fSmrg                           struct gl_memory_object *memObj)
6201e04c3fSmrg{
6301e04c3fSmrg   free(memObj);
6401e04c3fSmrg}
6501e04c3fSmrg
6601e04c3fSmrgvoid
6701e04c3fSmrg_mesa_init_memory_object_functions(struct dd_function_table *driver)
6801e04c3fSmrg{
6901e04c3fSmrg   driver->NewMemoryObject = _mesa_new_memory_object;
7001e04c3fSmrg   driver->DeleteMemoryObject = _mesa_delete_memory_object;
7101e04c3fSmrg}
7201e04c3fSmrg
7301e04c3fSmrg/**
7401e04c3fSmrg * Initialize a buffer object to default values.
7501e04c3fSmrg */
7601e04c3fSmrgvoid
7701e04c3fSmrg_mesa_initialize_memory_object(struct gl_context *ctx,
7801e04c3fSmrg                               struct gl_memory_object *obj,
7901e04c3fSmrg                               GLuint name)
8001e04c3fSmrg{
8101e04c3fSmrg   memset(obj, 0, sizeof(struct gl_memory_object));
8201e04c3fSmrg   obj->Name = name;
8301e04c3fSmrg   obj->Dedicated = GL_FALSE;
8401e04c3fSmrg}
8501e04c3fSmrg
8601e04c3fSmrgvoid GLAPIENTRY
8701e04c3fSmrg_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
8801e04c3fSmrg{
8901e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
9001e04c3fSmrg
9101e04c3fSmrg   if (MESA_VERBOSE & (VERBOSE_API)) {
9201e04c3fSmrg      _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
9301e04c3fSmrg                  memoryObjects);
9401e04c3fSmrg   }
9501e04c3fSmrg
9601e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
9701e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
9801e04c3fSmrg                  "glDeleteMemoryObjectsEXT(unsupported)");
9901e04c3fSmrg      return;
10001e04c3fSmrg   }
10101e04c3fSmrg
10201e04c3fSmrg   if (n < 0) {
10301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
10401e04c3fSmrg      return;
10501e04c3fSmrg   }
10601e04c3fSmrg
10701e04c3fSmrg   if (!memoryObjects)
10801e04c3fSmrg      return;
10901e04c3fSmrg
11001e04c3fSmrg   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
11101e04c3fSmrg   for (GLint i = 0; i < n; i++) {
11201e04c3fSmrg      if (memoryObjects[i] > 0) {
11301e04c3fSmrg         struct gl_memory_object *delObj
11401e04c3fSmrg            = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
11501e04c3fSmrg
11601e04c3fSmrg         if (delObj) {
11701e04c3fSmrg            _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
11801e04c3fSmrg                                   memoryObjects[i]);
11901e04c3fSmrg            ctx->Driver.DeleteMemoryObject(ctx, delObj);
12001e04c3fSmrg         }
12101e04c3fSmrg      }
12201e04c3fSmrg   }
12301e04c3fSmrg   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
12401e04c3fSmrg}
12501e04c3fSmrg
12601e04c3fSmrgGLboolean GLAPIENTRY
12701e04c3fSmrg_mesa_IsMemoryObjectEXT(GLuint memoryObject)
12801e04c3fSmrg{
12901e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
13001e04c3fSmrg
13101e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
13201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
13301e04c3fSmrg                  "glIsMemoryObjectEXT(unsupported)");
13401e04c3fSmrg      return GL_FALSE;
13501e04c3fSmrg   }
13601e04c3fSmrg
13701e04c3fSmrg   struct gl_memory_object *obj =
13801e04c3fSmrg      _mesa_lookup_memory_object(ctx, memoryObject);
13901e04c3fSmrg
14001e04c3fSmrg   return obj ? GL_TRUE : GL_FALSE;
14101e04c3fSmrg}
14201e04c3fSmrg
14301e04c3fSmrgvoid GLAPIENTRY
14401e04c3fSmrg_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
14501e04c3fSmrg{
14601e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
14701e04c3fSmrg
14801e04c3fSmrg   const char *func = "glCreateMemoryObjectsEXT";
14901e04c3fSmrg
15001e04c3fSmrg   if (MESA_VERBOSE & (VERBOSE_API))
15101e04c3fSmrg      _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
15201e04c3fSmrg
15301e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
15401e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
15501e04c3fSmrg      return;
15601e04c3fSmrg   }
15701e04c3fSmrg
15801e04c3fSmrg   if (n < 0) {
15901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
16001e04c3fSmrg      return;
16101e04c3fSmrg   }
16201e04c3fSmrg
16301e04c3fSmrg   if (!memoryObjects)
16401e04c3fSmrg      return;
16501e04c3fSmrg
16601e04c3fSmrg   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
1677ec681f3Smrg   if (_mesa_HashFindFreeKeys(ctx->Shared->MemoryObjects, memoryObjects, n)) {
16801e04c3fSmrg      for (GLsizei i = 0; i < n; i++) {
16901e04c3fSmrg         struct gl_memory_object *memObj;
17001e04c3fSmrg
17101e04c3fSmrg         /* allocate memory object */
17201e04c3fSmrg         memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
17301e04c3fSmrg         if (!memObj) {
17401e04c3fSmrg            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
17501e04c3fSmrg            _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
17601e04c3fSmrg            return;
17701e04c3fSmrg         }
17801e04c3fSmrg
17901e04c3fSmrg         /* insert into hash table */
18001e04c3fSmrg         _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
18101e04c3fSmrg                                memoryObjects[i],
1827ec681f3Smrg                                memObj, true);
18301e04c3fSmrg      }
18401e04c3fSmrg   }
18501e04c3fSmrg
18601e04c3fSmrg   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
18701e04c3fSmrg}
18801e04c3fSmrg
18901e04c3fSmrgvoid GLAPIENTRY
19001e04c3fSmrg_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
19101e04c3fSmrg                                 GLenum pname,
19201e04c3fSmrg                                 const GLint *params)
19301e04c3fSmrg{
19401e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
19501e04c3fSmrg   struct gl_memory_object *memObj;
19601e04c3fSmrg
19701e04c3fSmrg   const char *func = "glMemoryObjectParameterivEXT";
19801e04c3fSmrg
19901e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
20001e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
20101e04c3fSmrg      return;
20201e04c3fSmrg   }
20301e04c3fSmrg
20401e04c3fSmrg   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
20501e04c3fSmrg   if (!memObj)
20601e04c3fSmrg      return;
20701e04c3fSmrg
20801e04c3fSmrg   if (memObj->Immutable) {
20901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
21001e04c3fSmrg      return;
21101e04c3fSmrg   }
21201e04c3fSmrg
21301e04c3fSmrg   switch (pname) {
21401e04c3fSmrg   case GL_DEDICATED_MEMORY_OBJECT_EXT:
21501e04c3fSmrg      memObj->Dedicated = (GLboolean) params[0];
21601e04c3fSmrg      break;
21701e04c3fSmrg   case GL_PROTECTED_MEMORY_OBJECT_EXT:
21801e04c3fSmrg      /* EXT_protected_textures not supported */
21901e04c3fSmrg      goto invalid_pname;
22001e04c3fSmrg   default:
22101e04c3fSmrg      goto invalid_pname;
22201e04c3fSmrg   }
22301e04c3fSmrg   return;
22401e04c3fSmrg
22501e04c3fSmrginvalid_pname:
22601e04c3fSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
22701e04c3fSmrg}
22801e04c3fSmrg
22901e04c3fSmrgvoid GLAPIENTRY
23001e04c3fSmrg_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
23101e04c3fSmrg                                    GLenum pname,
23201e04c3fSmrg                                    GLint *params)
23301e04c3fSmrg{
23401e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
23501e04c3fSmrg   struct gl_memory_object *memObj;
23601e04c3fSmrg
23701e04c3fSmrg   const char *func = "glMemoryObjectParameterivEXT";
23801e04c3fSmrg
23901e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
24001e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
24101e04c3fSmrg      return;
24201e04c3fSmrg   }
24301e04c3fSmrg
24401e04c3fSmrg   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
24501e04c3fSmrg   if (!memObj)
24601e04c3fSmrg      return;
24701e04c3fSmrg
24801e04c3fSmrg   switch (pname) {
24901e04c3fSmrg      case GL_DEDICATED_MEMORY_OBJECT_EXT:
25001e04c3fSmrg         *params = (GLint) memObj->Dedicated;
25101e04c3fSmrg         break;
25201e04c3fSmrg      case GL_PROTECTED_MEMORY_OBJECT_EXT:
25301e04c3fSmrg         /* EXT_protected_textures not supported */
25401e04c3fSmrg         goto invalid_pname;
25501e04c3fSmrg      default:
25601e04c3fSmrg         goto invalid_pname;
25701e04c3fSmrg   }
25801e04c3fSmrg   return;
25901e04c3fSmrg
26001e04c3fSmrginvalid_pname:
26101e04c3fSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
26201e04c3fSmrg}
26301e04c3fSmrg
26401e04c3fSmrgstatic struct gl_memory_object *
26501e04c3fSmrglookup_memory_object_err(struct gl_context *ctx, unsigned memory,
26601e04c3fSmrg                         const char* func)
26701e04c3fSmrg{
26801e04c3fSmrg   if (memory == 0) {
26901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
27001e04c3fSmrg      return NULL;
27101e04c3fSmrg   }
27201e04c3fSmrg
27301e04c3fSmrg   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
27401e04c3fSmrg   if (!memObj)
27501e04c3fSmrg      return NULL;
27601e04c3fSmrg
27701e04c3fSmrg   if (!memObj->Immutable) {
27801e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
27901e04c3fSmrg                  func);
28001e04c3fSmrg      return NULL;
28101e04c3fSmrg   }
28201e04c3fSmrg
28301e04c3fSmrg   return memObj;
28401e04c3fSmrg}
28501e04c3fSmrg
28601e04c3fSmrg/**
28701e04c3fSmrg * Helper used by _mesa_TexStorageMem1/2/3DEXT().
28801e04c3fSmrg */
28901e04c3fSmrgstatic void
29001e04c3fSmrgtexstorage_memory(GLuint dims, GLenum target, GLsizei levels,
29101e04c3fSmrg                  GLenum internalFormat, GLsizei width, GLsizei height,
29201e04c3fSmrg                  GLsizei depth, GLuint memory, GLuint64 offset,
29301e04c3fSmrg                  const char *func)
29401e04c3fSmrg{
29501e04c3fSmrg   struct gl_texture_object *texObj;
29601e04c3fSmrg   struct gl_memory_object *memObj;
29701e04c3fSmrg
29801e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
29901e04c3fSmrg
30001e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
30101e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
30201e04c3fSmrg      return;
30301e04c3fSmrg   }
30401e04c3fSmrg
30501e04c3fSmrg   texObj = _mesa_get_current_tex_object(ctx, target);
30601e04c3fSmrg   if (!texObj)
30701e04c3fSmrg      return;
30801e04c3fSmrg
30901e04c3fSmrg   memObj = lookup_memory_object_err(ctx, memory, func);
31001e04c3fSmrg   if (!memObj)
31101e04c3fSmrg      return;
31201e04c3fSmrg
31301e04c3fSmrg   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
31401e04c3fSmrg                                levels, internalFormat,
31501e04c3fSmrg                                width, height, depth, offset, false);
31601e04c3fSmrg}
31701e04c3fSmrg
31801e04c3fSmrgstatic void
31901e04c3fSmrgtexstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
32001e04c3fSmrg                     GLenum internalFormat, GLsizei width, GLsizei height,
32101e04c3fSmrg                     GLsizei depth, GLboolean fixedSampleLocations,
32201e04c3fSmrg                     GLuint memory, GLuint64 offset, const char* func)
32301e04c3fSmrg{
32401e04c3fSmrg   struct gl_texture_object *texObj;
32501e04c3fSmrg   struct gl_memory_object *memObj;
32601e04c3fSmrg
32701e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
32801e04c3fSmrg
32901e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
33001e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
33101e04c3fSmrg      return;
33201e04c3fSmrg   }
33301e04c3fSmrg
33401e04c3fSmrg   texObj = _mesa_get_current_tex_object(ctx, target);
33501e04c3fSmrg   if (!texObj)
33601e04c3fSmrg      return;
33701e04c3fSmrg
33801e04c3fSmrg   memObj = lookup_memory_object_err(ctx, memory, func);
33901e04c3fSmrg   if (!memObj)
34001e04c3fSmrg      return;
34101e04c3fSmrg
34201e04c3fSmrg   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
34301e04c3fSmrg                                   internalFormat, width, height, depth,
34401e04c3fSmrg                                   fixedSampleLocations, offset, func);
34501e04c3fSmrg}
34601e04c3fSmrg
34701e04c3fSmrg/**
34801e04c3fSmrg * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
34901e04c3fSmrg */
35001e04c3fSmrgstatic void
35101e04c3fSmrgtexturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
35201e04c3fSmrg                      GLenum internalFormat, GLsizei width, GLsizei height,
35301e04c3fSmrg                      GLsizei depth, GLuint memory, GLuint64 offset,
35401e04c3fSmrg                      const char *func)
35501e04c3fSmrg{
35601e04c3fSmrg   struct gl_texture_object *texObj;
35701e04c3fSmrg   struct gl_memory_object *memObj;
35801e04c3fSmrg
35901e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
36001e04c3fSmrg
36101e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
36201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
36301e04c3fSmrg      return;
36401e04c3fSmrg   }
36501e04c3fSmrg
36601e04c3fSmrg   texObj = _mesa_lookup_texture(ctx, texture);
36701e04c3fSmrg   if (!texObj)
36801e04c3fSmrg      return;
36901e04c3fSmrg
37001e04c3fSmrg   memObj = lookup_memory_object_err(ctx, memory, func);
37101e04c3fSmrg   if (!memObj)
37201e04c3fSmrg      return;
37301e04c3fSmrg
37401e04c3fSmrg   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
37501e04c3fSmrg                                levels, internalFormat,
37601e04c3fSmrg                                width, height, depth, offset, true);
37701e04c3fSmrg}
37801e04c3fSmrg
37901e04c3fSmrgstatic void
38001e04c3fSmrgtexturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
38101e04c3fSmrg                         GLenum internalFormat, GLsizei width, GLsizei height,
38201e04c3fSmrg                         GLsizei depth, GLboolean fixedSampleLocations,
38301e04c3fSmrg                         GLuint memory, GLuint64 offset, const char* func)
38401e04c3fSmrg{
38501e04c3fSmrg   struct gl_texture_object *texObj;
38601e04c3fSmrg   struct gl_memory_object *memObj;
38701e04c3fSmrg
38801e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
38901e04c3fSmrg
39001e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object) {
39101e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
39201e04c3fSmrg      return;
39301e04c3fSmrg   }
39401e04c3fSmrg
39501e04c3fSmrg   texObj = _mesa_lookup_texture(ctx, texture);
39601e04c3fSmrg   if (!texObj)
39701e04c3fSmrg      return;
39801e04c3fSmrg
39901e04c3fSmrg   memObj = lookup_memory_object_err(ctx, memory, func);
40001e04c3fSmrg   if (!memObj)
40101e04c3fSmrg      return;
40201e04c3fSmrg
40301e04c3fSmrg   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
40401e04c3fSmrg                                   samples, internalFormat, width, height,
40501e04c3fSmrg                                   depth, fixedSampleLocations, offset, func);
40601e04c3fSmrg}
40701e04c3fSmrg
40801e04c3fSmrgvoid GLAPIENTRY
40901e04c3fSmrg_mesa_TexStorageMem2DEXT(GLenum target,
41001e04c3fSmrg                         GLsizei levels,
41101e04c3fSmrg                         GLenum internalFormat,
41201e04c3fSmrg                         GLsizei width,
41301e04c3fSmrg                         GLsizei height,
41401e04c3fSmrg                         GLuint memory,
41501e04c3fSmrg                         GLuint64 offset)
41601e04c3fSmrg{
41701e04c3fSmrg   texstorage_memory(2, target, levels, internalFormat, width, height, 1,
41801e04c3fSmrg                     memory, offset, "glTexStorageMem2DEXT");
41901e04c3fSmrg}
42001e04c3fSmrg
42101e04c3fSmrgvoid GLAPIENTRY
42201e04c3fSmrg_mesa_TexStorageMem2DMultisampleEXT(GLenum target,
42301e04c3fSmrg                                    GLsizei samples,
42401e04c3fSmrg                                    GLenum internalFormat,
42501e04c3fSmrg                                    GLsizei width,
42601e04c3fSmrg                                    GLsizei height,
42701e04c3fSmrg                                    GLboolean fixedSampleLocations,
42801e04c3fSmrg                                    GLuint memory,
42901e04c3fSmrg                                    GLuint64 offset)
43001e04c3fSmrg{
43101e04c3fSmrg   texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
43201e04c3fSmrg                        fixedSampleLocations, memory, offset,
43301e04c3fSmrg                        "glTexStorageMem2DMultisampleEXT");
43401e04c3fSmrg}
43501e04c3fSmrg
43601e04c3fSmrgvoid GLAPIENTRY
43701e04c3fSmrg_mesa_TexStorageMem3DEXT(GLenum target,
43801e04c3fSmrg                         GLsizei levels,
43901e04c3fSmrg                         GLenum internalFormat,
44001e04c3fSmrg                         GLsizei width,
44101e04c3fSmrg                         GLsizei height,
44201e04c3fSmrg                         GLsizei depth,
44301e04c3fSmrg                         GLuint memory,
44401e04c3fSmrg                         GLuint64 offset)
44501e04c3fSmrg{
44601e04c3fSmrg   texstorage_memory(3, target, levels, internalFormat, width, height, depth,
44701e04c3fSmrg                     memory, offset, "glTexStorageMem3DEXT");
44801e04c3fSmrg}
44901e04c3fSmrg
45001e04c3fSmrgvoid GLAPIENTRY
45101e04c3fSmrg_mesa_TexStorageMem3DMultisampleEXT(GLenum target,
45201e04c3fSmrg                                    GLsizei samples,
45301e04c3fSmrg                                    GLenum internalFormat,
45401e04c3fSmrg                                    GLsizei width,
45501e04c3fSmrg                                    GLsizei height,
45601e04c3fSmrg                                    GLsizei depth,
45701e04c3fSmrg                                    GLboolean fixedSampleLocations,
45801e04c3fSmrg                                    GLuint memory,
45901e04c3fSmrg                                    GLuint64 offset)
46001e04c3fSmrg{
46101e04c3fSmrg   texstorage_memory_ms(3, target, samples, internalFormat, width, height,
46201e04c3fSmrg                        depth, fixedSampleLocations, memory, offset,
46301e04c3fSmrg                        "glTexStorageMem3DMultisampleEXT");
46401e04c3fSmrg}
46501e04c3fSmrg
46601e04c3fSmrgvoid GLAPIENTRY
46701e04c3fSmrg_mesa_TextureStorageMem2DEXT(GLuint texture,
46801e04c3fSmrg                             GLsizei levels,
46901e04c3fSmrg                             GLenum internalFormat,
47001e04c3fSmrg                             GLsizei width,
47101e04c3fSmrg                             GLsizei height,
47201e04c3fSmrg                             GLuint memory,
47301e04c3fSmrg                             GLuint64 offset)
47401e04c3fSmrg{
47501e04c3fSmrg   texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
47601e04c3fSmrg                         memory, offset, "glTexureStorageMem2DEXT");
47701e04c3fSmrg}
47801e04c3fSmrg
47901e04c3fSmrgvoid GLAPIENTRY
48001e04c3fSmrg_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
48101e04c3fSmrg                                        GLsizei samples,
48201e04c3fSmrg                                        GLenum internalFormat,
48301e04c3fSmrg                                        GLsizei width,
48401e04c3fSmrg                                        GLsizei height,
48501e04c3fSmrg                                        GLboolean fixedSampleLocations,
48601e04c3fSmrg                                        GLuint memory,
48701e04c3fSmrg                                        GLuint64 offset)
48801e04c3fSmrg{
48901e04c3fSmrg   texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
49001e04c3fSmrg                            1, fixedSampleLocations, memory, offset,
49101e04c3fSmrg                            "glTextureStorageMem2DMultisampleEXT");
49201e04c3fSmrg}
49301e04c3fSmrg
49401e04c3fSmrgvoid GLAPIENTRY
49501e04c3fSmrg_mesa_TextureStorageMem3DEXT(GLuint texture,
49601e04c3fSmrg                             GLsizei levels,
49701e04c3fSmrg                             GLenum internalFormat,
49801e04c3fSmrg                             GLsizei width,
49901e04c3fSmrg                             GLsizei height,
50001e04c3fSmrg                             GLsizei depth,
50101e04c3fSmrg                             GLuint memory,
50201e04c3fSmrg                             GLuint64 offset)
50301e04c3fSmrg{
50401e04c3fSmrg   texturestorage_memory(3, texture, levels, internalFormat, width, height,
50501e04c3fSmrg                         depth, memory, offset, "glTextureStorageMem3DEXT");
50601e04c3fSmrg}
50701e04c3fSmrg
50801e04c3fSmrgvoid GLAPIENTRY
50901e04c3fSmrg_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
51001e04c3fSmrg                                        GLsizei samples,
51101e04c3fSmrg                                        GLenum internalFormat,
51201e04c3fSmrg                                        GLsizei width,
51301e04c3fSmrg                                        GLsizei height,
51401e04c3fSmrg                                        GLsizei depth,
51501e04c3fSmrg                                        GLboolean fixedSampleLocations,
51601e04c3fSmrg                                        GLuint memory,
51701e04c3fSmrg                                        GLuint64 offset)
51801e04c3fSmrg{
51901e04c3fSmrg   texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
52001e04c3fSmrg                            depth, fixedSampleLocations, memory, offset,
52101e04c3fSmrg                            "glTextureStorageMem3DMultisampleEXT");
52201e04c3fSmrg}
52301e04c3fSmrg
52401e04c3fSmrgvoid GLAPIENTRY
52501e04c3fSmrg_mesa_TexStorageMem1DEXT(GLenum target,
52601e04c3fSmrg                         GLsizei levels,
52701e04c3fSmrg                         GLenum internalFormat,
52801e04c3fSmrg                         GLsizei width,
52901e04c3fSmrg                         GLuint memory,
53001e04c3fSmrg                         GLuint64 offset)
53101e04c3fSmrg{
53201e04c3fSmrg   texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
53301e04c3fSmrg                     offset, "glTexStorageMem1DEXT");
53401e04c3fSmrg}
53501e04c3fSmrg
53601e04c3fSmrgvoid GLAPIENTRY
53701e04c3fSmrg_mesa_TextureStorageMem1DEXT(GLuint texture,
53801e04c3fSmrg                             GLsizei levels,
53901e04c3fSmrg                             GLenum internalFormat,
54001e04c3fSmrg                             GLsizei width,
54101e04c3fSmrg                             GLuint memory,
54201e04c3fSmrg                             GLuint64 offset)
54301e04c3fSmrg{
54401e04c3fSmrg   texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
54501e04c3fSmrg                         memory, offset, "glTextureStorageMem1DEXT");
54601e04c3fSmrg}
54701e04c3fSmrg
54801e04c3fSmrg/**
54901e04c3fSmrg * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
55001e04c3fSmrg * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
55101e04c3fSmrg */
55201e04c3fSmrgstatic struct gl_semaphore_object DummySemaphoreObject;
55301e04c3fSmrg
55401e04c3fSmrg/**
55501e04c3fSmrg * Delete a semaphore object.  Called via ctx->Driver.DeleteSemaphore().
55601e04c3fSmrg * Not removed from hash table here.
55701e04c3fSmrg */
55801e04c3fSmrgvoid
55901e04c3fSmrg_mesa_delete_semaphore_object(struct gl_context *ctx,
56001e04c3fSmrg                              struct gl_semaphore_object *semObj)
56101e04c3fSmrg{
56201e04c3fSmrg   if (semObj != &DummySemaphoreObject)
56301e04c3fSmrg      free(semObj);
56401e04c3fSmrg}
56501e04c3fSmrg
56601e04c3fSmrg/**
56701e04c3fSmrg * Initialize a semaphore object to default values.
56801e04c3fSmrg */
56901e04c3fSmrgvoid
57001e04c3fSmrg_mesa_initialize_semaphore_object(struct gl_context *ctx,
57101e04c3fSmrg                                  struct gl_semaphore_object *obj,
57201e04c3fSmrg                                  GLuint name)
57301e04c3fSmrg{
57401e04c3fSmrg   memset(obj, 0, sizeof(struct gl_semaphore_object));
57501e04c3fSmrg   obj->Name = name;
57601e04c3fSmrg}
57701e04c3fSmrg
57801e04c3fSmrgvoid GLAPIENTRY
57901e04c3fSmrg_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
58001e04c3fSmrg{
58101e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
58201e04c3fSmrg
58301e04c3fSmrg   const char *func = "glGenSemaphoresEXT";
58401e04c3fSmrg
58501e04c3fSmrg   if (MESA_VERBOSE & (VERBOSE_API))
58601e04c3fSmrg      _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores);
58701e04c3fSmrg
58801e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
58901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
59001e04c3fSmrg      return;
59101e04c3fSmrg   }
59201e04c3fSmrg
59301e04c3fSmrg   if (n < 0) {
59401e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
59501e04c3fSmrg      return;
59601e04c3fSmrg   }
59701e04c3fSmrg
59801e04c3fSmrg   if (!semaphores)
59901e04c3fSmrg      return;
60001e04c3fSmrg
60101e04c3fSmrg   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
6027ec681f3Smrg   if (_mesa_HashFindFreeKeys(ctx->Shared->SemaphoreObjects, semaphores, n)) {
60301e04c3fSmrg      for (GLsizei i = 0; i < n; i++) {
60401e04c3fSmrg         _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects,
6057ec681f3Smrg                                semaphores[i], &DummySemaphoreObject, true);
60601e04c3fSmrg      }
60701e04c3fSmrg   }
60801e04c3fSmrg
60901e04c3fSmrg   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
61001e04c3fSmrg}
61101e04c3fSmrg
61201e04c3fSmrgvoid GLAPIENTRY
61301e04c3fSmrg_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
61401e04c3fSmrg{
61501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
61601e04c3fSmrg
61701e04c3fSmrg   const char *func = "glDeleteSemaphoresEXT";
61801e04c3fSmrg
61901e04c3fSmrg   if (MESA_VERBOSE & (VERBOSE_API)) {
62001e04c3fSmrg      _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
62101e04c3fSmrg   }
62201e04c3fSmrg
62301e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
62401e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
62501e04c3fSmrg      return;
62601e04c3fSmrg   }
62701e04c3fSmrg
62801e04c3fSmrg   if (n < 0) {
62901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
63001e04c3fSmrg      return;
63101e04c3fSmrg   }
63201e04c3fSmrg
63301e04c3fSmrg   if (!semaphores)
63401e04c3fSmrg      return;
63501e04c3fSmrg
63601e04c3fSmrg   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
63701e04c3fSmrg   for (GLint i = 0; i < n; i++) {
63801e04c3fSmrg      if (semaphores[i] > 0) {
63901e04c3fSmrg         struct gl_semaphore_object *delObj
64001e04c3fSmrg            = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]);
64101e04c3fSmrg
64201e04c3fSmrg         if (delObj) {
64301e04c3fSmrg            _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects,
64401e04c3fSmrg                                   semaphores[i]);
64501e04c3fSmrg            ctx->Driver.DeleteSemaphoreObject(ctx, delObj);
64601e04c3fSmrg         }
64701e04c3fSmrg      }
64801e04c3fSmrg   }
64901e04c3fSmrg   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
65001e04c3fSmrg}
65101e04c3fSmrg
65201e04c3fSmrgGLboolean GLAPIENTRY
65301e04c3fSmrg_mesa_IsSemaphoreEXT(GLuint semaphore)
65401e04c3fSmrg{
65501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
65601e04c3fSmrg
65701e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
65801e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)");
65901e04c3fSmrg      return GL_FALSE;
66001e04c3fSmrg   }
66101e04c3fSmrg
66201e04c3fSmrg   struct gl_semaphore_object *obj =
66301e04c3fSmrg      _mesa_lookup_semaphore_object(ctx, semaphore);
66401e04c3fSmrg
66501e04c3fSmrg   return obj ? GL_TRUE : GL_FALSE;
66601e04c3fSmrg}
66701e04c3fSmrg
66801e04c3fSmrg/**
66901e04c3fSmrg * Helper that outputs the correct error status for parameter
67001e04c3fSmrg * calls where no pnames are defined
67101e04c3fSmrg */
67201e04c3fSmrgstatic void
67301e04c3fSmrgsemaphore_parameter_stub(const char* func, GLenum pname)
67401e04c3fSmrg{
67501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
67601e04c3fSmrg
67701e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
67801e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
67901e04c3fSmrg      return;
68001e04c3fSmrg   }
68101e04c3fSmrg
68201e04c3fSmrg   /* EXT_semaphore and EXT_semaphore_fd define no parameters */
68301e04c3fSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
68401e04c3fSmrg}
68501e04c3fSmrg
68601e04c3fSmrgvoid GLAPIENTRY
68701e04c3fSmrg_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
68801e04c3fSmrg                                 GLenum pname,
68901e04c3fSmrg                                 const GLuint64 *params)
69001e04c3fSmrg{
69101e04c3fSmrg   const char *func = "glSemaphoreParameterui64vEXT";
69201e04c3fSmrg
69301e04c3fSmrg   semaphore_parameter_stub(func, pname);
69401e04c3fSmrg}
69501e04c3fSmrg
69601e04c3fSmrgvoid GLAPIENTRY
69701e04c3fSmrg_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
69801e04c3fSmrg                                    GLenum pname,
69901e04c3fSmrg                                    GLuint64 *params)
70001e04c3fSmrg{
70101e04c3fSmrg   const char *func = "glGetSemaphoreParameterui64vEXT";
70201e04c3fSmrg
70301e04c3fSmrg   semaphore_parameter_stub(func, pname);
70401e04c3fSmrg}
70501e04c3fSmrg
70601e04c3fSmrgvoid GLAPIENTRY
70701e04c3fSmrg_mesa_WaitSemaphoreEXT(GLuint semaphore,
70801e04c3fSmrg                       GLuint numBufferBarriers,
70901e04c3fSmrg                       const GLuint *buffers,
71001e04c3fSmrg                       GLuint numTextureBarriers,
71101e04c3fSmrg                       const GLuint *textures,
71201e04c3fSmrg                       const GLenum *srcLayouts)
71301e04c3fSmrg{
71401e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
71501e04c3fSmrg   struct gl_semaphore_object *semObj = NULL;
71601e04c3fSmrg   struct gl_buffer_object **bufObjs = NULL;
71701e04c3fSmrg   struct gl_texture_object **texObjs = NULL;
71801e04c3fSmrg
71901e04c3fSmrg   const char *func = "glWaitSemaphoreEXT";
72001e04c3fSmrg
72101e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
72201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
72301e04c3fSmrg      return;
72401e04c3fSmrg   }
72501e04c3fSmrg
72601e04c3fSmrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
72701e04c3fSmrg
72801e04c3fSmrg   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
72901e04c3fSmrg   if (!semObj)
73001e04c3fSmrg      return;
73101e04c3fSmrg
7327ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
73301e04c3fSmrg
73401e04c3fSmrg   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
73501e04c3fSmrg   if (!bufObjs) {
73601e04c3fSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
73701e04c3fSmrg                  func, numBufferBarriers);
73801e04c3fSmrg      goto end;
73901e04c3fSmrg   }
74001e04c3fSmrg
74101e04c3fSmrg   for (unsigned i = 0; i < numBufferBarriers; i++) {
74201e04c3fSmrg      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
74301e04c3fSmrg   }
74401e04c3fSmrg
74501e04c3fSmrg   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
74601e04c3fSmrg   if (!texObjs) {
74701e04c3fSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
74801e04c3fSmrg                  func, numTextureBarriers);
74901e04c3fSmrg      goto end;
75001e04c3fSmrg   }
75101e04c3fSmrg
75201e04c3fSmrg   for (unsigned i = 0; i < numTextureBarriers; i++) {
75301e04c3fSmrg      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
75401e04c3fSmrg   }
75501e04c3fSmrg
75601e04c3fSmrg   ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj,
75701e04c3fSmrg                                         numBufferBarriers, bufObjs,
75801e04c3fSmrg                                         numTextureBarriers, texObjs,
75901e04c3fSmrg                                         srcLayouts);
76001e04c3fSmrg
76101e04c3fSmrgend:
76201e04c3fSmrg   free(bufObjs);
76301e04c3fSmrg   free(texObjs);
76401e04c3fSmrg}
76501e04c3fSmrg
76601e04c3fSmrgvoid GLAPIENTRY
76701e04c3fSmrg_mesa_SignalSemaphoreEXT(GLuint semaphore,
76801e04c3fSmrg                         GLuint numBufferBarriers,
76901e04c3fSmrg                         const GLuint *buffers,
77001e04c3fSmrg                         GLuint numTextureBarriers,
77101e04c3fSmrg                         const GLuint *textures,
77201e04c3fSmrg                         const GLenum *dstLayouts)
77301e04c3fSmrg{
77401e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
77501e04c3fSmrg   struct gl_semaphore_object *semObj = NULL;
77601e04c3fSmrg   struct gl_buffer_object **bufObjs = NULL;
77701e04c3fSmrg   struct gl_texture_object **texObjs = NULL;
77801e04c3fSmrg
77901e04c3fSmrg   const char *func = "glSignalSemaphoreEXT";
78001e04c3fSmrg
78101e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore) {
78201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
78301e04c3fSmrg      return;
78401e04c3fSmrg   }
78501e04c3fSmrg
78601e04c3fSmrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
78701e04c3fSmrg
78801e04c3fSmrg   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
78901e04c3fSmrg   if (!semObj)
79001e04c3fSmrg      return;
79101e04c3fSmrg
7927ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
79301e04c3fSmrg
79401e04c3fSmrg   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
79501e04c3fSmrg   if (!bufObjs) {
79601e04c3fSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
79701e04c3fSmrg                  func, numBufferBarriers);
79801e04c3fSmrg      goto end;
79901e04c3fSmrg   }
80001e04c3fSmrg
80101e04c3fSmrg   for (unsigned i = 0; i < numBufferBarriers; i++) {
80201e04c3fSmrg      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
80301e04c3fSmrg   }
80401e04c3fSmrg
80501e04c3fSmrg   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
80601e04c3fSmrg   if (!texObjs) {
80701e04c3fSmrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
80801e04c3fSmrg                  func, numTextureBarriers);
80901e04c3fSmrg      goto end;
81001e04c3fSmrg   }
81101e04c3fSmrg
81201e04c3fSmrg   for (unsigned i = 0; i < numTextureBarriers; i++) {
81301e04c3fSmrg      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
81401e04c3fSmrg   }
81501e04c3fSmrg
81601e04c3fSmrg   ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj,
81701e04c3fSmrg                                           numBufferBarriers, bufObjs,
81801e04c3fSmrg                                           numTextureBarriers, texObjs,
81901e04c3fSmrg                                           dstLayouts);
82001e04c3fSmrg
82101e04c3fSmrgend:
82201e04c3fSmrg   free(bufObjs);
82301e04c3fSmrg   free(texObjs);
82401e04c3fSmrg}
82501e04c3fSmrg
82601e04c3fSmrgvoid GLAPIENTRY
82701e04c3fSmrg_mesa_ImportMemoryFdEXT(GLuint memory,
82801e04c3fSmrg                        GLuint64 size,
82901e04c3fSmrg                        GLenum handleType,
83001e04c3fSmrg                        GLint fd)
83101e04c3fSmrg{
83201e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
83301e04c3fSmrg
83401e04c3fSmrg   const char *func = "glImportMemoryFdEXT";
83501e04c3fSmrg
83601e04c3fSmrg   if (!ctx->Extensions.EXT_memory_object_fd) {
83701e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
83801e04c3fSmrg      return;
83901e04c3fSmrg   }
84001e04c3fSmrg
84101e04c3fSmrg   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
84201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
84301e04c3fSmrg      return;
84401e04c3fSmrg   }
84501e04c3fSmrg
84601e04c3fSmrg   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
84701e04c3fSmrg   if (!memObj)
84801e04c3fSmrg      return;
84901e04c3fSmrg
85001e04c3fSmrg   ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
85101e04c3fSmrg   memObj->Immutable = GL_TRUE;
85201e04c3fSmrg}
85301e04c3fSmrg
85401e04c3fSmrgvoid GLAPIENTRY
85501e04c3fSmrg_mesa_ImportSemaphoreFdEXT(GLuint semaphore,
85601e04c3fSmrg                           GLenum handleType,
85701e04c3fSmrg                           GLint fd)
85801e04c3fSmrg{
85901e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
86001e04c3fSmrg
86101e04c3fSmrg   const char *func = "glImportSemaphoreFdEXT";
86201e04c3fSmrg
86301e04c3fSmrg   if (!ctx->Extensions.EXT_semaphore_fd) {
86401e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
86501e04c3fSmrg      return;
86601e04c3fSmrg   }
86701e04c3fSmrg
86801e04c3fSmrg   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
86901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
87001e04c3fSmrg      return;
87101e04c3fSmrg   }
87201e04c3fSmrg
87301e04c3fSmrg   struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
87401e04c3fSmrg                                                                      semaphore);
87501e04c3fSmrg   if (!semObj)
87601e04c3fSmrg      return;
87701e04c3fSmrg
87801e04c3fSmrg   if (semObj == &DummySemaphoreObject) {
87901e04c3fSmrg      semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore);
88001e04c3fSmrg      if (!semObj) {
88101e04c3fSmrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
88201e04c3fSmrg         return;
88301e04c3fSmrg      }
8847ec681f3Smrg      _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj, true);
88501e04c3fSmrg   }
88601e04c3fSmrg
88701e04c3fSmrg   ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd);
88801e04c3fSmrg}
889