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