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