1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2016 Red Hat.
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg
24b8e80941Smrg#include "macros.h"
25b8e80941Smrg#include "mtypes.h"
26b8e80941Smrg#include "bufferobj.h"
27b8e80941Smrg#include "context.h"
28b8e80941Smrg#include "externalobjects.h"
29b8e80941Smrg#include "teximage.h"
30b8e80941Smrg#include "texobj.h"
31b8e80941Smrg#include "glformats.h"
32b8e80941Smrg#include "texstorage.h"
33b8e80941Smrg
34b8e80941Smrg/**
35b8e80941Smrg * Allocate and initialize a new memory object.  But don't put it into the
36b8e80941Smrg * memory object hash table.
37b8e80941Smrg *
38b8e80941Smrg * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
39b8e80941Smrg * driver.
40b8e80941Smrg *
41b8e80941Smrg * \return pointer to new memory object.
42b8e80941Smrg */
43b8e80941Smrgstatic struct gl_memory_object *
44b8e80941Smrg_mesa_new_memory_object(struct gl_context *ctx, GLuint name)
45b8e80941Smrg{
46b8e80941Smrg   struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object);
47b8e80941Smrg   if (!obj)
48b8e80941Smrg      return NULL;
49b8e80941Smrg
50b8e80941Smrg   _mesa_initialize_memory_object(ctx, obj, name);
51b8e80941Smrg   return obj;
52b8e80941Smrg}
53b8e80941Smrg
54b8e80941Smrg/**
55b8e80941Smrg * Delete a memory object.  Called via ctx->Driver.DeleteMemory().
56b8e80941Smrg * Not removed from hash table here.
57b8e80941Smrg */
58b8e80941Smrgvoid
59b8e80941Smrg_mesa_delete_memory_object(struct gl_context *ctx,
60b8e80941Smrg                           struct gl_memory_object *memObj)
61b8e80941Smrg{
62b8e80941Smrg   free(memObj);
63b8e80941Smrg}
64b8e80941Smrg
65b8e80941Smrgvoid
66b8e80941Smrg_mesa_init_memory_object_functions(struct dd_function_table *driver)
67b8e80941Smrg{
68b8e80941Smrg   driver->NewMemoryObject = _mesa_new_memory_object;
69b8e80941Smrg   driver->DeleteMemoryObject = _mesa_delete_memory_object;
70b8e80941Smrg}
71b8e80941Smrg
72b8e80941Smrg/**
73b8e80941Smrg * Initialize a buffer object to default values.
74b8e80941Smrg */
75b8e80941Smrgvoid
76b8e80941Smrg_mesa_initialize_memory_object(struct gl_context *ctx,
77b8e80941Smrg                               struct gl_memory_object *obj,
78b8e80941Smrg                               GLuint name)
79b8e80941Smrg{
80b8e80941Smrg   memset(obj, 0, sizeof(struct gl_memory_object));
81b8e80941Smrg   obj->Name = name;
82b8e80941Smrg   obj->Dedicated = GL_FALSE;
83b8e80941Smrg}
84b8e80941Smrg
85b8e80941Smrgvoid GLAPIENTRY
86b8e80941Smrg_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
87b8e80941Smrg{
88b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
89b8e80941Smrg
90b8e80941Smrg   if (MESA_VERBOSE & (VERBOSE_API)) {
91b8e80941Smrg      _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
92b8e80941Smrg                  memoryObjects);
93b8e80941Smrg   }
94b8e80941Smrg
95b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
96b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
97b8e80941Smrg                  "glDeleteMemoryObjectsEXT(unsupported)");
98b8e80941Smrg      return;
99b8e80941Smrg   }
100b8e80941Smrg
101b8e80941Smrg   if (n < 0) {
102b8e80941Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
103b8e80941Smrg      return;
104b8e80941Smrg   }
105b8e80941Smrg
106b8e80941Smrg   if (!memoryObjects)
107b8e80941Smrg      return;
108b8e80941Smrg
109b8e80941Smrg   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
110b8e80941Smrg   for (GLint i = 0; i < n; i++) {
111b8e80941Smrg      if (memoryObjects[i] > 0) {
112b8e80941Smrg         struct gl_memory_object *delObj
113b8e80941Smrg            = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
114b8e80941Smrg
115b8e80941Smrg         if (delObj) {
116b8e80941Smrg            _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
117b8e80941Smrg                                   memoryObjects[i]);
118b8e80941Smrg            ctx->Driver.DeleteMemoryObject(ctx, delObj);
119b8e80941Smrg         }
120b8e80941Smrg      }
121b8e80941Smrg   }
122b8e80941Smrg   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
123b8e80941Smrg}
124b8e80941Smrg
125b8e80941SmrgGLboolean GLAPIENTRY
126b8e80941Smrg_mesa_IsMemoryObjectEXT(GLuint memoryObject)
127b8e80941Smrg{
128b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
129b8e80941Smrg
130b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
131b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
132b8e80941Smrg                  "glIsMemoryObjectEXT(unsupported)");
133b8e80941Smrg      return GL_FALSE;
134b8e80941Smrg   }
135b8e80941Smrg
136b8e80941Smrg   struct gl_memory_object *obj =
137b8e80941Smrg      _mesa_lookup_memory_object(ctx, memoryObject);
138b8e80941Smrg
139b8e80941Smrg   return obj ? GL_TRUE : GL_FALSE;
140b8e80941Smrg}
141b8e80941Smrg
142b8e80941Smrgvoid GLAPIENTRY
143b8e80941Smrg_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
144b8e80941Smrg{
145b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
146b8e80941Smrg
147b8e80941Smrg   const char *func = "glCreateMemoryObjectsEXT";
148b8e80941Smrg
149b8e80941Smrg   if (MESA_VERBOSE & (VERBOSE_API))
150b8e80941Smrg      _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
151b8e80941Smrg
152b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
153b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
154b8e80941Smrg      return;
155b8e80941Smrg   }
156b8e80941Smrg
157b8e80941Smrg   if (n < 0) {
158b8e80941Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
159b8e80941Smrg      return;
160b8e80941Smrg   }
161b8e80941Smrg
162b8e80941Smrg   if (!memoryObjects)
163b8e80941Smrg      return;
164b8e80941Smrg
165b8e80941Smrg   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
166b8e80941Smrg   GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->MemoryObjects, n);
167b8e80941Smrg   if (first) {
168b8e80941Smrg      for (GLsizei i = 0; i < n; i++) {
169b8e80941Smrg         struct gl_memory_object *memObj;
170b8e80941Smrg
171b8e80941Smrg         memoryObjects[i] = first + i;
172b8e80941Smrg
173b8e80941Smrg         /* allocate memory object */
174b8e80941Smrg         memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
175b8e80941Smrg         if (!memObj) {
176b8e80941Smrg            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
177b8e80941Smrg            _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
178b8e80941Smrg            return;
179b8e80941Smrg         }
180b8e80941Smrg
181b8e80941Smrg         /* insert into hash table */
182b8e80941Smrg         _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
183b8e80941Smrg                                memoryObjects[i],
184b8e80941Smrg                                memObj);
185b8e80941Smrg      }
186b8e80941Smrg   }
187b8e80941Smrg
188b8e80941Smrg   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
189b8e80941Smrg}
190b8e80941Smrg
191b8e80941Smrgvoid GLAPIENTRY
192b8e80941Smrg_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
193b8e80941Smrg                                 GLenum pname,
194b8e80941Smrg                                 const GLint *params)
195b8e80941Smrg{
196b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
197b8e80941Smrg   struct gl_memory_object *memObj;
198b8e80941Smrg
199b8e80941Smrg   const char *func = "glMemoryObjectParameterivEXT";
200b8e80941Smrg
201b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
202b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
203b8e80941Smrg      return;
204b8e80941Smrg   }
205b8e80941Smrg
206b8e80941Smrg   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
207b8e80941Smrg   if (!memObj)
208b8e80941Smrg      return;
209b8e80941Smrg
210b8e80941Smrg   if (memObj->Immutable) {
211b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
212b8e80941Smrg      return;
213b8e80941Smrg   }
214b8e80941Smrg
215b8e80941Smrg   switch (pname) {
216b8e80941Smrg   case GL_DEDICATED_MEMORY_OBJECT_EXT:
217b8e80941Smrg      memObj->Dedicated = (GLboolean) params[0];
218b8e80941Smrg      break;
219b8e80941Smrg   case GL_PROTECTED_MEMORY_OBJECT_EXT:
220b8e80941Smrg      /* EXT_protected_textures not supported */
221b8e80941Smrg      goto invalid_pname;
222b8e80941Smrg   default:
223b8e80941Smrg      goto invalid_pname;
224b8e80941Smrg   }
225b8e80941Smrg   return;
226b8e80941Smrg
227b8e80941Smrginvalid_pname:
228b8e80941Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
229b8e80941Smrg}
230b8e80941Smrg
231b8e80941Smrgvoid GLAPIENTRY
232b8e80941Smrg_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
233b8e80941Smrg                                    GLenum pname,
234b8e80941Smrg                                    GLint *params)
235b8e80941Smrg{
236b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
237b8e80941Smrg   struct gl_memory_object *memObj;
238b8e80941Smrg
239b8e80941Smrg   const char *func = "glMemoryObjectParameterivEXT";
240b8e80941Smrg
241b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
242b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
243b8e80941Smrg      return;
244b8e80941Smrg   }
245b8e80941Smrg
246b8e80941Smrg   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
247b8e80941Smrg   if (!memObj)
248b8e80941Smrg      return;
249b8e80941Smrg
250b8e80941Smrg   switch (pname) {
251b8e80941Smrg      case GL_DEDICATED_MEMORY_OBJECT_EXT:
252b8e80941Smrg         *params = (GLint) memObj->Dedicated;
253b8e80941Smrg         break;
254b8e80941Smrg      case GL_PROTECTED_MEMORY_OBJECT_EXT:
255b8e80941Smrg         /* EXT_protected_textures not supported */
256b8e80941Smrg         goto invalid_pname;
257b8e80941Smrg      default:
258b8e80941Smrg         goto invalid_pname;
259b8e80941Smrg   }
260b8e80941Smrg   return;
261b8e80941Smrg
262b8e80941Smrginvalid_pname:
263b8e80941Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
264b8e80941Smrg}
265b8e80941Smrg
266b8e80941Smrgstatic struct gl_memory_object *
267b8e80941Smrglookup_memory_object_err(struct gl_context *ctx, unsigned memory,
268b8e80941Smrg                         const char* func)
269b8e80941Smrg{
270b8e80941Smrg   if (memory == 0) {
271b8e80941Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
272b8e80941Smrg      return NULL;
273b8e80941Smrg   }
274b8e80941Smrg
275b8e80941Smrg   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
276b8e80941Smrg   if (!memObj)
277b8e80941Smrg      return NULL;
278b8e80941Smrg
279b8e80941Smrg   if (!memObj->Immutable) {
280b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
281b8e80941Smrg                  func);
282b8e80941Smrg      return NULL;
283b8e80941Smrg   }
284b8e80941Smrg
285b8e80941Smrg   return memObj;
286b8e80941Smrg}
287b8e80941Smrg
288b8e80941Smrg/**
289b8e80941Smrg * Helper used by _mesa_TexStorageMem1/2/3DEXT().
290b8e80941Smrg */
291b8e80941Smrgstatic void
292b8e80941Smrgtexstorage_memory(GLuint dims, GLenum target, GLsizei levels,
293b8e80941Smrg                  GLenum internalFormat, GLsizei width, GLsizei height,
294b8e80941Smrg                  GLsizei depth, GLuint memory, GLuint64 offset,
295b8e80941Smrg                  const char *func)
296b8e80941Smrg{
297b8e80941Smrg   struct gl_texture_object *texObj;
298b8e80941Smrg   struct gl_memory_object *memObj;
299b8e80941Smrg
300b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
301b8e80941Smrg
302b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
303b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
304b8e80941Smrg      return;
305b8e80941Smrg   }
306b8e80941Smrg
307b8e80941Smrg   texObj = _mesa_get_current_tex_object(ctx, target);
308b8e80941Smrg   if (!texObj)
309b8e80941Smrg      return;
310b8e80941Smrg
311b8e80941Smrg   memObj = lookup_memory_object_err(ctx, memory, func);
312b8e80941Smrg   if (!memObj)
313b8e80941Smrg      return;
314b8e80941Smrg
315b8e80941Smrg   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
316b8e80941Smrg                                levels, internalFormat,
317b8e80941Smrg                                width, height, depth, offset, false);
318b8e80941Smrg}
319b8e80941Smrg
320b8e80941Smrgstatic void
321b8e80941Smrgtexstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
322b8e80941Smrg                     GLenum internalFormat, GLsizei width, GLsizei height,
323b8e80941Smrg                     GLsizei depth, GLboolean fixedSampleLocations,
324b8e80941Smrg                     GLuint memory, GLuint64 offset, const char* func)
325b8e80941Smrg{
326b8e80941Smrg   struct gl_texture_object *texObj;
327b8e80941Smrg   struct gl_memory_object *memObj;
328b8e80941Smrg
329b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
330b8e80941Smrg
331b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
332b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
333b8e80941Smrg      return;
334b8e80941Smrg   }
335b8e80941Smrg
336b8e80941Smrg   texObj = _mesa_get_current_tex_object(ctx, target);
337b8e80941Smrg   if (!texObj)
338b8e80941Smrg      return;
339b8e80941Smrg
340b8e80941Smrg   memObj = lookup_memory_object_err(ctx, memory, func);
341b8e80941Smrg   if (!memObj)
342b8e80941Smrg      return;
343b8e80941Smrg
344b8e80941Smrg   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
345b8e80941Smrg                                   internalFormat, width, height, depth,
346b8e80941Smrg                                   fixedSampleLocations, offset, func);
347b8e80941Smrg}
348b8e80941Smrg
349b8e80941Smrg/**
350b8e80941Smrg * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
351b8e80941Smrg */
352b8e80941Smrgstatic void
353b8e80941Smrgtexturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
354b8e80941Smrg                      GLenum internalFormat, GLsizei width, GLsizei height,
355b8e80941Smrg                      GLsizei depth, GLuint memory, GLuint64 offset,
356b8e80941Smrg                      const char *func)
357b8e80941Smrg{
358b8e80941Smrg   struct gl_texture_object *texObj;
359b8e80941Smrg   struct gl_memory_object *memObj;
360b8e80941Smrg
361b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
362b8e80941Smrg
363b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
364b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
365b8e80941Smrg      return;
366b8e80941Smrg   }
367b8e80941Smrg
368b8e80941Smrg   texObj = _mesa_lookup_texture(ctx, texture);
369b8e80941Smrg   if (!texObj)
370b8e80941Smrg      return;
371b8e80941Smrg
372b8e80941Smrg   memObj = lookup_memory_object_err(ctx, memory, func);
373b8e80941Smrg   if (!memObj)
374b8e80941Smrg      return;
375b8e80941Smrg
376b8e80941Smrg   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
377b8e80941Smrg                                levels, internalFormat,
378b8e80941Smrg                                width, height, depth, offset, true);
379b8e80941Smrg}
380b8e80941Smrg
381b8e80941Smrgstatic void
382b8e80941Smrgtexturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
383b8e80941Smrg                         GLenum internalFormat, GLsizei width, GLsizei height,
384b8e80941Smrg                         GLsizei depth, GLboolean fixedSampleLocations,
385b8e80941Smrg                         GLuint memory, GLuint64 offset, const char* func)
386b8e80941Smrg{
387b8e80941Smrg   struct gl_texture_object *texObj;
388b8e80941Smrg   struct gl_memory_object *memObj;
389b8e80941Smrg
390b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
391b8e80941Smrg
392b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object) {
393b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
394b8e80941Smrg      return;
395b8e80941Smrg   }
396b8e80941Smrg
397b8e80941Smrg   texObj = _mesa_lookup_texture(ctx, texture);
398b8e80941Smrg   if (!texObj)
399b8e80941Smrg      return;
400b8e80941Smrg
401b8e80941Smrg   memObj = lookup_memory_object_err(ctx, memory, func);
402b8e80941Smrg   if (!memObj)
403b8e80941Smrg      return;
404b8e80941Smrg
405b8e80941Smrg   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
406b8e80941Smrg                                   samples, internalFormat, width, height,
407b8e80941Smrg                                   depth, fixedSampleLocations, offset, func);
408b8e80941Smrg}
409b8e80941Smrg
410b8e80941Smrgvoid GLAPIENTRY
411b8e80941Smrg_mesa_TexStorageMem2DEXT(GLenum target,
412b8e80941Smrg                         GLsizei levels,
413b8e80941Smrg                         GLenum internalFormat,
414b8e80941Smrg                         GLsizei width,
415b8e80941Smrg                         GLsizei height,
416b8e80941Smrg                         GLuint memory,
417b8e80941Smrg                         GLuint64 offset)
418b8e80941Smrg{
419b8e80941Smrg   texstorage_memory(2, target, levels, internalFormat, width, height, 1,
420b8e80941Smrg                     memory, offset, "glTexStorageMem2DEXT");
421b8e80941Smrg}
422b8e80941Smrg
423b8e80941Smrgvoid GLAPIENTRY
424b8e80941Smrg_mesa_TexStorageMem2DMultisampleEXT(GLenum target,
425b8e80941Smrg                                    GLsizei samples,
426b8e80941Smrg                                    GLenum internalFormat,
427b8e80941Smrg                                    GLsizei width,
428b8e80941Smrg                                    GLsizei height,
429b8e80941Smrg                                    GLboolean fixedSampleLocations,
430b8e80941Smrg                                    GLuint memory,
431b8e80941Smrg                                    GLuint64 offset)
432b8e80941Smrg{
433b8e80941Smrg   texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
434b8e80941Smrg                        fixedSampleLocations, memory, offset,
435b8e80941Smrg                        "glTexStorageMem2DMultisampleEXT");
436b8e80941Smrg}
437b8e80941Smrg
438b8e80941Smrgvoid GLAPIENTRY
439b8e80941Smrg_mesa_TexStorageMem3DEXT(GLenum target,
440b8e80941Smrg                         GLsizei levels,
441b8e80941Smrg                         GLenum internalFormat,
442b8e80941Smrg                         GLsizei width,
443b8e80941Smrg                         GLsizei height,
444b8e80941Smrg                         GLsizei depth,
445b8e80941Smrg                         GLuint memory,
446b8e80941Smrg                         GLuint64 offset)
447b8e80941Smrg{
448b8e80941Smrg   texstorage_memory(3, target, levels, internalFormat, width, height, depth,
449b8e80941Smrg                     memory, offset, "glTexStorageMem3DEXT");
450b8e80941Smrg}
451b8e80941Smrg
452b8e80941Smrgvoid GLAPIENTRY
453b8e80941Smrg_mesa_TexStorageMem3DMultisampleEXT(GLenum target,
454b8e80941Smrg                                    GLsizei samples,
455b8e80941Smrg                                    GLenum internalFormat,
456b8e80941Smrg                                    GLsizei width,
457b8e80941Smrg                                    GLsizei height,
458b8e80941Smrg                                    GLsizei depth,
459b8e80941Smrg                                    GLboolean fixedSampleLocations,
460b8e80941Smrg                                    GLuint memory,
461b8e80941Smrg                                    GLuint64 offset)
462b8e80941Smrg{
463b8e80941Smrg   texstorage_memory_ms(3, target, samples, internalFormat, width, height,
464b8e80941Smrg                        depth, fixedSampleLocations, memory, offset,
465b8e80941Smrg                        "glTexStorageMem3DMultisampleEXT");
466b8e80941Smrg}
467b8e80941Smrg
468b8e80941Smrgvoid GLAPIENTRY
469b8e80941Smrg_mesa_TextureStorageMem2DEXT(GLuint texture,
470b8e80941Smrg                             GLsizei levels,
471b8e80941Smrg                             GLenum internalFormat,
472b8e80941Smrg                             GLsizei width,
473b8e80941Smrg                             GLsizei height,
474b8e80941Smrg                             GLuint memory,
475b8e80941Smrg                             GLuint64 offset)
476b8e80941Smrg{
477b8e80941Smrg   texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
478b8e80941Smrg                         memory, offset, "glTexureStorageMem2DEXT");
479b8e80941Smrg}
480b8e80941Smrg
481b8e80941Smrgvoid GLAPIENTRY
482b8e80941Smrg_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
483b8e80941Smrg                                        GLsizei samples,
484b8e80941Smrg                                        GLenum internalFormat,
485b8e80941Smrg                                        GLsizei width,
486b8e80941Smrg                                        GLsizei height,
487b8e80941Smrg                                        GLboolean fixedSampleLocations,
488b8e80941Smrg                                        GLuint memory,
489b8e80941Smrg                                        GLuint64 offset)
490b8e80941Smrg{
491b8e80941Smrg   texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
492b8e80941Smrg                            1, fixedSampleLocations, memory, offset,
493b8e80941Smrg                            "glTextureStorageMem2DMultisampleEXT");
494b8e80941Smrg}
495b8e80941Smrg
496b8e80941Smrgvoid GLAPIENTRY
497b8e80941Smrg_mesa_TextureStorageMem3DEXT(GLuint texture,
498b8e80941Smrg                             GLsizei levels,
499b8e80941Smrg                             GLenum internalFormat,
500b8e80941Smrg                             GLsizei width,
501b8e80941Smrg                             GLsizei height,
502b8e80941Smrg                             GLsizei depth,
503b8e80941Smrg                             GLuint memory,
504b8e80941Smrg                             GLuint64 offset)
505b8e80941Smrg{
506b8e80941Smrg   texturestorage_memory(3, texture, levels, internalFormat, width, height,
507b8e80941Smrg                         depth, memory, offset, "glTextureStorageMem3DEXT");
508b8e80941Smrg}
509b8e80941Smrg
510b8e80941Smrgvoid GLAPIENTRY
511b8e80941Smrg_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
512b8e80941Smrg                                        GLsizei samples,
513b8e80941Smrg                                        GLenum internalFormat,
514b8e80941Smrg                                        GLsizei width,
515b8e80941Smrg                                        GLsizei height,
516b8e80941Smrg                                        GLsizei depth,
517b8e80941Smrg                                        GLboolean fixedSampleLocations,
518b8e80941Smrg                                        GLuint memory,
519b8e80941Smrg                                        GLuint64 offset)
520b8e80941Smrg{
521b8e80941Smrg   texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
522b8e80941Smrg                            depth, fixedSampleLocations, memory, offset,
523b8e80941Smrg                            "glTextureStorageMem3DMultisampleEXT");
524b8e80941Smrg}
525b8e80941Smrg
526b8e80941Smrgvoid GLAPIENTRY
527b8e80941Smrg_mesa_TexStorageMem1DEXT(GLenum target,
528b8e80941Smrg                         GLsizei levels,
529b8e80941Smrg                         GLenum internalFormat,
530b8e80941Smrg                         GLsizei width,
531b8e80941Smrg                         GLuint memory,
532b8e80941Smrg                         GLuint64 offset)
533b8e80941Smrg{
534b8e80941Smrg   texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
535b8e80941Smrg                     offset, "glTexStorageMem1DEXT");
536b8e80941Smrg}
537b8e80941Smrg
538b8e80941Smrgvoid GLAPIENTRY
539b8e80941Smrg_mesa_TextureStorageMem1DEXT(GLuint texture,
540b8e80941Smrg                             GLsizei levels,
541b8e80941Smrg                             GLenum internalFormat,
542b8e80941Smrg                             GLsizei width,
543b8e80941Smrg                             GLuint memory,
544b8e80941Smrg                             GLuint64 offset)
545b8e80941Smrg{
546b8e80941Smrg   texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
547b8e80941Smrg                         memory, offset, "glTextureStorageMem1DEXT");
548b8e80941Smrg}
549b8e80941Smrg
550b8e80941Smrg/**
551b8e80941Smrg * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
552b8e80941Smrg * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
553b8e80941Smrg */
554b8e80941Smrgstatic struct gl_semaphore_object DummySemaphoreObject;
555b8e80941Smrg
556b8e80941Smrg/**
557b8e80941Smrg * Delete a semaphore object.  Called via ctx->Driver.DeleteSemaphore().
558b8e80941Smrg * Not removed from hash table here.
559b8e80941Smrg */
560b8e80941Smrgvoid
561b8e80941Smrg_mesa_delete_semaphore_object(struct gl_context *ctx,
562b8e80941Smrg                              struct gl_semaphore_object *semObj)
563b8e80941Smrg{
564b8e80941Smrg   if (semObj != &DummySemaphoreObject)
565b8e80941Smrg      free(semObj);
566b8e80941Smrg}
567b8e80941Smrg
568b8e80941Smrg/**
569b8e80941Smrg * Initialize a semaphore object to default values.
570b8e80941Smrg */
571b8e80941Smrgvoid
572b8e80941Smrg_mesa_initialize_semaphore_object(struct gl_context *ctx,
573b8e80941Smrg                                  struct gl_semaphore_object *obj,
574b8e80941Smrg                                  GLuint name)
575b8e80941Smrg{
576b8e80941Smrg   memset(obj, 0, sizeof(struct gl_semaphore_object));
577b8e80941Smrg   obj->Name = name;
578b8e80941Smrg}
579b8e80941Smrg
580b8e80941Smrgvoid GLAPIENTRY
581b8e80941Smrg_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
582b8e80941Smrg{
583b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
584b8e80941Smrg
585b8e80941Smrg   const char *func = "glGenSemaphoresEXT";
586b8e80941Smrg
587b8e80941Smrg   if (MESA_VERBOSE & (VERBOSE_API))
588b8e80941Smrg      _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores);
589b8e80941Smrg
590b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
591b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
592b8e80941Smrg      return;
593b8e80941Smrg   }
594b8e80941Smrg
595b8e80941Smrg   if (n < 0) {
596b8e80941Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
597b8e80941Smrg      return;
598b8e80941Smrg   }
599b8e80941Smrg
600b8e80941Smrg   if (!semaphores)
601b8e80941Smrg      return;
602b8e80941Smrg
603b8e80941Smrg   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
604b8e80941Smrg   GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SemaphoreObjects, n);
605b8e80941Smrg   if (first) {
606b8e80941Smrg      for (GLsizei i = 0; i < n; i++) {
607b8e80941Smrg         semaphores[i] = first + i;
608b8e80941Smrg         _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects,
609b8e80941Smrg                                semaphores[i], &DummySemaphoreObject);
610b8e80941Smrg      }
611b8e80941Smrg   }
612b8e80941Smrg
613b8e80941Smrg   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
614b8e80941Smrg}
615b8e80941Smrg
616b8e80941Smrgvoid GLAPIENTRY
617b8e80941Smrg_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
618b8e80941Smrg{
619b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
620b8e80941Smrg
621b8e80941Smrg   const char *func = "glDeleteSemaphoresEXT";
622b8e80941Smrg
623b8e80941Smrg   if (MESA_VERBOSE & (VERBOSE_API)) {
624b8e80941Smrg      _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
625b8e80941Smrg   }
626b8e80941Smrg
627b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
628b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
629b8e80941Smrg      return;
630b8e80941Smrg   }
631b8e80941Smrg
632b8e80941Smrg   if (n < 0) {
633b8e80941Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
634b8e80941Smrg      return;
635b8e80941Smrg   }
636b8e80941Smrg
637b8e80941Smrg   if (!semaphores)
638b8e80941Smrg      return;
639b8e80941Smrg
640b8e80941Smrg   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
641b8e80941Smrg   for (GLint i = 0; i < n; i++) {
642b8e80941Smrg      if (semaphores[i] > 0) {
643b8e80941Smrg         struct gl_semaphore_object *delObj
644b8e80941Smrg            = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]);
645b8e80941Smrg
646b8e80941Smrg         if (delObj) {
647b8e80941Smrg            _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects,
648b8e80941Smrg                                   semaphores[i]);
649b8e80941Smrg            ctx->Driver.DeleteSemaphoreObject(ctx, delObj);
650b8e80941Smrg         }
651b8e80941Smrg      }
652b8e80941Smrg   }
653b8e80941Smrg   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
654b8e80941Smrg}
655b8e80941Smrg
656b8e80941SmrgGLboolean GLAPIENTRY
657b8e80941Smrg_mesa_IsSemaphoreEXT(GLuint semaphore)
658b8e80941Smrg{
659b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
660b8e80941Smrg
661b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
662b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)");
663b8e80941Smrg      return GL_FALSE;
664b8e80941Smrg   }
665b8e80941Smrg
666b8e80941Smrg   struct gl_semaphore_object *obj =
667b8e80941Smrg      _mesa_lookup_semaphore_object(ctx, semaphore);
668b8e80941Smrg
669b8e80941Smrg   return obj ? GL_TRUE : GL_FALSE;
670b8e80941Smrg}
671b8e80941Smrg
672b8e80941Smrg/**
673b8e80941Smrg * Helper that outputs the correct error status for parameter
674b8e80941Smrg * calls where no pnames are defined
675b8e80941Smrg */
676b8e80941Smrgstatic void
677b8e80941Smrgsemaphore_parameter_stub(const char* func, GLenum pname)
678b8e80941Smrg{
679b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
680b8e80941Smrg
681b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
682b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
683b8e80941Smrg      return;
684b8e80941Smrg   }
685b8e80941Smrg
686b8e80941Smrg   /* EXT_semaphore and EXT_semaphore_fd define no parameters */
687b8e80941Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
688b8e80941Smrg}
689b8e80941Smrg
690b8e80941Smrgvoid GLAPIENTRY
691b8e80941Smrg_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
692b8e80941Smrg                                 GLenum pname,
693b8e80941Smrg                                 const GLuint64 *params)
694b8e80941Smrg{
695b8e80941Smrg   const char *func = "glSemaphoreParameterui64vEXT";
696b8e80941Smrg
697b8e80941Smrg   semaphore_parameter_stub(func, pname);
698b8e80941Smrg}
699b8e80941Smrg
700b8e80941Smrgvoid GLAPIENTRY
701b8e80941Smrg_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
702b8e80941Smrg                                    GLenum pname,
703b8e80941Smrg                                    GLuint64 *params)
704b8e80941Smrg{
705b8e80941Smrg   const char *func = "glGetSemaphoreParameterui64vEXT";
706b8e80941Smrg
707b8e80941Smrg   semaphore_parameter_stub(func, pname);
708b8e80941Smrg}
709b8e80941Smrg
710b8e80941Smrgvoid GLAPIENTRY
711b8e80941Smrg_mesa_WaitSemaphoreEXT(GLuint semaphore,
712b8e80941Smrg                       GLuint numBufferBarriers,
713b8e80941Smrg                       const GLuint *buffers,
714b8e80941Smrg                       GLuint numTextureBarriers,
715b8e80941Smrg                       const GLuint *textures,
716b8e80941Smrg                       const GLenum *srcLayouts)
717b8e80941Smrg{
718b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
719b8e80941Smrg   struct gl_semaphore_object *semObj = NULL;
720b8e80941Smrg   struct gl_buffer_object **bufObjs = NULL;
721b8e80941Smrg   struct gl_texture_object **texObjs = NULL;
722b8e80941Smrg
723b8e80941Smrg   const char *func = "glWaitSemaphoreEXT";
724b8e80941Smrg
725b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
726b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
727b8e80941Smrg      return;
728b8e80941Smrg   }
729b8e80941Smrg
730b8e80941Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
731b8e80941Smrg
732b8e80941Smrg   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
733b8e80941Smrg   if (!semObj)
734b8e80941Smrg      return;
735b8e80941Smrg
736b8e80941Smrg   FLUSH_VERTICES(ctx, 0);
737b8e80941Smrg   FLUSH_CURRENT(ctx, 0);
738b8e80941Smrg
739b8e80941Smrg   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
740b8e80941Smrg   if (!bufObjs) {
741b8e80941Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
742b8e80941Smrg                  func, numBufferBarriers);
743b8e80941Smrg      goto end;
744b8e80941Smrg   }
745b8e80941Smrg
746b8e80941Smrg   for (unsigned i = 0; i < numBufferBarriers; i++) {
747b8e80941Smrg      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
748b8e80941Smrg   }
749b8e80941Smrg
750b8e80941Smrg   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
751b8e80941Smrg   if (!texObjs) {
752b8e80941Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
753b8e80941Smrg                  func, numTextureBarriers);
754b8e80941Smrg      goto end;
755b8e80941Smrg   }
756b8e80941Smrg
757b8e80941Smrg   for (unsigned i = 0; i < numTextureBarriers; i++) {
758b8e80941Smrg      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
759b8e80941Smrg   }
760b8e80941Smrg
761b8e80941Smrg   ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj,
762b8e80941Smrg                                         numBufferBarriers, bufObjs,
763b8e80941Smrg                                         numTextureBarriers, texObjs,
764b8e80941Smrg                                         srcLayouts);
765b8e80941Smrg
766b8e80941Smrgend:
767b8e80941Smrg   free(bufObjs);
768b8e80941Smrg   free(texObjs);
769b8e80941Smrg}
770b8e80941Smrg
771b8e80941Smrgvoid GLAPIENTRY
772b8e80941Smrg_mesa_SignalSemaphoreEXT(GLuint semaphore,
773b8e80941Smrg                         GLuint numBufferBarriers,
774b8e80941Smrg                         const GLuint *buffers,
775b8e80941Smrg                         GLuint numTextureBarriers,
776b8e80941Smrg                         const GLuint *textures,
777b8e80941Smrg                         const GLenum *dstLayouts)
778b8e80941Smrg{
779b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
780b8e80941Smrg   struct gl_semaphore_object *semObj = NULL;
781b8e80941Smrg   struct gl_buffer_object **bufObjs = NULL;
782b8e80941Smrg   struct gl_texture_object **texObjs = NULL;
783b8e80941Smrg
784b8e80941Smrg   const char *func = "glSignalSemaphoreEXT";
785b8e80941Smrg
786b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore) {
787b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
788b8e80941Smrg      return;
789b8e80941Smrg   }
790b8e80941Smrg
791b8e80941Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
792b8e80941Smrg
793b8e80941Smrg   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
794b8e80941Smrg   if (!semObj)
795b8e80941Smrg      return;
796b8e80941Smrg
797b8e80941Smrg   FLUSH_VERTICES(ctx, 0);
798b8e80941Smrg   FLUSH_CURRENT(ctx, 0);
799b8e80941Smrg
800b8e80941Smrg   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
801b8e80941Smrg   if (!bufObjs) {
802b8e80941Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
803b8e80941Smrg                  func, numBufferBarriers);
804b8e80941Smrg      goto end;
805b8e80941Smrg   }
806b8e80941Smrg
807b8e80941Smrg   for (unsigned i = 0; i < numBufferBarriers; i++) {
808b8e80941Smrg      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
809b8e80941Smrg   }
810b8e80941Smrg
811b8e80941Smrg   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
812b8e80941Smrg   if (!texObjs) {
813b8e80941Smrg      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
814b8e80941Smrg                  func, numTextureBarriers);
815b8e80941Smrg      goto end;
816b8e80941Smrg   }
817b8e80941Smrg
818b8e80941Smrg   for (unsigned i = 0; i < numTextureBarriers; i++) {
819b8e80941Smrg      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
820b8e80941Smrg   }
821b8e80941Smrg
822b8e80941Smrg   ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj,
823b8e80941Smrg                                           numBufferBarriers, bufObjs,
824b8e80941Smrg                                           numTextureBarriers, texObjs,
825b8e80941Smrg                                           dstLayouts);
826b8e80941Smrg
827b8e80941Smrgend:
828b8e80941Smrg   free(bufObjs);
829b8e80941Smrg   free(texObjs);
830b8e80941Smrg}
831b8e80941Smrg
832b8e80941Smrgvoid GLAPIENTRY
833b8e80941Smrg_mesa_ImportMemoryFdEXT(GLuint memory,
834b8e80941Smrg                        GLuint64 size,
835b8e80941Smrg                        GLenum handleType,
836b8e80941Smrg                        GLint fd)
837b8e80941Smrg{
838b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
839b8e80941Smrg
840b8e80941Smrg   const char *func = "glImportMemoryFdEXT";
841b8e80941Smrg
842b8e80941Smrg   if (!ctx->Extensions.EXT_memory_object_fd) {
843b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
844b8e80941Smrg      return;
845b8e80941Smrg   }
846b8e80941Smrg
847b8e80941Smrg   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
848b8e80941Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
849b8e80941Smrg      return;
850b8e80941Smrg   }
851b8e80941Smrg
852b8e80941Smrg   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
853b8e80941Smrg   if (!memObj)
854b8e80941Smrg      return;
855b8e80941Smrg
856b8e80941Smrg   ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
857b8e80941Smrg   memObj->Immutable = GL_TRUE;
858b8e80941Smrg}
859b8e80941Smrg
860b8e80941Smrgvoid GLAPIENTRY
861b8e80941Smrg_mesa_ImportSemaphoreFdEXT(GLuint semaphore,
862b8e80941Smrg                           GLenum handleType,
863b8e80941Smrg                           GLint fd)
864b8e80941Smrg{
865b8e80941Smrg   GET_CURRENT_CONTEXT(ctx);
866b8e80941Smrg
867b8e80941Smrg   const char *func = "glImportSemaphoreFdEXT";
868b8e80941Smrg
869b8e80941Smrg   if (!ctx->Extensions.EXT_semaphore_fd) {
870b8e80941Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
871b8e80941Smrg      return;
872b8e80941Smrg   }
873b8e80941Smrg
874b8e80941Smrg   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
875b8e80941Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
876b8e80941Smrg      return;
877b8e80941Smrg   }
878b8e80941Smrg
879b8e80941Smrg   struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
880b8e80941Smrg                                                                      semaphore);
881b8e80941Smrg   if (!semObj)
882b8e80941Smrg      return;
883b8e80941Smrg
884b8e80941Smrg   if (semObj == &DummySemaphoreObject) {
885b8e80941Smrg      semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore);
886b8e80941Smrg      if (!semObj) {
887b8e80941Smrg         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
888b8e80941Smrg         return;
889b8e80941Smrg      }
890b8e80941Smrg      _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj);
891b8e80941Smrg   }
892b8e80941Smrg
893b8e80941Smrg   ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd);
894b8e80941Smrg}
895