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