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 */ 40static struct gl_texture_handle_object * 41lookup_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 */ 56static struct gl_image_handle_object * 57lookup_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 */ 72static void 73delete_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 */ 85static void 86delete_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 */ 98static inline bool 99is_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 */ 108static inline bool 109is_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 */ 118static void 119make_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 */ 168static void 169make_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 204static struct gl_texture_handle_object * 205find_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 216static GLuint64 217get_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 280static struct gl_image_handle_object * 281find_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 295static GLuint64 296get_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 */ 370void 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 377void 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 */ 387void 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 395void 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 */ 410void 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 417void 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 440void 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 */ 472void 473_mesa_init_sampler_handles(struct gl_sampler_object *sampObj) 474{ 475 util_dynarray_init(&sampObj->Handles, NULL); 476} 477 478void 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 497static GLboolean 498is_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 540GLuint64 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 554GLuint64 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 605GLuint64 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 622GLuint64 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 687void 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 698void 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 733void 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 744void 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 779GLuint64 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 794GLuint64 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 865void 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 876void 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 920void 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 931void 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 967GLboolean GLAPIENTRY 968_mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle) 969{ 970 GET_CURRENT_CONTEXT(ctx); 971 return is_texture_handle_resident(ctx, handle); 972} 973 974GLboolean 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 1000GLboolean GLAPIENTRY 1001_mesa_IsImageHandleResidentARB_no_error(GLuint64 handle) 1002{ 1003 GET_CURRENT_CONTEXT(ctx); 1004 return is_image_handle_resident(ctx, handle); 1005} 1006 1007GLboolean 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