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