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