mesa: Implement GL_ARB_texture_filter_anisotropic
[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 #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 *
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 *
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
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
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
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
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
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
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 *
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
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 *
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
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 }
331
332 /* Request a new image handle from the driver. */
333 handle = ctx->Driver.NewImageHandle(ctx, &imgObj);
334 if (!handle) {
335 mtx_unlock(&ctx->Shared->HandlesMutex);
336 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()");
337 return 0;
338 }
339
340 imgHandleObj = CALLOC_STRUCT(gl_image_handle_object);
341 if (!imgHandleObj) {
342 mtx_unlock(&ctx->Shared->HandlesMutex);
343 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()");
344 return 0;
345 }
346
347 /* Store the handle into the texture object. */
348 memcpy(&imgHandleObj->imgObj, &imgObj, sizeof(struct gl_image_unit));
349 imgHandleObj->handle = handle;
350 util_dynarray_append(&texObj->ImageHandles,
351 struct gl_image_handle_object *, imgHandleObj);
352
353 /* When referenced by one or more handles, texture objects are immutable. */
354 texObj->HandleAllocated = true;
355 if (texObj->Target == GL_TEXTURE_BUFFER)
356 texObj->BufferObject->HandleAllocated = true;
357 texObj->Sampler.HandleAllocated = true;
358
359 /* Store the handle in the shared state for all contexts. */
360 _mesa_hash_table_u64_insert(ctx->Shared->ImageHandles, handle, imgHandleObj);
361 mtx_unlock(&ctx->Shared->HandlesMutex);
362
363 return handle;
364 }
365
366 /**
367 * Init/free per-context resident handles.
368 */
369 void
370 _mesa_init_resident_handles(struct gl_context *ctx)
371 {
372 ctx->ResidentTextureHandles = _mesa_hash_table_u64_create(NULL);
373 ctx->ResidentImageHandles = _mesa_hash_table_u64_create(NULL);
374 }
375
376 void
377 _mesa_free_resident_handles(struct gl_context *ctx)
378 {
379 _mesa_hash_table_u64_destroy(ctx->ResidentTextureHandles, NULL);
380 _mesa_hash_table_u64_destroy(ctx->ResidentImageHandles, NULL);
381 }
382
383 /**
384 * Init/free shared allocated handles.
385 */
386 void
387 _mesa_init_shared_handles(struct gl_shared_state *shared)
388 {
389 shared->TextureHandles = _mesa_hash_table_u64_create(NULL);
390 shared->ImageHandles = _mesa_hash_table_u64_create(NULL);
391 mtx_init(&shared->HandlesMutex, mtx_recursive);
392 }
393
394 void
395 _mesa_free_shared_handles(struct gl_shared_state *shared)
396 {
397 if (shared->TextureHandles)
398 _mesa_hash_table_u64_destroy(shared->TextureHandles, NULL);
399
400 if (shared->ImageHandles)
401 _mesa_hash_table_u64_destroy(shared->ImageHandles, NULL);
402
403 mtx_destroy(&shared->HandlesMutex);
404 }
405
406 /**
407 * Init/free texture/image handles per-texture object.
408 */
409 void
410 _mesa_init_texture_handles(struct gl_texture_object *texObj)
411 {
412 util_dynarray_init(&texObj->SamplerHandles, NULL);
413 util_dynarray_init(&texObj->ImageHandles, NULL);
414 }
415
416 void
417 _mesa_make_texture_handles_non_resident(struct gl_context *ctx,
418 struct gl_texture_object *texObj)
419 {
420 mtx_lock(&ctx->Shared->HandlesMutex);
421
422 /* Texture handles */
423 util_dynarray_foreach(&texObj->SamplerHandles,
424 struct gl_texture_handle_object *, texHandleObj) {
425 if (is_texture_handle_resident(ctx, (*texHandleObj)->handle))
426 make_texture_handle_resident(ctx, *texHandleObj, false);
427 }
428
429 /* Image handles */
430 util_dynarray_foreach(&texObj->ImageHandles,
431 struct gl_image_handle_object *, imgHandleObj) {
432 if (is_image_handle_resident(ctx, (*imgHandleObj)->handle))
433 make_image_handle_resident(ctx, *imgHandleObj, GL_READ_ONLY, false);
434 }
435
436 mtx_unlock(&ctx->Shared->HandlesMutex);
437 }
438
439 void
440 _mesa_delete_texture_handles(struct gl_context *ctx,
441 struct gl_texture_object *texObj)
442 {
443 /* Texture handles */
444 util_dynarray_foreach(&texObj->SamplerHandles,
445 struct gl_texture_handle_object *, texHandleObj) {
446 struct gl_sampler_object *sampObj = (*texHandleObj)->sampObj;
447
448 if (sampObj) {
449 /* Delete the handle in the separate sampler object. */
450 util_dynarray_delete_unordered(&sampObj->Handles,
451 struct gl_texture_handle_object *,
452 *texHandleObj);
453 }
454 delete_texture_handle(ctx, (*texHandleObj)->handle);
455 free(*texHandleObj);
456 }
457 util_dynarray_fini(&texObj->SamplerHandles);
458
459 /* Image handles */
460 util_dynarray_foreach(&texObj->ImageHandles,
461 struct gl_image_handle_object *, imgHandleObj) {
462 delete_image_handle(ctx, (*imgHandleObj)->handle);
463 free(*imgHandleObj);
464 }
465 util_dynarray_fini(&texObj->ImageHandles);
466 }
467
468 /**
469 * Init/free texture handles per-sampler object.
470 */
471 void
472 _mesa_init_sampler_handles(struct gl_sampler_object *sampObj)
473 {
474 util_dynarray_init(&sampObj->Handles, NULL);
475 }
476
477 void
478 _mesa_delete_sampler_handles(struct gl_context *ctx,
479 struct gl_sampler_object *sampObj)
480 {
481 util_dynarray_foreach(&sampObj->Handles,
482 struct gl_texture_handle_object *, texHandleObj) {
483 struct gl_texture_object *texObj = (*texHandleObj)->texObj;
484
485 /* Delete the handle in the texture object. */
486 util_dynarray_delete_unordered(&texObj->SamplerHandles,
487 struct gl_texture_handle_object *,
488 *texHandleObj);
489
490 delete_texture_handle(ctx, (*texHandleObj)->handle);
491 free(*texHandleObj);
492 }
493 util_dynarray_fini(&sampObj->Handles);
494 }
495
496 static GLboolean
497 is_sampler_border_color_valid(struct gl_sampler_object *samp)
498 {
499 static const GLfloat valid_float_border_colors[4][4] = {
500 { 0.0, 0.0, 0.0, 0.0 },
501 { 0.0, 0.0, 0.0, 1.0 },
502 { 1.0, 1.0, 1.0, 0.0 },
503 { 1.0, 1.0, 1.0, 1.0 },
504 };
505 static const GLint valid_integer_border_colors[4][4] = {
506 { 0, 0, 0, 0 },
507 { 0, 0, 0, 1 },
508 { 1, 1, 1, 0 },
509 { 1, 1, 1, 1 },
510 };
511 size_t size = sizeof(samp->BorderColor.ui);
512
513 /* The ARB_bindless_texture spec says:
514 *
515 * "The error INVALID_OPERATION is generated if the border color (taken from
516 * the embedded sampler for GetTextureHandleARB or from the <sampler> for
517 * GetTextureSamplerHandleARB) is not one of the following allowed values.
518 * If the texture's base internal format is signed or unsigned integer,
519 * allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and (1,1,1,1). If
520 * the base internal format is not integer, allowed values are
521 * (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
522 * (1.0,1.0,1.0,1.0)."
523 */
524 if (!memcmp(samp->BorderColor.f, valid_float_border_colors[0], size) ||
525 !memcmp(samp->BorderColor.f, valid_float_border_colors[1], size) ||
526 !memcmp(samp->BorderColor.f, valid_float_border_colors[2], size) ||
527 !memcmp(samp->BorderColor.f, valid_float_border_colors[3], size))
528 return GL_TRUE;
529
530 if (!memcmp(samp->BorderColor.ui, valid_integer_border_colors[0], size) ||
531 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[1], size) ||
532 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[2], size) ||
533 !memcmp(samp->BorderColor.ui, valid_integer_border_colors[3], size))
534 return GL_TRUE;
535
536 return GL_FALSE;
537 }
538
539 GLuint64 GLAPIENTRY
540 _mesa_GetTextureHandleARB_no_error(GLuint texture)
541 {
542 struct gl_texture_object *texObj;
543
544 GET_CURRENT_CONTEXT(ctx);
545
546 texObj = _mesa_lookup_texture(ctx, texture);
547 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler))
548 _mesa_test_texobj_completeness(ctx, texObj);
549
550 return get_texture_handle(ctx, texObj, &texObj->Sampler);
551 }
552
553 GLuint64 GLAPIENTRY
554 _mesa_GetTextureHandleARB(GLuint texture)
555 {
556 struct gl_texture_object *texObj = NULL;
557
558 GET_CURRENT_CONTEXT(ctx);
559
560 if (!_mesa_has_ARB_bindless_texture(ctx)) {
561 _mesa_error(ctx, GL_INVALID_OPERATION,
562 "glGetTextureHandleARB(unsupported)");
563 return 0;
564 }
565
566 /* The ARB_bindless_texture spec says:
567 *
568 * "The error INVALID_VALUE is generated by GetTextureHandleARB or
569 * GetTextureSamplerHandleARB if <texture> is zero or not the name of an
570 * existing texture object."
571 */
572 if (texture > 0)
573 texObj = _mesa_lookup_texture(ctx, texture);
574
575 if (!texObj) {
576 _mesa_error(ctx, GL_INVALID_VALUE, "glGetTextureHandleARB(texture)");
577 return 0;
578 }
579
580 /* The ARB_bindless_texture spec says:
581 *
582 * "The error INVALID_OPERATION is generated by GetTextureHandleARB or
583 * GetTextureSamplerHandleARB if the texture object specified by <texture>
584 * is not complete."
585 */
586 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
587 _mesa_test_texobj_completeness(ctx, texObj);
588 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
589 _mesa_error(ctx, GL_INVALID_OPERATION,
590 "glGetTextureHandleARB(incomplete texture)");
591 return 0;
592 }
593 }
594
595 if (!is_sampler_border_color_valid(&texObj->Sampler)) {
596 _mesa_error(ctx, GL_INVALID_OPERATION,
597 "glGetTextureHandleARB(invalid border color)");
598 return 0;
599 }
600
601 return get_texture_handle(ctx, texObj, &texObj->Sampler);
602 }
603
604 GLuint64 GLAPIENTRY
605 _mesa_GetTextureSamplerHandleARB_no_error(GLuint texture, GLuint sampler)
606 {
607 struct gl_texture_object *texObj;
608 struct gl_sampler_object *sampObj;
609
610 GET_CURRENT_CONTEXT(ctx);
611
612 texObj = _mesa_lookup_texture(ctx, texture);
613 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
614
615 if (!_mesa_is_texture_complete(texObj, sampObj))
616 _mesa_test_texobj_completeness(ctx, texObj);
617
618 return get_texture_handle(ctx, texObj, sampObj);
619 }
620
621 GLuint64 GLAPIENTRY
622 _mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler)
623 {
624 struct gl_texture_object *texObj = NULL;
625 struct gl_sampler_object *sampObj;
626
627 GET_CURRENT_CONTEXT(ctx);
628
629 if (!_mesa_has_ARB_bindless_texture(ctx)) {
630 _mesa_error(ctx, GL_INVALID_OPERATION,
631 "glGetTextureSamplerHandleARB(unsupported)");
632 return 0;
633 }
634
635 /* The ARB_bindless_texture spec says:
636 *
637 * "The error INVALID_VALUE is generated by GetTextureHandleARB or
638 * GetTextureSamplerHandleARB if <texture> is zero or not the name of an
639 * existing texture object."
640 */
641 if (texture > 0)
642 texObj = _mesa_lookup_texture(ctx, texture);
643
644 if (!texObj) {
645 _mesa_error(ctx, GL_INVALID_VALUE,
646 "glGetTextureSamplerHandleARB(texture)");
647 return 0;
648 }
649
650 /* The ARB_bindless_texture spec says:
651 *
652 * "The error INVALID_VALUE is generated by GetTextureSamplerHandleARB if
653 * <sampler> is zero or is not the name of an existing sampler object."
654 */
655 sampObj = _mesa_lookup_samplerobj(ctx, sampler);
656 if (!sampObj) {
657 _mesa_error(ctx, GL_INVALID_VALUE,
658 "glGetTextureSamplerHandleARB(sampler)");
659 return 0;
660 }
661
662 /* The ARB_bindless_texture spec says:
663 *
664 * "The error INVALID_OPERATION is generated by GetTextureHandleARB or
665 * GetTextureSamplerHandleARB if the texture object specified by <texture>
666 * is not complete."
667 */
668 if (!_mesa_is_texture_complete(texObj, sampObj)) {
669 _mesa_test_texobj_completeness(ctx, texObj);
670 if (!_mesa_is_texture_complete(texObj, sampObj)) {
671 _mesa_error(ctx, GL_INVALID_OPERATION,
672 "glGetTextureSamplerHandleARB(incomplete texture)");
673 return 0;
674 }
675 }
676
677 if (!is_sampler_border_color_valid(sampObj)) {
678 _mesa_error(ctx, GL_INVALID_OPERATION,
679 "glGetTextureSamplerHandleARB(invalid border color)");
680 return 0;
681 }
682
683 return get_texture_handle(ctx, texObj, sampObj);
684 }
685
686 void GLAPIENTRY
687 _mesa_MakeTextureHandleResidentARB_no_error(GLuint64 handle)
688 {
689 struct gl_texture_handle_object *texHandleObj;
690
691 GET_CURRENT_CONTEXT(ctx);
692
693 texHandleObj = lookup_texture_handle(ctx, handle);
694 make_texture_handle_resident(ctx, texHandleObj, true);
695 }
696
697 void GLAPIENTRY
698 _mesa_MakeTextureHandleResidentARB(GLuint64 handle)
699 {
700 struct gl_texture_handle_object *texHandleObj;
701
702 GET_CURRENT_CONTEXT(ctx);
703
704 if (!_mesa_has_ARB_bindless_texture(ctx)) {
705 _mesa_error(ctx, GL_INVALID_OPERATION,
706 "glMakeTextureHandleResidentARB(unsupported)");
707 return;
708 }
709
710 /* The ARB_bindless_texture spec says:
711 *
712 * "The error INVALID_OPERATION is generated by MakeTextureHandleResidentARB
713 * if <handle> is not a valid texture handle, or if <handle> is already
714 * resident in the current GL context."
715 */
716 texHandleObj = lookup_texture_handle(ctx, handle);
717 if (!texHandleObj) {
718 _mesa_error(ctx, GL_INVALID_OPERATION,
719 "glMakeTextureHandleResidentARB(handle)");
720 return;
721 }
722
723 if (is_texture_handle_resident(ctx, handle)) {
724 _mesa_error(ctx, GL_INVALID_OPERATION,
725 "glMakeTextureHandleResidentARB(already resident)");
726 return;
727 }
728
729 make_texture_handle_resident(ctx, texHandleObj, true);
730 }
731
732 void GLAPIENTRY
733 _mesa_MakeTextureHandleNonResidentARB_no_error(GLuint64 handle)
734 {
735 struct gl_texture_handle_object *texHandleObj;
736
737 GET_CURRENT_CONTEXT(ctx);
738
739 texHandleObj = lookup_texture_handle(ctx, handle);
740 make_texture_handle_resident(ctx, texHandleObj, false);
741 }
742
743 void GLAPIENTRY
744 _mesa_MakeTextureHandleNonResidentARB(GLuint64 handle)
745 {
746 struct gl_texture_handle_object *texHandleObj;
747
748 GET_CURRENT_CONTEXT(ctx);
749
750 if (!_mesa_has_ARB_bindless_texture(ctx)) {
751 _mesa_error(ctx, GL_INVALID_OPERATION,
752 "glMakeTextureHandleNonResidentARB(unsupported)");
753 return;
754 }
755
756 /* The ARB_bindless_texture spec says:
757 *
758 * "The error INVALID_OPERATION is generated by
759 * MakeTextureHandleNonResidentARB if <handle> is not a valid texture
760 * handle, or if <handle> is not resident in the current GL context."
761 */
762 texHandleObj = lookup_texture_handle(ctx, handle);
763 if (!texHandleObj) {
764 _mesa_error(ctx, GL_INVALID_OPERATION,
765 "glMakeTextureHandleNonResidentARB(handle)");
766 return;
767 }
768
769 if (!is_texture_handle_resident(ctx, handle)) {
770 _mesa_error(ctx, GL_INVALID_OPERATION,
771 "glMakeTextureHandleNonResidentARB(not resident)");
772 return;
773 }
774
775 make_texture_handle_resident(ctx, texHandleObj, false);
776 }
777
778 GLuint64 GLAPIENTRY
779 _mesa_GetImageHandleARB_no_error(GLuint texture, GLint level, GLboolean layered,
780 GLint layer, GLenum format)
781 {
782 struct gl_texture_object *texObj;
783
784 GET_CURRENT_CONTEXT(ctx);
785
786 texObj = _mesa_lookup_texture(ctx, texture);
787 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler))
788 _mesa_test_texobj_completeness(ctx, texObj);
789
790 return get_image_handle(ctx, texObj, level, layered, layer, format);
791 }
792
793 GLuint64 GLAPIENTRY
794 _mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered,
795 GLint layer, GLenum format)
796 {
797 struct gl_texture_object *texObj = NULL;
798
799 GET_CURRENT_CONTEXT(ctx);
800
801 if (!_mesa_has_ARB_bindless_texture(ctx) ||
802 !_mesa_has_ARB_shader_image_load_store(ctx)) {
803 _mesa_error(ctx, GL_INVALID_OPERATION,
804 "glGetImageHandleARB(unsupported)");
805 return 0;
806 }
807
808 /* The ARB_bindless_texture spec says:
809 *
810 * "The error INVALID_VALUE is generated by GetImageHandleARB if <texture>
811 * is zero or not the name of an existing texture object, if the image for
812 * <level> does not existing in <texture>, or if <layered> is FALSE and
813 * <layer> is greater than or equal to the number of layers in the image at
814 * <level>."
815 */
816 if (texture > 0)
817 texObj = _mesa_lookup_texture(ctx, texture);
818
819 if (!texObj) {
820 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(texture)");
821 return 0;
822 }
823
824 if (level < 0 || level >= _mesa_max_texture_levels(ctx, texObj->Target)) {
825 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(level)");
826 return 0;
827 }
828
829 if (!layered && layer > _mesa_get_texture_layers(texObj, level)) {
830 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(layer)");
831 return 0;
832 }
833
834 if (!_mesa_is_shader_image_format_supported(ctx, format)) {
835 _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(format)");
836 return 0;
837 }
838
839 /* The ARB_bindless_texture spec says:
840 *
841 * "The error INVALID_OPERATION is generated by GetImageHandleARB if the
842 * texture object <texture> is not complete or if <layered> is TRUE and
843 * <texture> is not a three-dimensional, one-dimensional array, two
844 * dimensional array, cube map, or cube map array texture."
845 */
846 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
847 _mesa_test_texobj_completeness(ctx, texObj);
848 if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
849 _mesa_error(ctx, GL_INVALID_OPERATION,
850 "glGetImageHandleARB(incomplete texture)");
851 return 0;
852 }
853 }
854
855 if (layered && !_mesa_tex_target_is_layered(texObj->Target)) {
856 _mesa_error(ctx, GL_INVALID_OPERATION,
857 "glGetImageHandleARB(not layered)");
858 return 0;
859 }
860
861 return get_image_handle(ctx, texObj, level, layered, layer, format);
862 }
863
864 void GLAPIENTRY
865 _mesa_MakeImageHandleResidentARB_no_error(GLuint64 handle, GLenum access)
866 {
867 struct gl_image_handle_object *imgHandleObj;
868
869 GET_CURRENT_CONTEXT(ctx);
870
871 imgHandleObj = lookup_image_handle(ctx, handle);
872 make_image_handle_resident(ctx, imgHandleObj, access, true);
873 }
874
875 void GLAPIENTRY
876 _mesa_MakeImageHandleResidentARB(GLuint64 handle, GLenum access)
877 {
878 struct gl_image_handle_object *imgHandleObj;
879
880 GET_CURRENT_CONTEXT(ctx);
881
882 if (!_mesa_has_ARB_bindless_texture(ctx) ||
883 !_mesa_has_ARB_shader_image_load_store(ctx)) {
884 _mesa_error(ctx, GL_INVALID_OPERATION,
885 "glMakeImageHandleResidentARB(unsupported)");
886 return;
887 }
888
889 if (access != GL_READ_ONLY &&
890 access != GL_WRITE_ONLY &&
891 access != GL_READ_WRITE) {
892 _mesa_error(ctx, GL_INVALID_ENUM,
893 "glMakeImageHandleResidentARB(access)");
894 return;
895 }
896
897 /* The ARB_bindless_texture spec says:
898 *
899 * "The error INVALID_OPERATION is generated by MakeImageHandleResidentARB
900 * if <handle> is not a valid image handle, or if <handle> is already
901 * resident in the current GL context."
902 */
903 imgHandleObj = lookup_image_handle(ctx, handle);
904 if (!imgHandleObj) {
905 _mesa_error(ctx, GL_INVALID_OPERATION,
906 "glMakeImageHandleResidentARB(handle)");
907 return;
908 }
909
910 if (is_image_handle_resident(ctx, handle)) {
911 _mesa_error(ctx, GL_INVALID_OPERATION,
912 "glMakeImageHandleResidentARB(already resident)");
913 return;
914 }
915
916 make_image_handle_resident(ctx, imgHandleObj, access, true);
917 }
918
919 void GLAPIENTRY
920 _mesa_MakeImageHandleNonResidentARB_no_error(GLuint64 handle)
921 {
922 struct gl_image_handle_object *imgHandleObj;
923
924 GET_CURRENT_CONTEXT(ctx);
925
926 imgHandleObj = lookup_image_handle(ctx, handle);
927 make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false);
928 }
929
930 void GLAPIENTRY
931 _mesa_MakeImageHandleNonResidentARB(GLuint64 handle)
932 {
933 struct gl_image_handle_object *imgHandleObj;
934
935 GET_CURRENT_CONTEXT(ctx);
936
937 if (!_mesa_has_ARB_bindless_texture(ctx) ||
938 !_mesa_has_ARB_shader_image_load_store(ctx)) {
939 _mesa_error(ctx, GL_INVALID_OPERATION,
940 "glMakeImageHandleNonResidentARB(unsupported)");
941 return;
942 }
943
944 /* The ARB_bindless_texture spec says:
945 *
946 * "The error INVALID_OPERATION is generated by
947 * MakeImageHandleNonResidentARB if <handle> is not a valid image handle,
948 * or if <handle> is not resident in the current GL context."
949 */
950 imgHandleObj = lookup_image_handle(ctx, handle);
951 if (!imgHandleObj) {
952 _mesa_error(ctx, GL_INVALID_OPERATION,
953 "glMakeImageHandleNonResidentARB(handle)");
954 return;
955 }
956
957 if (!is_image_handle_resident(ctx, handle)) {
958 _mesa_error(ctx, GL_INVALID_OPERATION,
959 "glMakeImageHandleNonResidentARB(not resident)");
960 return;
961 }
962
963 make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false);
964 }
965
966 GLboolean GLAPIENTRY
967 _mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle)
968 {
969 GET_CURRENT_CONTEXT(ctx);
970 return is_texture_handle_resident(ctx, handle);
971 }
972
973 GLboolean GLAPIENTRY
974 _mesa_IsTextureHandleResidentARB(GLuint64 handle)
975 {
976 GET_CURRENT_CONTEXT(ctx);
977
978 if (!_mesa_has_ARB_bindless_texture(ctx)) {
979 _mesa_error(ctx, GL_INVALID_OPERATION,
980 "glIsTextureHandleResidentARB(unsupported)");
981 return GL_FALSE;
982 }
983
984 /* The ARB_bindless_texture spec says:
985 *
986 * "The error INVALID_OPERATION will be generated by
987 * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is
988 * not a valid texture or image handle, respectively."
989 */
990 if (!lookup_texture_handle(ctx, handle)) {
991 _mesa_error(ctx, GL_INVALID_OPERATION,
992 "glIsTextureHandleResidentARB(handle)");
993 return GL_FALSE;
994 }
995
996 return is_texture_handle_resident(ctx, handle);
997 }
998
999 GLboolean GLAPIENTRY
1000 _mesa_IsImageHandleResidentARB_no_error(GLuint64 handle)
1001 {
1002 GET_CURRENT_CONTEXT(ctx);
1003 return is_image_handle_resident(ctx, handle);
1004 }
1005
1006 GLboolean GLAPIENTRY
1007 _mesa_IsImageHandleResidentARB(GLuint64 handle)
1008 {
1009 GET_CURRENT_CONTEXT(ctx);
1010
1011 if (!_mesa_has_ARB_bindless_texture(ctx) ||
1012 !_mesa_has_ARB_shader_image_load_store(ctx)) {
1013 _mesa_error(ctx, GL_INVALID_OPERATION,
1014 "glIsImageHandleResidentARB(unsupported)");
1015 return GL_FALSE;
1016 }
1017
1018 /* The ARB_bindless_texture spec says:
1019 *
1020 * "The error INVALID_OPERATION will be generated by
1021 * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is
1022 * not a valid texture or image handle, respectively."
1023 */
1024 if (!lookup_image_handle(ctx, handle)) {
1025 _mesa_error(ctx, GL_INVALID_OPERATION,
1026 "glIsImageHandleResidentARB(handle)");
1027 return GL_FALSE;
1028 }
1029
1030 return is_image_handle_resident(ctx, handle);
1031 }