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