• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
lookup_texture_handle(struct gl_context * ctx,GLuint64 id)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 *
lookup_image_handle(struct gl_context * ctx,GLuint64 id)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
delete_texture_handle(struct gl_context * ctx,GLuint64 id)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
delete_image_handle(struct gl_context * ctx,GLuint64 id)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
is_texture_handle_resident(struct gl_context * ctx,GLuint64 handle)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
is_image_handle_resident(struct gl_context * ctx,GLuint64 handle)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
make_texture_handle_resident(struct gl_context * ctx,struct gl_texture_handle_object * texHandleObj,bool resident)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
make_image_handle_resident(struct gl_context * ctx,struct gl_image_handle_object * imgHandleObj,GLenum access,bool resident)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 *
find_texhandleobj(struct gl_texture_object * texObj,struct gl_sampler_object * sampObj)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
get_texture_handle(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_sampler_object * sampObj)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 *
find_imghandleobj(struct gl_texture_object * texObj,GLint level,GLboolean layered,GLint layer,GLenum format)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
get_image_handle(struct gl_context * ctx,struct gl_texture_object * texObj,GLint level,GLboolean layered,GLint layer,GLenum format)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
_mesa_init_resident_handles(struct gl_context * ctx)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
_mesa_free_resident_handles(struct gl_context * ctx)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
_mesa_init_shared_handles(struct gl_shared_state * shared)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
_mesa_free_shared_handles(struct gl_shared_state * shared)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
_mesa_init_texture_handles(struct gl_texture_object * texObj)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
_mesa_make_texture_handles_non_resident(struct gl_context * ctx,struct gl_texture_object * texObj)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
_mesa_delete_texture_handles(struct gl_context * ctx,struct gl_texture_object * texObj)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
_mesa_init_sampler_handles(struct gl_sampler_object * sampObj)473 _mesa_init_sampler_handles(struct gl_sampler_object *sampObj)
474 {
475    util_dynarray_init(&sampObj->Handles, NULL);
476 }
477 
478 void
_mesa_delete_sampler_handles(struct gl_context * ctx,struct gl_sampler_object * sampObj)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
is_sampler_border_color_valid(struct gl_sampler_object * samp)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
_mesa_GetTextureHandleARB_no_error(GLuint texture)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
_mesa_GetTextureHandleARB(GLuint texture)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
_mesa_GetTextureSamplerHandleARB_no_error(GLuint texture,GLuint sampler)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
_mesa_GetTextureSamplerHandleARB(GLuint texture,GLuint sampler)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
_mesa_MakeTextureHandleResidentARB_no_error(GLuint64 handle)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
_mesa_MakeTextureHandleResidentARB(GLuint64 handle)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
_mesa_MakeTextureHandleNonResidentARB_no_error(GLuint64 handle)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
_mesa_MakeTextureHandleNonResidentARB(GLuint64 handle)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
_mesa_GetImageHandleARB_no_error(GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum format)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
_mesa_GetImageHandleARB(GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum format)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
_mesa_MakeImageHandleResidentARB_no_error(GLuint64 handle,GLenum access)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
_mesa_MakeImageHandleResidentARB(GLuint64 handle,GLenum access)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
_mesa_MakeImageHandleNonResidentARB_no_error(GLuint64 handle)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
_mesa_MakeImageHandleNonResidentARB(GLuint64 handle)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
_mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle)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
_mesa_IsTextureHandleResidentARB(GLuint64 handle)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
_mesa_IsImageHandleResidentARB_no_error(GLuint64 handle)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
_mesa_IsImageHandleResidentARB(GLuint64 handle)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