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