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