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