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