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