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