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