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