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