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