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 */ 43static 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 */ 58void 59_mesa_delete_memory_object(struct gl_context *ctx, 60 struct gl_memory_object *memObj) 61{ 62 free(memObj); 63} 64 65void 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 */ 75void 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 85void 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 125GLboolean 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 142void 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 191void 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 227invalid_pname: 228 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 229} 230 231void 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 262invalid_pname: 263 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); 264} 265 266static struct gl_memory_object * 267lookup_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 */ 291static void 292texstorage_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 320static void 321texstorage_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 */ 352static void 353texturestorage_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 381static void 382texturestorage_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 410void 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 423void 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 438void 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 452void 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 468void 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 481void 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 496void 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 510void 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 526void 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 538void 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 */ 554static 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 */ 560void 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 */ 571void 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 580void 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 616void 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 656GLboolean 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 */ 676static void 677semaphore_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 690void 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 700void 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 710void 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 FLUSH_CURRENT(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 766end: 767 free(bufObjs); 768 free(texObjs); 769} 770 771void 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 FLUSH_CURRENT(ctx, 0); 799 800 bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers); 801 if (!bufObjs) { 802 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)", 803 func, numBufferBarriers); 804 goto end; 805 } 806 807 for (unsigned i = 0; i < numBufferBarriers; i++) { 808 bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]); 809 } 810 811 texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers); 812 if (!texObjs) { 813 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)", 814 func, numTextureBarriers); 815 goto end; 816 } 817 818 for (unsigned i = 0; i < numTextureBarriers; i++) { 819 texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); 820 } 821 822 ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj, 823 numBufferBarriers, bufObjs, 824 numTextureBarriers, texObjs, 825 dstLayouts); 826 827end: 828 free(bufObjs); 829 free(texObjs); 830} 831 832void GLAPIENTRY 833_mesa_ImportMemoryFdEXT(GLuint memory, 834 GLuint64 size, 835 GLenum handleType, 836 GLint fd) 837{ 838 GET_CURRENT_CONTEXT(ctx); 839 840 const char *func = "glImportMemoryFdEXT"; 841 842 if (!ctx->Extensions.EXT_memory_object_fd) { 843 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); 844 return; 845 } 846 847 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) { 848 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); 849 return; 850 } 851 852 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory); 853 if (!memObj) 854 return; 855 856 ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd); 857 memObj->Immutable = GL_TRUE; 858} 859 860void GLAPIENTRY 861_mesa_ImportSemaphoreFdEXT(GLuint semaphore, 862 GLenum handleType, 863 GLint fd) 864{ 865 GET_CURRENT_CONTEXT(ctx); 866 867 const char *func = "glImportSemaphoreFdEXT"; 868 869 if (!ctx->Extensions.EXT_semaphore_fd) { 870 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); 871 return; 872 } 873 874 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) { 875 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); 876 return; 877 } 878 879 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, 880 semaphore); 881 if (!semObj) 882 return; 883 884 if (semObj == &DummySemaphoreObject) { 885 semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore); 886 if (!semObj) { 887 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 888 return; 889 } 890 _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj); 891 } 892 893 ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd); 894} 895