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