1 /* 2 * Copyright 2017 Valve Corporation. 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 "glheader.h" 25 #include "context.h" 26 #include "enums.h" 27 #include "imports.h" 28 #include "hash.h" 29 #include "mtypes.h" 30 #include "shaderimage.h" 31 #include "teximage.h" 32 #include "texobj.h" 33 #include "texturebindless.h" 34 35 #include "util/hash_table.h" 36 37 /** 38 * Return the gl_texture_handle_object for a given 64-bit handle. 39 */ 40 static struct gl_texture_handle_object * 41 lookup_texture_handle(struct gl_context *ctx, GLuint64 id) 42 { 43 struct gl_texture_handle_object *texHandleObj; 44 45 mtx_lock(&ctx->Shared->HandlesMutex); 46 texHandleObj = (struct gl_texture_handle_object *) 47 _mesa_hash_table_u64_search(ctx->Shared->TextureHandles, id); 48 mtx_unlock(&ctx->Shared->HandlesMutex); 49 50 return texHandleObj; 51 } 52 53 /** 54 * Return the gl_image_handle_object for a given 64-bit handle. 55 */ 56 static struct gl_image_handle_object * 57 lookup_image_handle(struct gl_context *ctx, GLuint64 id) 58 { 59 struct gl_image_handle_object *imgHandleObj; 60 61 mtx_lock(&ctx->Shared->HandlesMutex); 62 imgHandleObj = (struct gl_image_handle_object *) 63 _mesa_hash_table_u64_search(ctx->Shared->ImageHandles, id); 64 mtx_unlock(&ctx->Shared->HandlesMutex); 65 66 return imgHandleObj; 67 } 68 69 /** 70 * Delete a texture handle in the shared state. 71 */ 72 static void 73 delete_texture_handle(struct gl_context *ctx, GLuint64 id) 74 { 75 mtx_lock(&ctx->Shared->HandlesMutex); 76 _mesa_hash_table_u64_remove(ctx->Shared->TextureHandles, id); 77 mtx_unlock(&ctx->Shared->HandlesMutex); 78 79 ctx->Driver.DeleteTextureHandle(ctx, id); 80 } 81 82 /** 83 * Delete an image handle in the shared state. 84 */ 85 static void 86 delete_image_handle(struct gl_context *ctx, GLuint64 id) 87 { 88 mtx_lock(&ctx->Shared->HandlesMutex); 89 _mesa_hash_table_u64_remove(ctx->Shared->ImageHandles, id); 90 mtx_unlock(&ctx->Shared->HandlesMutex); 91 92 ctx->Driver.DeleteImageHandle(ctx, id); 93 } 94 95 /** 96 * Return TRUE if the texture handle is resident in the current context. 97 */ 98 static inline bool 99 is_texture_handle_resident(struct gl_context *ctx, GLuint64 handle) 100 { 101 return _mesa_hash_table_u64_search(ctx->ResidentTextureHandles, 102 handle) != NULL; 103 } 104 105 /** 106 * Return TRUE if the image handle is resident in the current context. 107 */ 108 static inline bool 109 is_image_handle_resident(struct gl_context *ctx, GLuint64 handle) 110 { 111 return _mesa_hash_table_u64_search(ctx->ResidentImageHandles, 112 handle) != NULL; 113 } 114 115 /** 116 * Make a texture handle resident/non-resident in the current context. 117 */ 118 static void 119 make_texture_handle_resident(struct gl_context *ctx, 120 struct gl_texture_handle_object *texHandleObj, 121 bool resident) 122 { 123 struct gl_sampler_object *sampObj = NULL; 124 struct gl_texture_object *texObj = NULL; 125 GLuint64 handle = texHandleObj->handle; 126 127 if (resident) { 128 assert(!is_texture_handle_resident(ctx, handle)); 129 130 _mesa_hash_table_u64_insert(ctx->ResidentTextureHandles, handle, 131 texHandleObj); 132 133 ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_TRUE); 134 135 /* Reference the texture object (and the separate sampler if needed) to 136 * be sure it won't be deleted until it is not bound anywhere and there 137 * are no handles using the object that are resident in any context. 138 */ 139 _mesa_reference_texobj(&texObj, texHandleObj->texObj); 140 if (texHandleObj->sampObj) 141 _mesa_reference_sampler_object(ctx, &sampObj, texHandleObj->sampObj); 142 } else { 143 assert(is_texture_handle_resident(ctx, handle)); 144 145 _mesa_hash_table_u64_remove(ctx->ResidentTextureHandles, handle); 146 147 ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_FALSE); 148 149 /* Unreference the texture object but keep the pointer intact, if 150 * refcount hits zero, the texture and all handles will be deleted. 151 */ 152 texObj = texHandleObj->texObj; 153 _mesa_reference_texobj(&texObj, NULL); 154 155 /* Unreference the separate sampler object but keep the pointer intact, 156 * if refcount hits zero, the sampler and all handles will be deleted. 157 */ 158 if (texHandleObj->sampObj) { 159 sampObj = texHandleObj->sampObj; 160 _mesa_reference_sampler_object(ctx, &sampObj, NULL); 161 } 162 } 163 } 164 165 /** 166 * Make an image handle resident/non-resident in the current context. 167 */ 168 static void 169 make_image_handle_resident(struct gl_context *ctx, 170 struct gl_image_handle_object *imgHandleObj, 171 GLenum access, bool resident) 172 { 173 struct gl_texture_object *texObj = NULL; 174 GLuint64 handle = imgHandleObj->handle; 175 176 if (resident) { 177 assert(!is_image_handle_resident(ctx, handle)); 178 179 _mesa_hash_table_u64_insert(ctx->ResidentImageHandles, handle, 180 imgHandleObj); 181 182 ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_TRUE); 183 184 /* Reference the texture object to be sure it won't be deleted until it 185 * is not bound anywhere and there are no handles using the object that 186 * are resident in any context. 187 */ 188 _mesa_reference_texobj(&texObj, imgHandleObj->imgObj.TexObj); 189 } else { 190 assert(is_image_handle_resident(ctx, handle)); 191 192 _mesa_hash_table_u64_remove(ctx->ResidentImageHandles, handle); 193 194 ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_FALSE); 195 196 /* Unreference the texture object but keep the pointer intact, if 197 * refcount hits zero, the texture and all handles will be deleted. 198 */ 199 texObj = imgHandleObj->imgObj.TexObj; 200 _mesa_reference_texobj(&texObj, NULL); 201 } 202 } 203 204 static struct gl_texture_handle_object * 205 find_texhandleobj(struct gl_texture_object *texObj, 206 struct gl_sampler_object *sampObj) 207 { 208 util_dynarray_foreach(&texObj->SamplerHandles, 209 struct gl_texture_handle_object *, texHandleObj) { 210 if ((*texHandleObj)->sampObj == sampObj) 211 return *texHandleObj; 212 } 213 return NULL; 214 } 215 216 static GLuint64 217 get_texture_handle(struct gl_context *ctx, struct gl_texture_object *texObj, 218 struct gl_sampler_object *sampObj) 219 { 220 bool separate_sampler = &texObj->Sampler != sampObj; 221 struct gl_texture_handle_object *texHandleObj; 222 GLuint64 handle; 223 224 /* The ARB_bindless_texture spec says: 225 * 226 * "The handle for each texture or texture/sampler pair is unique; the same 227 * handle will be returned if GetTextureHandleARB is called multiple times 228 * for the same texture or if GetTextureSamplerHandleARB is called multiple 229 * times for the same texture/sampler pair." 230 */ 231 mtx_lock(&ctx->Shared->HandlesMutex); 232 texHandleObj = find_texhandleobj(texObj, separate_sampler ? sampObj : NULL); 233 if (texHandleObj) { 234 mtx_unlock(&ctx->Shared->HandlesMutex); 235 return texHandleObj->handle; 236 } 237 238 /* Request a new texture handle from the driver. */ 239 handle = ctx->Driver.NewTextureHandle(ctx, texObj, sampObj); 240 if (!handle) { 241 mtx_unlock(&ctx->Shared->HandlesMutex); 242 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()"); 243 return 0; 244 } 245 246 texHandleObj = CALLOC_STRUCT(gl_texture_handle_object); 247 if (!texHandleObj) { 248 mtx_unlock(&ctx->Shared->HandlesMutex); 249 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()"); 250 return 0; 251 } 252 253 /* Store the handle into the texture object. */ 254 texHandleObj->texObj = texObj; 255 texHandleObj->sampObj = separate_sampler ? sampObj : NULL; 256 texHandleObj->handle = handle; 257 util_dynarray_append(&texObj->SamplerHandles, 258 struct gl_texture_handle_object *, texHandleObj); 259 260 if (separate_sampler) { 261 /* Store the handle into the separate sampler if needed. */ 262 util_dynarray_append(&sampObj->Handles, 263 struct gl_texture_handle_object *, texHandleObj); 264 } 265 266 /* When referenced by one or more handles, texture objects are immutable. */ 267 texObj->HandleAllocated = true; 268 if (texObj->Target == GL_TEXTURE_BUFFER) 269 texObj->BufferObject->HandleAllocated = true; 270 sampObj->HandleAllocated = true; 271 272 /* Store the handle in the shared state for all contexts. */ 273 _mesa_hash_table_u64_insert(ctx->Shared->TextureHandles, handle, 274 texHandleObj); 275 mtx_unlock(&ctx->Shared->HandlesMutex); 276 277 return handle; 278 } 279 280 static struct gl_image_handle_object * 281 find_imghandleobj(struct gl_texture_object *texObj, GLint level, 282 GLboolean layered, GLint layer, GLenum format) 283 { 284 util_dynarray_foreach(&texObj->ImageHandles, 285 struct gl_image_handle_object *, imgHandleObj) { 286 struct gl_image_unit *u = &(*imgHandleObj)->imgObj; 287 288 if (u->TexObj == texObj && u->Level == level && u->Layered == layered && 289 u->Layer == layer && u->Format == format) 290 return *imgHandleObj; 291 } 292 return NULL; 293 } 294 295 static GLuint64 296 get_image_handle(struct gl_context *ctx, struct gl_texture_object *texObj, 297 GLint level, GLboolean layered, GLint layer, GLenum format) 298 { 299 struct gl_image_handle_object *imgHandleObj; 300 struct gl_image_unit imgObj; 301 GLuint64 handle; 302 303 /* The ARB_bindless_texture spec says: 304 * 305 * "The handle returned for each combination of <texture>, <level>, 306 * <layered>, <layer>, and <format> is unique; the same handle will be 307 * returned if GetImageHandleARB is called multiple times with the same 308 * parameters." 309 */ 310 mtx_lock(&ctx->Shared->HandlesMutex); 311 imgHandleObj = find_imghandleobj(texObj, level, layered, layer, format); 312 if (imgHandleObj) { 313 mtx_unlock(&ctx->Shared->HandlesMutex); 314 return imgHandleObj->handle; 315 } 316 317 imgObj.TexObj = texObj; /* weak reference */ 318 imgObj.Level = level; 319 imgObj.Access = GL_READ_WRITE; 320 imgObj.Format = format; 321 imgObj._ActualFormat = _mesa_get_shader_image_format(format); 322 323 if (_mesa_tex_target_is_layered(texObj->Target)) { 324 imgObj.Layered = layered; 325 imgObj.Layer = layer; 326 imgObj._Layer = (imgObj.Layered ? 0 : imgObj.Layer); 327 } else { 328 imgObj.Layered = GL_FALSE; 329 imgObj.Layer = 0; 330 imgObj._Layer = 0; 331 } 332 333 /* Request a new image handle from the driver. */ 334 handle = ctx->Driver.NewImageHandle(ctx, &imgObj); 335 if (!handle) { 336 mtx_unlock(&ctx->Shared->HandlesMutex); 337 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()"); 338 return 0; 339 } 340 341 imgHandleObj = CALLOC_STRUCT(gl_image_handle_object); 342 if (!imgHandleObj) { 343 mtx_unlock(&ctx->Shared->HandlesMutex); 344 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()"); 345 return 0; 346 } 347 348 /* Store the handle into the texture object. */ 349 memcpy(&imgHandleObj->imgObj, &imgObj, sizeof(struct gl_image_unit)); 350 imgHandleObj->handle = handle; 351 util_dynarray_append(&texObj->ImageHandles, 352 struct gl_image_handle_object *, imgHandleObj); 353 354 /* When referenced by one or more handles, texture objects are immutable. */ 355 texObj->HandleAllocated = true; 356 if (texObj->Target == GL_TEXTURE_BUFFER) 357 texObj->BufferObject->HandleAllocated = true; 358 texObj->Sampler.HandleAllocated = true; 359 360 /* Store the handle in the shared state for all contexts. */ 361 _mesa_hash_table_u64_insert(ctx->Shared->ImageHandles, handle, imgHandleObj); 362 mtx_unlock(&ctx->Shared->HandlesMutex); 363 364 return handle; 365 } 366 367 /** 368 * Init/free per-context resident handles. 369 */ 370 void 371 _mesa_init_resident_handles(struct gl_context *ctx) 372 { 373 ctx->ResidentTextureHandles = _mesa_hash_table_u64_create(NULL); 374 ctx->ResidentImageHandles = _mesa_hash_table_u64_create(NULL); 375 } 376 377 void 378 _mesa_free_resident_handles(struct gl_context *ctx) 379 { 380 _mesa_hash_table_u64_destroy(ctx->ResidentTextureHandles, NULL); 381 _mesa_hash_table_u64_destroy(ctx->ResidentImageHandles, NULL); 382 } 383 384 /** 385 * Init/free shared allocated handles. 386 */ 387 void 388 _mesa_init_shared_handles(struct gl_shared_state *shared) 389 { 390 shared->TextureHandles = _mesa_hash_table_u64_create(NULL); 391 shared->ImageHandles = _mesa_hash_table_u64_create(NULL); 392 mtx_init(&shared->HandlesMutex, mtx_recursive); 393 } 394 395 void 396 _mesa_free_shared_handles(struct gl_shared_state *shared) 397 { 398 if (shared->TextureHandles) 399 _mesa_hash_table_u64_destroy(shared->TextureHandles, NULL); 400 401 if (shared->ImageHandles) 402 _mesa_hash_table_u64_destroy(shared->ImageHandles, NULL); 403 404 mtx_destroy(&shared->HandlesMutex); 405 } 406 407 /** 408 * Init/free texture/image handles per-texture object. 409 */ 410 void 411 _mesa_init_texture_handles(struct gl_texture_object *texObj) 412 { 413 util_dynarray_init(&texObj->SamplerHandles, NULL); 414 util_dynarray_init(&texObj->ImageHandles, NULL); 415 } 416 417 void 418 _mesa_make_texture_handles_non_resident(struct gl_context *ctx, 419 struct gl_texture_object *texObj) 420 { 421 mtx_lock(&ctx->Shared->HandlesMutex); 422 423 /* Texture handles */ 424 util_dynarray_foreach(&texObj->SamplerHandles, 425 struct gl_texture_handle_object *, texHandleObj) { 426 if (is_texture_handle_resident(ctx, (*texHandleObj)->handle)) 427 make_texture_handle_resident(ctx, *texHandleObj, false); 428 } 429 430 /* Image handles */ 431 util_dynarray_foreach(&texObj->ImageHandles, 432 struct gl_image_handle_object *, imgHandleObj) { 433 if (is_image_handle_resident(ctx, (*imgHandleObj)->handle)) 434 make_image_handle_resident(ctx, *imgHandleObj, GL_READ_ONLY, false); 435 } 436 437 mtx_unlock(&ctx->Shared->HandlesMutex); 438 } 439 440 void 441 _mesa_delete_texture_handles(struct gl_context *ctx, 442 struct gl_texture_object *texObj) 443 { 444 /* Texture handles */ 445 util_dynarray_foreach(&texObj->SamplerHandles, 446 struct gl_texture_handle_object *, texHandleObj) { 447 struct gl_sampler_object *sampObj = (*texHandleObj)->sampObj; 448 449 if (sampObj) { 450 /* Delete the handle in the separate sampler object. */ 451 util_dynarray_delete_unordered(&sampObj->Handles, 452 struct gl_texture_handle_object *, 453 *texHandleObj); 454 } 455 delete_texture_handle(ctx, (*texHandleObj)->handle); 456 free(*texHandleObj); 457 } 458 util_dynarray_fini(&texObj->SamplerHandles); 459 460 /* Image handles */ 461 util_dynarray_foreach(&texObj->ImageHandles, 462 struct gl_image_handle_object *, imgHandleObj) { 463 delete_image_handle(ctx, (*imgHandleObj)->handle); 464 free(*imgHandleObj); 465 } 466 util_dynarray_fini(&texObj->ImageHandles); 467 } 468 469 /** 470 * Init/free texture handles per-sampler object. 471 */ 472 void 473 _mesa_init_sampler_handles(struct gl_sampler_object *sampObj) 474 { 475 util_dynarray_init(&sampObj->Handles, NULL); 476 } 477 478 void 479 _mesa_delete_sampler_handles(struct gl_context *ctx, 480 struct gl_sampler_object *sampObj) 481 { 482 util_dynarray_foreach(&sampObj->Handles, 483 struct gl_texture_handle_object *, texHandleObj) { 484 struct gl_texture_object *texObj = (*texHandleObj)->texObj; 485 486 /* Delete the handle in the texture object. */ 487 util_dynarray_delete_unordered(&texObj->SamplerHandles, 488 struct gl_texture_handle_object *, 489 *texHandleObj); 490 491 delete_texture_handle(ctx, (*texHandleObj)->handle); 492 free(*texHandleObj); 493 } 494 util_dynarray_fini(&sampObj->Handles); 495 } 496 497 static GLboolean 498 is_sampler_border_color_valid(struct gl_sampler_object *samp) 499 { 500 static const GLfloat valid_float_border_colors[4][4] = { 501 { 0.0, 0.0, 0.0, 0.0 }, 502 { 0.0, 0.0, 0.0, 1.0 }, 503 { 1.0, 1.0, 1.0, 0.0 }, 504 { 1.0, 1.0, 1.0, 1.0 }, 505 }; 506 static const GLint valid_integer_border_colors[4][4] = { 507 { 0, 0, 0, 0 }, 508 { 0, 0, 0, 1 }, 509 { 1, 1, 1, 0 }, 510 { 1, 1, 1, 1 }, 511 }; 512 size_t size = sizeof(samp->BorderColor.ui); 513 514 /* The ARB_bindless_texture spec says: 515 * 516 * "The error INVALID_OPERATION is generated if the border color (taken from 517 * the embedded sampler for GetTextureHandleARB or from the <sampler> for 518 * GetTextureSamplerHandleARB) is not one of the following allowed values. 519 * If the texture's base internal format is signed or unsigned integer, 520 * allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and (1,1,1,1). If 521 * the base internal format is not integer, allowed values are 522 * (0.0,0.0,0.0,0.0), (0.0,0.0,0.0,1.0), (1.0,1.0,1.0,0.0), and 523 * (1.0,1.0,1.0,1.0)." 524 */ 525 if (!memcmp(samp->BorderColor.f, valid_float_border_colors[0], size) || 526 !memcmp(samp->BorderColor.f, valid_float_border_colors[1], size) || 527 !memcmp(samp->BorderColor.f, valid_float_border_colors[2], size) || 528 !memcmp(samp->BorderColor.f, valid_float_border_colors[3], size)) 529 return GL_TRUE; 530 531 if (!memcmp(samp->BorderColor.ui, valid_integer_border_colors[0], size) || 532 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[1], size) || 533 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[2], size) || 534 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[3], size)) 535 return GL_TRUE; 536 537 return GL_FALSE; 538 } 539 540 GLuint64 GLAPIENTRY 541 _mesa_GetTextureHandleARB_no_error(GLuint texture) 542 { 543 struct gl_texture_object *texObj; 544 545 GET_CURRENT_CONTEXT(ctx); 546 547 texObj = _mesa_lookup_texture(ctx, texture); 548 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) 549 _mesa_test_texobj_completeness(ctx, texObj); 550 551 return get_texture_handle(ctx, texObj, &texObj->Sampler); 552 } 553 554 GLuint64 GLAPIENTRY 555 _mesa_GetTextureHandleARB(GLuint texture) 556 { 557 struct gl_texture_object *texObj = NULL; 558 559 GET_CURRENT_CONTEXT(ctx); 560 561 if (!_mesa_has_ARB_bindless_texture(ctx)) { 562 _mesa_error(ctx, GL_INVALID_OPERATION, 563 "glGetTextureHandleARB(unsupported)"); 564 return 0; 565 } 566 567 /* The ARB_bindless_texture spec says: 568 * 569 * "The error INVALID_VALUE is generated by GetTextureHandleARB or 570 * GetTextureSamplerHandleARB if <texture> is zero or not the name of an 571 * existing texture object." 572 */ 573 if (texture > 0) 574 texObj = _mesa_lookup_texture(ctx, texture); 575 576 if (!texObj) { 577 _mesa_error(ctx, GL_INVALID_VALUE, "glGetTextureHandleARB(texture)"); 578 return 0; 579 } 580 581 /* The ARB_bindless_texture spec says: 582 * 583 * "The error INVALID_OPERATION is generated by GetTextureHandleARB or 584 * GetTextureSamplerHandleARB if the texture object specified by <texture> 585 * is not complete." 586 */ 587 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 588 _mesa_test_texobj_completeness(ctx, texObj); 589 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 590 _mesa_error(ctx, GL_INVALID_OPERATION, 591 "glGetTextureHandleARB(incomplete texture)"); 592 return 0; 593 } 594 } 595 596 if (!is_sampler_border_color_valid(&texObj->Sampler)) { 597 _mesa_error(ctx, GL_INVALID_OPERATION, 598 "glGetTextureHandleARB(invalid border color)"); 599 return 0; 600 } 601 602 return get_texture_handle(ctx, texObj, &texObj->Sampler); 603 } 604 605 GLuint64 GLAPIENTRY 606 _mesa_GetTextureSamplerHandleARB_no_error(GLuint texture, GLuint sampler) 607 { 608 struct gl_texture_object *texObj; 609 struct gl_sampler_object *sampObj; 610 611 GET_CURRENT_CONTEXT(ctx); 612 613 texObj = _mesa_lookup_texture(ctx, texture); 614 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 615 616 if (!_mesa_is_texture_complete(texObj, sampObj)) 617 _mesa_test_texobj_completeness(ctx, texObj); 618 619 return get_texture_handle(ctx, texObj, sampObj); 620 } 621 622 GLuint64 GLAPIENTRY 623 _mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler) 624 { 625 struct gl_texture_object *texObj = NULL; 626 struct gl_sampler_object *sampObj; 627 628 GET_CURRENT_CONTEXT(ctx); 629 630 if (!_mesa_has_ARB_bindless_texture(ctx)) { 631 _mesa_error(ctx, GL_INVALID_OPERATION, 632 "glGetTextureSamplerHandleARB(unsupported)"); 633 return 0; 634 } 635 636 /* The ARB_bindless_texture spec says: 637 * 638 * "The error INVALID_VALUE is generated by GetTextureHandleARB or 639 * GetTextureSamplerHandleARB if <texture> is zero or not the name of an 640 * existing texture object." 641 */ 642 if (texture > 0) 643 texObj = _mesa_lookup_texture(ctx, texture); 644 645 if (!texObj) { 646 _mesa_error(ctx, GL_INVALID_VALUE, 647 "glGetTextureSamplerHandleARB(texture)"); 648 return 0; 649 } 650 651 /* The ARB_bindless_texture spec says: 652 * 653 * "The error INVALID_VALUE is generated by GetTextureSamplerHandleARB if 654 * <sampler> is zero or is not the name of an existing sampler object." 655 */ 656 sampObj = _mesa_lookup_samplerobj(ctx, sampler); 657 if (!sampObj) { 658 _mesa_error(ctx, GL_INVALID_VALUE, 659 "glGetTextureSamplerHandleARB(sampler)"); 660 return 0; 661 } 662 663 /* The ARB_bindless_texture spec says: 664 * 665 * "The error INVALID_OPERATION is generated by GetTextureHandleARB or 666 * GetTextureSamplerHandleARB if the texture object specified by <texture> 667 * is not complete." 668 */ 669 if (!_mesa_is_texture_complete(texObj, sampObj)) { 670 _mesa_test_texobj_completeness(ctx, texObj); 671 if (!_mesa_is_texture_complete(texObj, sampObj)) { 672 _mesa_error(ctx, GL_INVALID_OPERATION, 673 "glGetTextureSamplerHandleARB(incomplete texture)"); 674 return 0; 675 } 676 } 677 678 if (!is_sampler_border_color_valid(sampObj)) { 679 _mesa_error(ctx, GL_INVALID_OPERATION, 680 "glGetTextureSamplerHandleARB(invalid border color)"); 681 return 0; 682 } 683 684 return get_texture_handle(ctx, texObj, sampObj); 685 } 686 687 void GLAPIENTRY 688 _mesa_MakeTextureHandleResidentARB_no_error(GLuint64 handle) 689 { 690 struct gl_texture_handle_object *texHandleObj; 691 692 GET_CURRENT_CONTEXT(ctx); 693 694 texHandleObj = lookup_texture_handle(ctx, handle); 695 make_texture_handle_resident(ctx, texHandleObj, true); 696 } 697 698 void GLAPIENTRY 699 _mesa_MakeTextureHandleResidentARB(GLuint64 handle) 700 { 701 struct gl_texture_handle_object *texHandleObj; 702 703 GET_CURRENT_CONTEXT(ctx); 704 705 if (!_mesa_has_ARB_bindless_texture(ctx)) { 706 _mesa_error(ctx, GL_INVALID_OPERATION, 707 "glMakeTextureHandleResidentARB(unsupported)"); 708 return; 709 } 710 711 /* The ARB_bindless_texture spec says: 712 * 713 * "The error INVALID_OPERATION is generated by MakeTextureHandleResidentARB 714 * if <handle> is not a valid texture handle, or if <handle> is already 715 * resident in the current GL context." 716 */ 717 texHandleObj = lookup_texture_handle(ctx, handle); 718 if (!texHandleObj) { 719 _mesa_error(ctx, GL_INVALID_OPERATION, 720 "glMakeTextureHandleResidentARB(handle)"); 721 return; 722 } 723 724 if (is_texture_handle_resident(ctx, handle)) { 725 _mesa_error(ctx, GL_INVALID_OPERATION, 726 "glMakeTextureHandleResidentARB(already resident)"); 727 return; 728 } 729 730 make_texture_handle_resident(ctx, texHandleObj, true); 731 } 732 733 void GLAPIENTRY 734 _mesa_MakeTextureHandleNonResidentARB_no_error(GLuint64 handle) 735 { 736 struct gl_texture_handle_object *texHandleObj; 737 738 GET_CURRENT_CONTEXT(ctx); 739 740 texHandleObj = lookup_texture_handle(ctx, handle); 741 make_texture_handle_resident(ctx, texHandleObj, false); 742 } 743 744 void GLAPIENTRY 745 _mesa_MakeTextureHandleNonResidentARB(GLuint64 handle) 746 { 747 struct gl_texture_handle_object *texHandleObj; 748 749 GET_CURRENT_CONTEXT(ctx); 750 751 if (!_mesa_has_ARB_bindless_texture(ctx)) { 752 _mesa_error(ctx, GL_INVALID_OPERATION, 753 "glMakeTextureHandleNonResidentARB(unsupported)"); 754 return; 755 } 756 757 /* The ARB_bindless_texture spec says: 758 * 759 * "The error INVALID_OPERATION is generated by 760 * MakeTextureHandleNonResidentARB if <handle> is not a valid texture 761 * handle, or if <handle> is not resident in the current GL context." 762 */ 763 texHandleObj = lookup_texture_handle(ctx, handle); 764 if (!texHandleObj) { 765 _mesa_error(ctx, GL_INVALID_OPERATION, 766 "glMakeTextureHandleNonResidentARB(handle)"); 767 return; 768 } 769 770 if (!is_texture_handle_resident(ctx, handle)) { 771 _mesa_error(ctx, GL_INVALID_OPERATION, 772 "glMakeTextureHandleNonResidentARB(not resident)"); 773 return; 774 } 775 776 make_texture_handle_resident(ctx, texHandleObj, false); 777 } 778 779 GLuint64 GLAPIENTRY 780 _mesa_GetImageHandleARB_no_error(GLuint texture, GLint level, GLboolean layered, 781 GLint layer, GLenum format) 782 { 783 struct gl_texture_object *texObj; 784 785 GET_CURRENT_CONTEXT(ctx); 786 787 texObj = _mesa_lookup_texture(ctx, texture); 788 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) 789 _mesa_test_texobj_completeness(ctx, texObj); 790 791 return get_image_handle(ctx, texObj, level, layered, layer, format); 792 } 793 794 GLuint64 GLAPIENTRY 795 _mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered, 796 GLint layer, GLenum format) 797 { 798 struct gl_texture_object *texObj = NULL; 799 800 GET_CURRENT_CONTEXT(ctx); 801 802 if (!_mesa_has_ARB_bindless_texture(ctx) || 803 !_mesa_has_ARB_shader_image_load_store(ctx)) { 804 _mesa_error(ctx, GL_INVALID_OPERATION, 805 "glGetImageHandleARB(unsupported)"); 806 return 0; 807 } 808 809 /* The ARB_bindless_texture spec says: 810 * 811 * "The error INVALID_VALUE is generated by GetImageHandleARB if <texture> 812 * is zero or not the name of an existing texture object, if the image for 813 * <level> does not existing in <texture>, or if <layered> is FALSE and 814 * <layer> is greater than or equal to the number of layers in the image at 815 * <level>." 816 */ 817 if (texture > 0) 818 texObj = _mesa_lookup_texture(ctx, texture); 819 820 if (!texObj) { 821 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(texture)"); 822 return 0; 823 } 824 825 if (level < 0 || level >= _mesa_max_texture_levels(ctx, texObj->Target)) { 826 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(level)"); 827 return 0; 828 } 829 830 if (!layered && layer > _mesa_get_texture_layers(texObj, level)) { 831 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(layer)"); 832 return 0; 833 } 834 835 if (!_mesa_is_shader_image_format_supported(ctx, format)) { 836 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(format)"); 837 return 0; 838 } 839 840 /* The ARB_bindless_texture spec says: 841 * 842 * "The error INVALID_OPERATION is generated by GetImageHandleARB if the 843 * texture object <texture> is not complete or if <layered> is TRUE and 844 * <texture> is not a three-dimensional, one-dimensional array, two 845 * dimensional array, cube map, or cube map array texture." 846 */ 847 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 848 _mesa_test_texobj_completeness(ctx, texObj); 849 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 850 _mesa_error(ctx, GL_INVALID_OPERATION, 851 "glGetImageHandleARB(incomplete texture)"); 852 return 0; 853 } 854 } 855 856 if (layered && !_mesa_tex_target_is_layered(texObj->Target)) { 857 _mesa_error(ctx, GL_INVALID_OPERATION, 858 "glGetImageHandleARB(not layered)"); 859 return 0; 860 } 861 862 return get_image_handle(ctx, texObj, level, layered, layer, format); 863 } 864 865 void GLAPIENTRY 866 _mesa_MakeImageHandleResidentARB_no_error(GLuint64 handle, GLenum access) 867 { 868 struct gl_image_handle_object *imgHandleObj; 869 870 GET_CURRENT_CONTEXT(ctx); 871 872 imgHandleObj = lookup_image_handle(ctx, handle); 873 make_image_handle_resident(ctx, imgHandleObj, access, true); 874 } 875 876 void GLAPIENTRY 877 _mesa_MakeImageHandleResidentARB(GLuint64 handle, GLenum access) 878 { 879 struct gl_image_handle_object *imgHandleObj; 880 881 GET_CURRENT_CONTEXT(ctx); 882 883 if (!_mesa_has_ARB_bindless_texture(ctx) || 884 !_mesa_has_ARB_shader_image_load_store(ctx)) { 885 _mesa_error(ctx, GL_INVALID_OPERATION, 886 "glMakeImageHandleResidentARB(unsupported)"); 887 return; 888 } 889 890 if (access != GL_READ_ONLY && 891 access != GL_WRITE_ONLY && 892 access != GL_READ_WRITE) { 893 _mesa_error(ctx, GL_INVALID_ENUM, 894 "glMakeImageHandleResidentARB(access)"); 895 return; 896 } 897 898 /* The ARB_bindless_texture spec says: 899 * 900 * "The error INVALID_OPERATION is generated by MakeImageHandleResidentARB 901 * if <handle> is not a valid image handle, or if <handle> is already 902 * resident in the current GL context." 903 */ 904 imgHandleObj = lookup_image_handle(ctx, handle); 905 if (!imgHandleObj) { 906 _mesa_error(ctx, GL_INVALID_OPERATION, 907 "glMakeImageHandleResidentARB(handle)"); 908 return; 909 } 910 911 if (is_image_handle_resident(ctx, handle)) { 912 _mesa_error(ctx, GL_INVALID_OPERATION, 913 "glMakeImageHandleResidentARB(already resident)"); 914 return; 915 } 916 917 make_image_handle_resident(ctx, imgHandleObj, access, true); 918 } 919 920 void GLAPIENTRY 921 _mesa_MakeImageHandleNonResidentARB_no_error(GLuint64 handle) 922 { 923 struct gl_image_handle_object *imgHandleObj; 924 925 GET_CURRENT_CONTEXT(ctx); 926 927 imgHandleObj = lookup_image_handle(ctx, handle); 928 make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false); 929 } 930 931 void GLAPIENTRY 932 _mesa_MakeImageHandleNonResidentARB(GLuint64 handle) 933 { 934 struct gl_image_handle_object *imgHandleObj; 935 936 GET_CURRENT_CONTEXT(ctx); 937 938 if (!_mesa_has_ARB_bindless_texture(ctx) || 939 !_mesa_has_ARB_shader_image_load_store(ctx)) { 940 _mesa_error(ctx, GL_INVALID_OPERATION, 941 "glMakeImageHandleNonResidentARB(unsupported)"); 942 return; 943 } 944 945 /* The ARB_bindless_texture spec says: 946 * 947 * "The error INVALID_OPERATION is generated by 948 * MakeImageHandleNonResidentARB if <handle> is not a valid image handle, 949 * or if <handle> is not resident in the current GL context." 950 */ 951 imgHandleObj = lookup_image_handle(ctx, handle); 952 if (!imgHandleObj) { 953 _mesa_error(ctx, GL_INVALID_OPERATION, 954 "glMakeImageHandleNonResidentARB(handle)"); 955 return; 956 } 957 958 if (!is_image_handle_resident(ctx, handle)) { 959 _mesa_error(ctx, GL_INVALID_OPERATION, 960 "glMakeImageHandleNonResidentARB(not resident)"); 961 return; 962 } 963 964 make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false); 965 } 966 967 GLboolean GLAPIENTRY 968 _mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle) 969 { 970 GET_CURRENT_CONTEXT(ctx); 971 return is_texture_handle_resident(ctx, handle); 972 } 973 974 GLboolean GLAPIENTRY 975 _mesa_IsTextureHandleResidentARB(GLuint64 handle) 976 { 977 GET_CURRENT_CONTEXT(ctx); 978 979 if (!_mesa_has_ARB_bindless_texture(ctx)) { 980 _mesa_error(ctx, GL_INVALID_OPERATION, 981 "glIsTextureHandleResidentARB(unsupported)"); 982 return GL_FALSE; 983 } 984 985 /* The ARB_bindless_texture spec says: 986 * 987 * "The error INVALID_OPERATION will be generated by 988 * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is 989 * not a valid texture or image handle, respectively." 990 */ 991 if (!lookup_texture_handle(ctx, handle)) { 992 _mesa_error(ctx, GL_INVALID_OPERATION, 993 "glIsTextureHandleResidentARB(handle)"); 994 return GL_FALSE; 995 } 996 997 return is_texture_handle_resident(ctx, handle); 998 } 999 1000 GLboolean GLAPIENTRY 1001 _mesa_IsImageHandleResidentARB_no_error(GLuint64 handle) 1002 { 1003 GET_CURRENT_CONTEXT(ctx); 1004 return is_image_handle_resident(ctx, handle); 1005 } 1006 1007 GLboolean GLAPIENTRY 1008 _mesa_IsImageHandleResidentARB(GLuint64 handle) 1009 { 1010 GET_CURRENT_CONTEXT(ctx); 1011 1012 if (!_mesa_has_ARB_bindless_texture(ctx) || 1013 !_mesa_has_ARB_shader_image_load_store(ctx)) { 1014 _mesa_error(ctx, GL_INVALID_OPERATION, 1015 "glIsImageHandleResidentARB(unsupported)"); 1016 return GL_FALSE; 1017 } 1018 1019 /* The ARB_bindless_texture spec says: 1020 * 1021 * "The error INVALID_OPERATION will be generated by 1022 * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is 1023 * not a valid texture or image handle, respectively." 1024 */ 1025 if (!lookup_image_handle(ctx, handle)) { 1026 _mesa_error(ctx, GL_INVALID_OPERATION, 1027 "glIsImageHandleResidentARB(handle)"); 1028 return GL_FALSE; 1029 } 1030 1031 return is_image_handle_resident(ctx, handle); 1032 } 1033