texturebindless.c revision 01e04c3f
101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2017 Valve Corporation. 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2101e04c3fSmrg * DEALINGS IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include "glheader.h" 2501e04c3fSmrg#include "context.h" 2601e04c3fSmrg#include "enums.h" 2701e04c3fSmrg#include "imports.h" 2801e04c3fSmrg#include "hash.h" 2901e04c3fSmrg#include "mtypes.h" 3001e04c3fSmrg#include "shaderimage.h" 3101e04c3fSmrg#include "teximage.h" 3201e04c3fSmrg#include "texobj.h" 3301e04c3fSmrg#include "texturebindless.h" 3401e04c3fSmrg 3501e04c3fSmrg#include "util/hash_table.h" 3601e04c3fSmrg 3701e04c3fSmrg/** 3801e04c3fSmrg * Return the gl_texture_handle_object for a given 64-bit handle. 3901e04c3fSmrg */ 4001e04c3fSmrgstatic struct gl_texture_handle_object * 4101e04c3fSmrglookup_texture_handle(struct gl_context *ctx, GLuint64 id) 4201e04c3fSmrg{ 4301e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 4401e04c3fSmrg 4501e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 4601e04c3fSmrg texHandleObj = (struct gl_texture_handle_object *) 4701e04c3fSmrg _mesa_hash_table_u64_search(ctx->Shared->TextureHandles, id); 4801e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 4901e04c3fSmrg 5001e04c3fSmrg return texHandleObj; 5101e04c3fSmrg} 5201e04c3fSmrg 5301e04c3fSmrg/** 5401e04c3fSmrg * Return the gl_image_handle_object for a given 64-bit handle. 5501e04c3fSmrg */ 5601e04c3fSmrgstatic struct gl_image_handle_object * 5701e04c3fSmrglookup_image_handle(struct gl_context *ctx, GLuint64 id) 5801e04c3fSmrg{ 5901e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 6001e04c3fSmrg 6101e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 6201e04c3fSmrg imgHandleObj = (struct gl_image_handle_object *) 6301e04c3fSmrg _mesa_hash_table_u64_search(ctx->Shared->ImageHandles, id); 6401e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 6501e04c3fSmrg 6601e04c3fSmrg return imgHandleObj; 6701e04c3fSmrg} 6801e04c3fSmrg 6901e04c3fSmrg/** 7001e04c3fSmrg * Delete a texture handle in the shared state. 7101e04c3fSmrg */ 7201e04c3fSmrgstatic void 7301e04c3fSmrgdelete_texture_handle(struct gl_context *ctx, GLuint64 id) 7401e04c3fSmrg{ 7501e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 7601e04c3fSmrg _mesa_hash_table_u64_remove(ctx->Shared->TextureHandles, id); 7701e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 7801e04c3fSmrg 7901e04c3fSmrg ctx->Driver.DeleteTextureHandle(ctx, id); 8001e04c3fSmrg} 8101e04c3fSmrg 8201e04c3fSmrg/** 8301e04c3fSmrg * Delete an image handle in the shared state. 8401e04c3fSmrg */ 8501e04c3fSmrgstatic void 8601e04c3fSmrgdelete_image_handle(struct gl_context *ctx, GLuint64 id) 8701e04c3fSmrg{ 8801e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 8901e04c3fSmrg _mesa_hash_table_u64_remove(ctx->Shared->ImageHandles, id); 9001e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 9101e04c3fSmrg 9201e04c3fSmrg ctx->Driver.DeleteImageHandle(ctx, id); 9301e04c3fSmrg} 9401e04c3fSmrg 9501e04c3fSmrg/** 9601e04c3fSmrg * Return TRUE if the texture handle is resident in the current context. 9701e04c3fSmrg */ 9801e04c3fSmrgstatic inline bool 9901e04c3fSmrgis_texture_handle_resident(struct gl_context *ctx, GLuint64 handle) 10001e04c3fSmrg{ 10101e04c3fSmrg return _mesa_hash_table_u64_search(ctx->ResidentTextureHandles, 10201e04c3fSmrg handle) != NULL; 10301e04c3fSmrg} 10401e04c3fSmrg 10501e04c3fSmrg/** 10601e04c3fSmrg * Return TRUE if the image handle is resident in the current context. 10701e04c3fSmrg */ 10801e04c3fSmrgstatic inline bool 10901e04c3fSmrgis_image_handle_resident(struct gl_context *ctx, GLuint64 handle) 11001e04c3fSmrg{ 11101e04c3fSmrg return _mesa_hash_table_u64_search(ctx->ResidentImageHandles, 11201e04c3fSmrg handle) != NULL; 11301e04c3fSmrg} 11401e04c3fSmrg 11501e04c3fSmrg/** 11601e04c3fSmrg * Make a texture handle resident/non-resident in the current context. 11701e04c3fSmrg */ 11801e04c3fSmrgstatic void 11901e04c3fSmrgmake_texture_handle_resident(struct gl_context *ctx, 12001e04c3fSmrg struct gl_texture_handle_object *texHandleObj, 12101e04c3fSmrg bool resident) 12201e04c3fSmrg{ 12301e04c3fSmrg struct gl_sampler_object *sampObj = NULL; 12401e04c3fSmrg struct gl_texture_object *texObj = NULL; 12501e04c3fSmrg GLuint64 handle = texHandleObj->handle; 12601e04c3fSmrg 12701e04c3fSmrg if (resident) { 12801e04c3fSmrg assert(!is_texture_handle_resident(ctx, handle)); 12901e04c3fSmrg 13001e04c3fSmrg _mesa_hash_table_u64_insert(ctx->ResidentTextureHandles, handle, 13101e04c3fSmrg texHandleObj); 13201e04c3fSmrg 13301e04c3fSmrg ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_TRUE); 13401e04c3fSmrg 13501e04c3fSmrg /* Reference the texture object (and the separate sampler if needed) to 13601e04c3fSmrg * be sure it won't be deleted until it is not bound anywhere and there 13701e04c3fSmrg * are no handles using the object that are resident in any context. 13801e04c3fSmrg */ 13901e04c3fSmrg _mesa_reference_texobj(&texObj, texHandleObj->texObj); 14001e04c3fSmrg if (texHandleObj->sampObj) 14101e04c3fSmrg _mesa_reference_sampler_object(ctx, &sampObj, texHandleObj->sampObj); 14201e04c3fSmrg } else { 14301e04c3fSmrg assert(is_texture_handle_resident(ctx, handle)); 14401e04c3fSmrg 14501e04c3fSmrg _mesa_hash_table_u64_remove(ctx->ResidentTextureHandles, handle); 14601e04c3fSmrg 14701e04c3fSmrg ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_FALSE); 14801e04c3fSmrg 14901e04c3fSmrg /* Unreference the texture object but keep the pointer intact, if 15001e04c3fSmrg * refcount hits zero, the texture and all handles will be deleted. 15101e04c3fSmrg */ 15201e04c3fSmrg texObj = texHandleObj->texObj; 15301e04c3fSmrg _mesa_reference_texobj(&texObj, NULL); 15401e04c3fSmrg 15501e04c3fSmrg /* Unreference the separate sampler object but keep the pointer intact, 15601e04c3fSmrg * if refcount hits zero, the sampler and all handles will be deleted. 15701e04c3fSmrg */ 15801e04c3fSmrg if (texHandleObj->sampObj) { 15901e04c3fSmrg sampObj = texHandleObj->sampObj; 16001e04c3fSmrg _mesa_reference_sampler_object(ctx, &sampObj, NULL); 16101e04c3fSmrg } 16201e04c3fSmrg } 16301e04c3fSmrg} 16401e04c3fSmrg 16501e04c3fSmrg/** 16601e04c3fSmrg * Make an image handle resident/non-resident in the current context. 16701e04c3fSmrg */ 16801e04c3fSmrgstatic void 16901e04c3fSmrgmake_image_handle_resident(struct gl_context *ctx, 17001e04c3fSmrg struct gl_image_handle_object *imgHandleObj, 17101e04c3fSmrg GLenum access, bool resident) 17201e04c3fSmrg{ 17301e04c3fSmrg struct gl_texture_object *texObj = NULL; 17401e04c3fSmrg GLuint64 handle = imgHandleObj->handle; 17501e04c3fSmrg 17601e04c3fSmrg if (resident) { 17701e04c3fSmrg assert(!is_image_handle_resident(ctx, handle)); 17801e04c3fSmrg 17901e04c3fSmrg _mesa_hash_table_u64_insert(ctx->ResidentImageHandles, handle, 18001e04c3fSmrg imgHandleObj); 18101e04c3fSmrg 18201e04c3fSmrg ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_TRUE); 18301e04c3fSmrg 18401e04c3fSmrg /* Reference the texture object to be sure it won't be deleted until it 18501e04c3fSmrg * is not bound anywhere and there are no handles using the object that 18601e04c3fSmrg * are resident in any context. 18701e04c3fSmrg */ 18801e04c3fSmrg _mesa_reference_texobj(&texObj, imgHandleObj->imgObj.TexObj); 18901e04c3fSmrg } else { 19001e04c3fSmrg assert(is_image_handle_resident(ctx, handle)); 19101e04c3fSmrg 19201e04c3fSmrg _mesa_hash_table_u64_remove(ctx->ResidentImageHandles, handle); 19301e04c3fSmrg 19401e04c3fSmrg ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_FALSE); 19501e04c3fSmrg 19601e04c3fSmrg /* Unreference the texture object but keep the pointer intact, if 19701e04c3fSmrg * refcount hits zero, the texture and all handles will be deleted. 19801e04c3fSmrg */ 19901e04c3fSmrg texObj = imgHandleObj->imgObj.TexObj; 20001e04c3fSmrg _mesa_reference_texobj(&texObj, NULL); 20101e04c3fSmrg } 20201e04c3fSmrg} 20301e04c3fSmrg 20401e04c3fSmrgstatic struct gl_texture_handle_object * 20501e04c3fSmrgfind_texhandleobj(struct gl_texture_object *texObj, 20601e04c3fSmrg struct gl_sampler_object *sampObj) 20701e04c3fSmrg{ 20801e04c3fSmrg util_dynarray_foreach(&texObj->SamplerHandles, 20901e04c3fSmrg struct gl_texture_handle_object *, texHandleObj) { 21001e04c3fSmrg if ((*texHandleObj)->sampObj == sampObj) 21101e04c3fSmrg return *texHandleObj; 21201e04c3fSmrg } 21301e04c3fSmrg return NULL; 21401e04c3fSmrg} 21501e04c3fSmrg 21601e04c3fSmrgstatic GLuint64 21701e04c3fSmrgget_texture_handle(struct gl_context *ctx, struct gl_texture_object *texObj, 21801e04c3fSmrg struct gl_sampler_object *sampObj) 21901e04c3fSmrg{ 22001e04c3fSmrg bool separate_sampler = &texObj->Sampler != sampObj; 22101e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 22201e04c3fSmrg GLuint64 handle; 22301e04c3fSmrg 22401e04c3fSmrg /* The ARB_bindless_texture spec says: 22501e04c3fSmrg * 22601e04c3fSmrg * "The handle for each texture or texture/sampler pair is unique; the same 22701e04c3fSmrg * handle will be returned if GetTextureHandleARB is called multiple times 22801e04c3fSmrg * for the same texture or if GetTextureSamplerHandleARB is called multiple 22901e04c3fSmrg * times for the same texture/sampler pair." 23001e04c3fSmrg */ 23101e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 23201e04c3fSmrg texHandleObj = find_texhandleobj(texObj, separate_sampler ? sampObj : NULL); 23301e04c3fSmrg if (texHandleObj) { 23401e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 23501e04c3fSmrg return texHandleObj->handle; 23601e04c3fSmrg } 23701e04c3fSmrg 23801e04c3fSmrg /* Request a new texture handle from the driver. */ 23901e04c3fSmrg handle = ctx->Driver.NewTextureHandle(ctx, texObj, sampObj); 24001e04c3fSmrg if (!handle) { 24101e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 24201e04c3fSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()"); 24301e04c3fSmrg return 0; 24401e04c3fSmrg } 24501e04c3fSmrg 24601e04c3fSmrg texHandleObj = CALLOC_STRUCT(gl_texture_handle_object); 24701e04c3fSmrg if (!texHandleObj) { 24801e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 24901e04c3fSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()"); 25001e04c3fSmrg return 0; 25101e04c3fSmrg } 25201e04c3fSmrg 25301e04c3fSmrg /* Store the handle into the texture object. */ 25401e04c3fSmrg texHandleObj->texObj = texObj; 25501e04c3fSmrg texHandleObj->sampObj = separate_sampler ? sampObj : NULL; 25601e04c3fSmrg texHandleObj->handle = handle; 25701e04c3fSmrg util_dynarray_append(&texObj->SamplerHandles, 25801e04c3fSmrg struct gl_texture_handle_object *, texHandleObj); 25901e04c3fSmrg 26001e04c3fSmrg if (separate_sampler) { 26101e04c3fSmrg /* Store the handle into the separate sampler if needed. */ 26201e04c3fSmrg util_dynarray_append(&sampObj->Handles, 26301e04c3fSmrg struct gl_texture_handle_object *, texHandleObj); 26401e04c3fSmrg } 26501e04c3fSmrg 26601e04c3fSmrg /* When referenced by one or more handles, texture objects are immutable. */ 26701e04c3fSmrg texObj->HandleAllocated = true; 26801e04c3fSmrg if (texObj->Target == GL_TEXTURE_BUFFER) 26901e04c3fSmrg texObj->BufferObject->HandleAllocated = true; 27001e04c3fSmrg sampObj->HandleAllocated = true; 27101e04c3fSmrg 27201e04c3fSmrg /* Store the handle in the shared state for all contexts. */ 27301e04c3fSmrg _mesa_hash_table_u64_insert(ctx->Shared->TextureHandles, handle, 27401e04c3fSmrg texHandleObj); 27501e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 27601e04c3fSmrg 27701e04c3fSmrg return handle; 27801e04c3fSmrg} 27901e04c3fSmrg 28001e04c3fSmrgstatic struct gl_image_handle_object * 28101e04c3fSmrgfind_imghandleobj(struct gl_texture_object *texObj, GLint level, 28201e04c3fSmrg GLboolean layered, GLint layer, GLenum format) 28301e04c3fSmrg{ 28401e04c3fSmrg util_dynarray_foreach(&texObj->ImageHandles, 28501e04c3fSmrg struct gl_image_handle_object *, imgHandleObj) { 28601e04c3fSmrg struct gl_image_unit *u = &(*imgHandleObj)->imgObj; 28701e04c3fSmrg 28801e04c3fSmrg if (u->TexObj == texObj && u->Level == level && u->Layered == layered && 28901e04c3fSmrg u->Layer == layer && u->Format == format) 29001e04c3fSmrg return *imgHandleObj; 29101e04c3fSmrg } 29201e04c3fSmrg return NULL; 29301e04c3fSmrg} 29401e04c3fSmrg 29501e04c3fSmrgstatic GLuint64 29601e04c3fSmrgget_image_handle(struct gl_context *ctx, struct gl_texture_object *texObj, 29701e04c3fSmrg GLint level, GLboolean layered, GLint layer, GLenum format) 29801e04c3fSmrg{ 29901e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 30001e04c3fSmrg struct gl_image_unit imgObj; 30101e04c3fSmrg GLuint64 handle; 30201e04c3fSmrg 30301e04c3fSmrg /* The ARB_bindless_texture spec says: 30401e04c3fSmrg * 30501e04c3fSmrg * "The handle returned for each combination of <texture>, <level>, 30601e04c3fSmrg * <layered>, <layer>, and <format> is unique; the same handle will be 30701e04c3fSmrg * returned if GetImageHandleARB is called multiple times with the same 30801e04c3fSmrg * parameters." 30901e04c3fSmrg */ 31001e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 31101e04c3fSmrg imgHandleObj = find_imghandleobj(texObj, level, layered, layer, format); 31201e04c3fSmrg if (imgHandleObj) { 31301e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 31401e04c3fSmrg return imgHandleObj->handle; 31501e04c3fSmrg } 31601e04c3fSmrg 31701e04c3fSmrg imgObj.TexObj = texObj; /* weak reference */ 31801e04c3fSmrg imgObj.Level = level; 31901e04c3fSmrg imgObj.Access = GL_READ_WRITE; 32001e04c3fSmrg imgObj.Format = format; 32101e04c3fSmrg imgObj._ActualFormat = _mesa_get_shader_image_format(format); 32201e04c3fSmrg 32301e04c3fSmrg if (_mesa_tex_target_is_layered(texObj->Target)) { 32401e04c3fSmrg imgObj.Layered = layered; 32501e04c3fSmrg imgObj.Layer = layer; 32601e04c3fSmrg imgObj._Layer = (imgObj.Layered ? 0 : imgObj.Layer); 32701e04c3fSmrg } else { 32801e04c3fSmrg imgObj.Layered = GL_FALSE; 32901e04c3fSmrg imgObj.Layer = 0; 33001e04c3fSmrg imgObj._Layer = 0; 33101e04c3fSmrg } 33201e04c3fSmrg 33301e04c3fSmrg /* Request a new image handle from the driver. */ 33401e04c3fSmrg handle = ctx->Driver.NewImageHandle(ctx, &imgObj); 33501e04c3fSmrg if (!handle) { 33601e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 33701e04c3fSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()"); 33801e04c3fSmrg return 0; 33901e04c3fSmrg } 34001e04c3fSmrg 34101e04c3fSmrg imgHandleObj = CALLOC_STRUCT(gl_image_handle_object); 34201e04c3fSmrg if (!imgHandleObj) { 34301e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 34401e04c3fSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()"); 34501e04c3fSmrg return 0; 34601e04c3fSmrg } 34701e04c3fSmrg 34801e04c3fSmrg /* Store the handle into the texture object. */ 34901e04c3fSmrg memcpy(&imgHandleObj->imgObj, &imgObj, sizeof(struct gl_image_unit)); 35001e04c3fSmrg imgHandleObj->handle = handle; 35101e04c3fSmrg util_dynarray_append(&texObj->ImageHandles, 35201e04c3fSmrg struct gl_image_handle_object *, imgHandleObj); 35301e04c3fSmrg 35401e04c3fSmrg /* When referenced by one or more handles, texture objects are immutable. */ 35501e04c3fSmrg texObj->HandleAllocated = true; 35601e04c3fSmrg if (texObj->Target == GL_TEXTURE_BUFFER) 35701e04c3fSmrg texObj->BufferObject->HandleAllocated = true; 35801e04c3fSmrg texObj->Sampler.HandleAllocated = true; 35901e04c3fSmrg 36001e04c3fSmrg /* Store the handle in the shared state for all contexts. */ 36101e04c3fSmrg _mesa_hash_table_u64_insert(ctx->Shared->ImageHandles, handle, imgHandleObj); 36201e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 36301e04c3fSmrg 36401e04c3fSmrg return handle; 36501e04c3fSmrg} 36601e04c3fSmrg 36701e04c3fSmrg/** 36801e04c3fSmrg * Init/free per-context resident handles. 36901e04c3fSmrg */ 37001e04c3fSmrgvoid 37101e04c3fSmrg_mesa_init_resident_handles(struct gl_context *ctx) 37201e04c3fSmrg{ 37301e04c3fSmrg ctx->ResidentTextureHandles = _mesa_hash_table_u64_create(NULL); 37401e04c3fSmrg ctx->ResidentImageHandles = _mesa_hash_table_u64_create(NULL); 37501e04c3fSmrg} 37601e04c3fSmrg 37701e04c3fSmrgvoid 37801e04c3fSmrg_mesa_free_resident_handles(struct gl_context *ctx) 37901e04c3fSmrg{ 38001e04c3fSmrg _mesa_hash_table_u64_destroy(ctx->ResidentTextureHandles, NULL); 38101e04c3fSmrg _mesa_hash_table_u64_destroy(ctx->ResidentImageHandles, NULL); 38201e04c3fSmrg} 38301e04c3fSmrg 38401e04c3fSmrg/** 38501e04c3fSmrg * Init/free shared allocated handles. 38601e04c3fSmrg */ 38701e04c3fSmrgvoid 38801e04c3fSmrg_mesa_init_shared_handles(struct gl_shared_state *shared) 38901e04c3fSmrg{ 39001e04c3fSmrg shared->TextureHandles = _mesa_hash_table_u64_create(NULL); 39101e04c3fSmrg shared->ImageHandles = _mesa_hash_table_u64_create(NULL); 39201e04c3fSmrg mtx_init(&shared->HandlesMutex, mtx_recursive); 39301e04c3fSmrg} 39401e04c3fSmrg 39501e04c3fSmrgvoid 39601e04c3fSmrg_mesa_free_shared_handles(struct gl_shared_state *shared) 39701e04c3fSmrg{ 39801e04c3fSmrg if (shared->TextureHandles) 39901e04c3fSmrg _mesa_hash_table_u64_destroy(shared->TextureHandles, NULL); 40001e04c3fSmrg 40101e04c3fSmrg if (shared->ImageHandles) 40201e04c3fSmrg _mesa_hash_table_u64_destroy(shared->ImageHandles, NULL); 40301e04c3fSmrg 40401e04c3fSmrg mtx_destroy(&shared->HandlesMutex); 40501e04c3fSmrg} 40601e04c3fSmrg 40701e04c3fSmrg/** 40801e04c3fSmrg * Init/free texture/image handles per-texture object. 40901e04c3fSmrg */ 41001e04c3fSmrgvoid 41101e04c3fSmrg_mesa_init_texture_handles(struct gl_texture_object *texObj) 41201e04c3fSmrg{ 41301e04c3fSmrg util_dynarray_init(&texObj->SamplerHandles, NULL); 41401e04c3fSmrg util_dynarray_init(&texObj->ImageHandles, NULL); 41501e04c3fSmrg} 41601e04c3fSmrg 41701e04c3fSmrgvoid 41801e04c3fSmrg_mesa_make_texture_handles_non_resident(struct gl_context *ctx, 41901e04c3fSmrg struct gl_texture_object *texObj) 42001e04c3fSmrg{ 42101e04c3fSmrg mtx_lock(&ctx->Shared->HandlesMutex); 42201e04c3fSmrg 42301e04c3fSmrg /* Texture handles */ 42401e04c3fSmrg util_dynarray_foreach(&texObj->SamplerHandles, 42501e04c3fSmrg struct gl_texture_handle_object *, texHandleObj) { 42601e04c3fSmrg if (is_texture_handle_resident(ctx, (*texHandleObj)->handle)) 42701e04c3fSmrg make_texture_handle_resident(ctx, *texHandleObj, false); 42801e04c3fSmrg } 42901e04c3fSmrg 43001e04c3fSmrg /* Image handles */ 43101e04c3fSmrg util_dynarray_foreach(&texObj->ImageHandles, 43201e04c3fSmrg struct gl_image_handle_object *, imgHandleObj) { 43301e04c3fSmrg if (is_image_handle_resident(ctx, (*imgHandleObj)->handle)) 43401e04c3fSmrg make_image_handle_resident(ctx, *imgHandleObj, GL_READ_ONLY, false); 43501e04c3fSmrg } 43601e04c3fSmrg 43701e04c3fSmrg mtx_unlock(&ctx->Shared->HandlesMutex); 43801e04c3fSmrg} 43901e04c3fSmrg 44001e04c3fSmrgvoid 44101e04c3fSmrg_mesa_delete_texture_handles(struct gl_context *ctx, 44201e04c3fSmrg struct gl_texture_object *texObj) 44301e04c3fSmrg{ 44401e04c3fSmrg /* Texture handles */ 44501e04c3fSmrg util_dynarray_foreach(&texObj->SamplerHandles, 44601e04c3fSmrg struct gl_texture_handle_object *, texHandleObj) { 44701e04c3fSmrg struct gl_sampler_object *sampObj = (*texHandleObj)->sampObj; 44801e04c3fSmrg 44901e04c3fSmrg if (sampObj) { 45001e04c3fSmrg /* Delete the handle in the separate sampler object. */ 45101e04c3fSmrg util_dynarray_delete_unordered(&sampObj->Handles, 45201e04c3fSmrg struct gl_texture_handle_object *, 45301e04c3fSmrg *texHandleObj); 45401e04c3fSmrg } 45501e04c3fSmrg delete_texture_handle(ctx, (*texHandleObj)->handle); 45601e04c3fSmrg free(*texHandleObj); 45701e04c3fSmrg } 45801e04c3fSmrg util_dynarray_fini(&texObj->SamplerHandles); 45901e04c3fSmrg 46001e04c3fSmrg /* Image handles */ 46101e04c3fSmrg util_dynarray_foreach(&texObj->ImageHandles, 46201e04c3fSmrg struct gl_image_handle_object *, imgHandleObj) { 46301e04c3fSmrg delete_image_handle(ctx, (*imgHandleObj)->handle); 46401e04c3fSmrg free(*imgHandleObj); 46501e04c3fSmrg } 46601e04c3fSmrg util_dynarray_fini(&texObj->ImageHandles); 46701e04c3fSmrg} 46801e04c3fSmrg 46901e04c3fSmrg/** 47001e04c3fSmrg * Init/free texture handles per-sampler object. 47101e04c3fSmrg */ 47201e04c3fSmrgvoid 47301e04c3fSmrg_mesa_init_sampler_handles(struct gl_sampler_object *sampObj) 47401e04c3fSmrg{ 47501e04c3fSmrg util_dynarray_init(&sampObj->Handles, NULL); 47601e04c3fSmrg} 47701e04c3fSmrg 47801e04c3fSmrgvoid 47901e04c3fSmrg_mesa_delete_sampler_handles(struct gl_context *ctx, 48001e04c3fSmrg struct gl_sampler_object *sampObj) 48101e04c3fSmrg{ 48201e04c3fSmrg util_dynarray_foreach(&sampObj->Handles, 48301e04c3fSmrg struct gl_texture_handle_object *, texHandleObj) { 48401e04c3fSmrg struct gl_texture_object *texObj = (*texHandleObj)->texObj; 48501e04c3fSmrg 48601e04c3fSmrg /* Delete the handle in the texture object. */ 48701e04c3fSmrg util_dynarray_delete_unordered(&texObj->SamplerHandles, 48801e04c3fSmrg struct gl_texture_handle_object *, 48901e04c3fSmrg *texHandleObj); 49001e04c3fSmrg 49101e04c3fSmrg delete_texture_handle(ctx, (*texHandleObj)->handle); 49201e04c3fSmrg free(*texHandleObj); 49301e04c3fSmrg } 49401e04c3fSmrg util_dynarray_fini(&sampObj->Handles); 49501e04c3fSmrg} 49601e04c3fSmrg 49701e04c3fSmrgstatic GLboolean 49801e04c3fSmrgis_sampler_border_color_valid(struct gl_sampler_object *samp) 49901e04c3fSmrg{ 50001e04c3fSmrg static const GLfloat valid_float_border_colors[4][4] = { 50101e04c3fSmrg { 0.0, 0.0, 0.0, 0.0 }, 50201e04c3fSmrg { 0.0, 0.0, 0.0, 1.0 }, 50301e04c3fSmrg { 1.0, 1.0, 1.0, 0.0 }, 50401e04c3fSmrg { 1.0, 1.0, 1.0, 1.0 }, 50501e04c3fSmrg }; 50601e04c3fSmrg static const GLint valid_integer_border_colors[4][4] = { 50701e04c3fSmrg { 0, 0, 0, 0 }, 50801e04c3fSmrg { 0, 0, 0, 1 }, 50901e04c3fSmrg { 1, 1, 1, 0 }, 51001e04c3fSmrg { 1, 1, 1, 1 }, 51101e04c3fSmrg }; 51201e04c3fSmrg size_t size = sizeof(samp->BorderColor.ui); 51301e04c3fSmrg 51401e04c3fSmrg /* The ARB_bindless_texture spec says: 51501e04c3fSmrg * 51601e04c3fSmrg * "The error INVALID_OPERATION is generated if the border color (taken from 51701e04c3fSmrg * the embedded sampler for GetTextureHandleARB or from the <sampler> for 51801e04c3fSmrg * GetTextureSamplerHandleARB) is not one of the following allowed values. 51901e04c3fSmrg * If the texture's base internal format is signed or unsigned integer, 52001e04c3fSmrg * allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and (1,1,1,1). If 52101e04c3fSmrg * the base internal format is not integer, allowed values are 52201e04c3fSmrg * (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 52301e04c3fSmrg * (1.0,1.0,1.0,1.0)." 52401e04c3fSmrg */ 52501e04c3fSmrg if (!memcmp(samp->BorderColor.f, valid_float_border_colors[0], size) || 52601e04c3fSmrg !memcmp(samp->BorderColor.f, valid_float_border_colors[1], size) || 52701e04c3fSmrg !memcmp(samp->BorderColor.f, valid_float_border_colors[2], size) || 52801e04c3fSmrg !memcmp(samp->BorderColor.f, valid_float_border_colors[3], size)) 52901e04c3fSmrg return GL_TRUE; 53001e04c3fSmrg 53101e04c3fSmrg if (!memcmp(samp->BorderColor.ui, valid_integer_border_colors[0], size) || 53201e04c3fSmrg !memcmp(samp->BorderColor.ui, valid_integer_border_colors[1], size) || 53301e04c3fSmrg !memcmp(samp->BorderColor.ui, valid_integer_border_colors[2], size) || 53401e04c3fSmrg !memcmp(samp->BorderColor.ui, valid_integer_border_colors[3], size)) 53501e04c3fSmrg return GL_TRUE; 53601e04c3fSmrg 53701e04c3fSmrg return GL_FALSE; 53801e04c3fSmrg} 53901e04c3fSmrg 54001e04c3fSmrgGLuint64 GLAPIENTRY 54101e04c3fSmrg_mesa_GetTextureHandleARB_no_error(GLuint texture) 54201e04c3fSmrg{ 54301e04c3fSmrg struct gl_texture_object *texObj; 54401e04c3fSmrg 54501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 54601e04c3fSmrg 54701e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 54801e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) 54901e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 55001e04c3fSmrg 55101e04c3fSmrg return get_texture_handle(ctx, texObj, &texObj->Sampler); 55201e04c3fSmrg} 55301e04c3fSmrg 55401e04c3fSmrgGLuint64 GLAPIENTRY 55501e04c3fSmrg_mesa_GetTextureHandleARB(GLuint texture) 55601e04c3fSmrg{ 55701e04c3fSmrg struct gl_texture_object *texObj = NULL; 55801e04c3fSmrg 55901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 56001e04c3fSmrg 56101e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx)) { 56201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 56301e04c3fSmrg "glGetTextureHandleARB(unsupported)"); 56401e04c3fSmrg return 0; 56501e04c3fSmrg } 56601e04c3fSmrg 56701e04c3fSmrg /* The ARB_bindless_texture spec says: 56801e04c3fSmrg * 56901e04c3fSmrg * "The error INVALID_VALUE is generated by GetTextureHandleARB or 57001e04c3fSmrg * GetTextureSamplerHandleARB if <texture> is zero or not the name of an 57101e04c3fSmrg * existing texture object." 57201e04c3fSmrg */ 57301e04c3fSmrg if (texture > 0) 57401e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 57501e04c3fSmrg 57601e04c3fSmrg if (!texObj) { 57701e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetTextureHandleARB(texture)"); 57801e04c3fSmrg return 0; 57901e04c3fSmrg } 58001e04c3fSmrg 58101e04c3fSmrg /* The ARB_bindless_texture spec says: 58201e04c3fSmrg * 58301e04c3fSmrg * "The error INVALID_OPERATION is generated by GetTextureHandleARB or 58401e04c3fSmrg * GetTextureSamplerHandleARB if the texture object specified by <texture> 58501e04c3fSmrg * is not complete." 58601e04c3fSmrg */ 58701e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 58801e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 58901e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 59001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 59101e04c3fSmrg "glGetTextureHandleARB(incomplete texture)"); 59201e04c3fSmrg return 0; 59301e04c3fSmrg } 59401e04c3fSmrg } 59501e04c3fSmrg 59601e04c3fSmrg if (!is_sampler_border_color_valid(&texObj->Sampler)) { 59701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 59801e04c3fSmrg "glGetTextureHandleARB(invalid border color)"); 59901e04c3fSmrg return 0; 60001e04c3fSmrg } 60101e04c3fSmrg 60201e04c3fSmrg return get_texture_handle(ctx, texObj, &texObj->Sampler); 60301e04c3fSmrg} 60401e04c3fSmrg 60501e04c3fSmrgGLuint64 GLAPIENTRY 60601e04c3fSmrg_mesa_GetTextureSamplerHandleARB_no_error(GLuint texture, GLuint sampler) 60701e04c3fSmrg{ 60801e04c3fSmrg struct gl_texture_object *texObj; 60901e04c3fSmrg struct gl_sampler_object *sampObj; 61001e04c3fSmrg 61101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 61201e04c3fSmrg 61301e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 61401e04c3fSmrg sampObj = _mesa_lookup_samplerobj(ctx, sampler); 61501e04c3fSmrg 61601e04c3fSmrg if (!_mesa_is_texture_complete(texObj, sampObj)) 61701e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 61801e04c3fSmrg 61901e04c3fSmrg return get_texture_handle(ctx, texObj, sampObj); 62001e04c3fSmrg} 62101e04c3fSmrg 62201e04c3fSmrgGLuint64 GLAPIENTRY 62301e04c3fSmrg_mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler) 62401e04c3fSmrg{ 62501e04c3fSmrg struct gl_texture_object *texObj = NULL; 62601e04c3fSmrg struct gl_sampler_object *sampObj; 62701e04c3fSmrg 62801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 62901e04c3fSmrg 63001e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx)) { 63101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 63201e04c3fSmrg "glGetTextureSamplerHandleARB(unsupported)"); 63301e04c3fSmrg return 0; 63401e04c3fSmrg } 63501e04c3fSmrg 63601e04c3fSmrg /* The ARB_bindless_texture spec says: 63701e04c3fSmrg * 63801e04c3fSmrg * "The error INVALID_VALUE is generated by GetTextureHandleARB or 63901e04c3fSmrg * GetTextureSamplerHandleARB if <texture> is zero or not the name of an 64001e04c3fSmrg * existing texture object." 64101e04c3fSmrg */ 64201e04c3fSmrg if (texture > 0) 64301e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 64401e04c3fSmrg 64501e04c3fSmrg if (!texObj) { 64601e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 64701e04c3fSmrg "glGetTextureSamplerHandleARB(texture)"); 64801e04c3fSmrg return 0; 64901e04c3fSmrg } 65001e04c3fSmrg 65101e04c3fSmrg /* The ARB_bindless_texture spec says: 65201e04c3fSmrg * 65301e04c3fSmrg * "The error INVALID_VALUE is generated by GetTextureSamplerHandleARB if 65401e04c3fSmrg * <sampler> is zero or is not the name of an existing sampler object." 65501e04c3fSmrg */ 65601e04c3fSmrg sampObj = _mesa_lookup_samplerobj(ctx, sampler); 65701e04c3fSmrg if (!sampObj) { 65801e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 65901e04c3fSmrg "glGetTextureSamplerHandleARB(sampler)"); 66001e04c3fSmrg return 0; 66101e04c3fSmrg } 66201e04c3fSmrg 66301e04c3fSmrg /* The ARB_bindless_texture spec says: 66401e04c3fSmrg * 66501e04c3fSmrg * "The error INVALID_OPERATION is generated by GetTextureHandleARB or 66601e04c3fSmrg * GetTextureSamplerHandleARB if the texture object specified by <texture> 66701e04c3fSmrg * is not complete." 66801e04c3fSmrg */ 66901e04c3fSmrg if (!_mesa_is_texture_complete(texObj, sampObj)) { 67001e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 67101e04c3fSmrg if (!_mesa_is_texture_complete(texObj, sampObj)) { 67201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 67301e04c3fSmrg "glGetTextureSamplerHandleARB(incomplete texture)"); 67401e04c3fSmrg return 0; 67501e04c3fSmrg } 67601e04c3fSmrg } 67701e04c3fSmrg 67801e04c3fSmrg if (!is_sampler_border_color_valid(sampObj)) { 67901e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 68001e04c3fSmrg "glGetTextureSamplerHandleARB(invalid border color)"); 68101e04c3fSmrg return 0; 68201e04c3fSmrg } 68301e04c3fSmrg 68401e04c3fSmrg return get_texture_handle(ctx, texObj, sampObj); 68501e04c3fSmrg} 68601e04c3fSmrg 68701e04c3fSmrgvoid GLAPIENTRY 68801e04c3fSmrg_mesa_MakeTextureHandleResidentARB_no_error(GLuint64 handle) 68901e04c3fSmrg{ 69001e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 69101e04c3fSmrg 69201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 69301e04c3fSmrg 69401e04c3fSmrg texHandleObj = lookup_texture_handle(ctx, handle); 69501e04c3fSmrg make_texture_handle_resident(ctx, texHandleObj, true); 69601e04c3fSmrg} 69701e04c3fSmrg 69801e04c3fSmrgvoid GLAPIENTRY 69901e04c3fSmrg_mesa_MakeTextureHandleResidentARB(GLuint64 handle) 70001e04c3fSmrg{ 70101e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 70201e04c3fSmrg 70301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 70401e04c3fSmrg 70501e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx)) { 70601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 70701e04c3fSmrg "glMakeTextureHandleResidentARB(unsupported)"); 70801e04c3fSmrg return; 70901e04c3fSmrg } 71001e04c3fSmrg 71101e04c3fSmrg /* The ARB_bindless_texture spec says: 71201e04c3fSmrg * 71301e04c3fSmrg * "The error INVALID_OPERATION is generated by MakeTextureHandleResidentARB 71401e04c3fSmrg * if <handle> is not a valid texture handle, or if <handle> is already 71501e04c3fSmrg * resident in the current GL context." 71601e04c3fSmrg */ 71701e04c3fSmrg texHandleObj = lookup_texture_handle(ctx, handle); 71801e04c3fSmrg if (!texHandleObj) { 71901e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 72001e04c3fSmrg "glMakeTextureHandleResidentARB(handle)"); 72101e04c3fSmrg return; 72201e04c3fSmrg } 72301e04c3fSmrg 72401e04c3fSmrg if (is_texture_handle_resident(ctx, handle)) { 72501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 72601e04c3fSmrg "glMakeTextureHandleResidentARB(already resident)"); 72701e04c3fSmrg return; 72801e04c3fSmrg } 72901e04c3fSmrg 73001e04c3fSmrg make_texture_handle_resident(ctx, texHandleObj, true); 73101e04c3fSmrg} 73201e04c3fSmrg 73301e04c3fSmrgvoid GLAPIENTRY 73401e04c3fSmrg_mesa_MakeTextureHandleNonResidentARB_no_error(GLuint64 handle) 73501e04c3fSmrg{ 73601e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 73701e04c3fSmrg 73801e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 73901e04c3fSmrg 74001e04c3fSmrg texHandleObj = lookup_texture_handle(ctx, handle); 74101e04c3fSmrg make_texture_handle_resident(ctx, texHandleObj, false); 74201e04c3fSmrg} 74301e04c3fSmrg 74401e04c3fSmrgvoid GLAPIENTRY 74501e04c3fSmrg_mesa_MakeTextureHandleNonResidentARB(GLuint64 handle) 74601e04c3fSmrg{ 74701e04c3fSmrg struct gl_texture_handle_object *texHandleObj; 74801e04c3fSmrg 74901e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 75001e04c3fSmrg 75101e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx)) { 75201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 75301e04c3fSmrg "glMakeTextureHandleNonResidentARB(unsupported)"); 75401e04c3fSmrg return; 75501e04c3fSmrg } 75601e04c3fSmrg 75701e04c3fSmrg /* The ARB_bindless_texture spec says: 75801e04c3fSmrg * 75901e04c3fSmrg * "The error INVALID_OPERATION is generated by 76001e04c3fSmrg * MakeTextureHandleNonResidentARB if <handle> is not a valid texture 76101e04c3fSmrg * handle, or if <handle> is not resident in the current GL context." 76201e04c3fSmrg */ 76301e04c3fSmrg texHandleObj = lookup_texture_handle(ctx, handle); 76401e04c3fSmrg if (!texHandleObj) { 76501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 76601e04c3fSmrg "glMakeTextureHandleNonResidentARB(handle)"); 76701e04c3fSmrg return; 76801e04c3fSmrg } 76901e04c3fSmrg 77001e04c3fSmrg if (!is_texture_handle_resident(ctx, handle)) { 77101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 77201e04c3fSmrg "glMakeTextureHandleNonResidentARB(not resident)"); 77301e04c3fSmrg return; 77401e04c3fSmrg } 77501e04c3fSmrg 77601e04c3fSmrg make_texture_handle_resident(ctx, texHandleObj, false); 77701e04c3fSmrg} 77801e04c3fSmrg 77901e04c3fSmrgGLuint64 GLAPIENTRY 78001e04c3fSmrg_mesa_GetImageHandleARB_no_error(GLuint texture, GLint level, GLboolean layered, 78101e04c3fSmrg GLint layer, GLenum format) 78201e04c3fSmrg{ 78301e04c3fSmrg struct gl_texture_object *texObj; 78401e04c3fSmrg 78501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 78601e04c3fSmrg 78701e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 78801e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) 78901e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 79001e04c3fSmrg 79101e04c3fSmrg return get_image_handle(ctx, texObj, level, layered, layer, format); 79201e04c3fSmrg} 79301e04c3fSmrg 79401e04c3fSmrgGLuint64 GLAPIENTRY 79501e04c3fSmrg_mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered, 79601e04c3fSmrg GLint layer, GLenum format) 79701e04c3fSmrg{ 79801e04c3fSmrg struct gl_texture_object *texObj = NULL; 79901e04c3fSmrg 80001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 80101e04c3fSmrg 80201e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx) || 80301e04c3fSmrg !_mesa_has_ARB_shader_image_load_store(ctx)) { 80401e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 80501e04c3fSmrg "glGetImageHandleARB(unsupported)"); 80601e04c3fSmrg return 0; 80701e04c3fSmrg } 80801e04c3fSmrg 80901e04c3fSmrg /* The ARB_bindless_texture spec says: 81001e04c3fSmrg * 81101e04c3fSmrg * "The error INVALID_VALUE is generated by GetImageHandleARB if <texture> 81201e04c3fSmrg * is zero or not the name of an existing texture object, if the image for 81301e04c3fSmrg * <level> does not existing in <texture>, or if <layered> is FALSE and 81401e04c3fSmrg * <layer> is greater than or equal to the number of layers in the image at 81501e04c3fSmrg * <level>." 81601e04c3fSmrg */ 81701e04c3fSmrg if (texture > 0) 81801e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 81901e04c3fSmrg 82001e04c3fSmrg if (!texObj) { 82101e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(texture)"); 82201e04c3fSmrg return 0; 82301e04c3fSmrg } 82401e04c3fSmrg 82501e04c3fSmrg if (level < 0 || level >= _mesa_max_texture_levels(ctx, texObj->Target)) { 82601e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(level)"); 82701e04c3fSmrg return 0; 82801e04c3fSmrg } 82901e04c3fSmrg 83001e04c3fSmrg if (!layered && layer > _mesa_get_texture_layers(texObj, level)) { 83101e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(layer)"); 83201e04c3fSmrg return 0; 83301e04c3fSmrg } 83401e04c3fSmrg 83501e04c3fSmrg if (!_mesa_is_shader_image_format_supported(ctx, format)) { 83601e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(format)"); 83701e04c3fSmrg return 0; 83801e04c3fSmrg } 83901e04c3fSmrg 84001e04c3fSmrg /* The ARB_bindless_texture spec says: 84101e04c3fSmrg * 84201e04c3fSmrg * "The error INVALID_OPERATION is generated by GetImageHandleARB if the 84301e04c3fSmrg * texture object <texture> is not complete or if <layered> is TRUE and 84401e04c3fSmrg * <texture> is not a three-dimensional, one-dimensional array, two 84501e04c3fSmrg * dimensional array, cube map, or cube map array texture." 84601e04c3fSmrg */ 84701e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 84801e04c3fSmrg _mesa_test_texobj_completeness(ctx, texObj); 84901e04c3fSmrg if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) { 85001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 85101e04c3fSmrg "glGetImageHandleARB(incomplete texture)"); 85201e04c3fSmrg return 0; 85301e04c3fSmrg } 85401e04c3fSmrg } 85501e04c3fSmrg 85601e04c3fSmrg if (layered && !_mesa_tex_target_is_layered(texObj->Target)) { 85701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 85801e04c3fSmrg "glGetImageHandleARB(not layered)"); 85901e04c3fSmrg return 0; 86001e04c3fSmrg } 86101e04c3fSmrg 86201e04c3fSmrg return get_image_handle(ctx, texObj, level, layered, layer, format); 86301e04c3fSmrg} 86401e04c3fSmrg 86501e04c3fSmrgvoid GLAPIENTRY 86601e04c3fSmrg_mesa_MakeImageHandleResidentARB_no_error(GLuint64 handle, GLenum access) 86701e04c3fSmrg{ 86801e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 86901e04c3fSmrg 87001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 87101e04c3fSmrg 87201e04c3fSmrg imgHandleObj = lookup_image_handle(ctx, handle); 87301e04c3fSmrg make_image_handle_resident(ctx, imgHandleObj, access, true); 87401e04c3fSmrg} 87501e04c3fSmrg 87601e04c3fSmrgvoid GLAPIENTRY 87701e04c3fSmrg_mesa_MakeImageHandleResidentARB(GLuint64 handle, GLenum access) 87801e04c3fSmrg{ 87901e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 88001e04c3fSmrg 88101e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 88201e04c3fSmrg 88301e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx) || 88401e04c3fSmrg !_mesa_has_ARB_shader_image_load_store(ctx)) { 88501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 88601e04c3fSmrg "glMakeImageHandleResidentARB(unsupported)"); 88701e04c3fSmrg return; 88801e04c3fSmrg } 88901e04c3fSmrg 89001e04c3fSmrg if (access != GL_READ_ONLY && 89101e04c3fSmrg access != GL_WRITE_ONLY && 89201e04c3fSmrg access != GL_READ_WRITE) { 89301e04c3fSmrg _mesa_error(ctx, GL_INVALID_ENUM, 89401e04c3fSmrg "glMakeImageHandleResidentARB(access)"); 89501e04c3fSmrg return; 89601e04c3fSmrg } 89701e04c3fSmrg 89801e04c3fSmrg /* The ARB_bindless_texture spec says: 89901e04c3fSmrg * 90001e04c3fSmrg * "The error INVALID_OPERATION is generated by MakeImageHandleResidentARB 90101e04c3fSmrg * if <handle> is not a valid image handle, or if <handle> is already 90201e04c3fSmrg * resident in the current GL context." 90301e04c3fSmrg */ 90401e04c3fSmrg imgHandleObj = lookup_image_handle(ctx, handle); 90501e04c3fSmrg if (!imgHandleObj) { 90601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 90701e04c3fSmrg "glMakeImageHandleResidentARB(handle)"); 90801e04c3fSmrg return; 90901e04c3fSmrg } 91001e04c3fSmrg 91101e04c3fSmrg if (is_image_handle_resident(ctx, handle)) { 91201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 91301e04c3fSmrg "glMakeImageHandleResidentARB(already resident)"); 91401e04c3fSmrg return; 91501e04c3fSmrg } 91601e04c3fSmrg 91701e04c3fSmrg make_image_handle_resident(ctx, imgHandleObj, access, true); 91801e04c3fSmrg} 91901e04c3fSmrg 92001e04c3fSmrgvoid GLAPIENTRY 92101e04c3fSmrg_mesa_MakeImageHandleNonResidentARB_no_error(GLuint64 handle) 92201e04c3fSmrg{ 92301e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 92401e04c3fSmrg 92501e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 92601e04c3fSmrg 92701e04c3fSmrg imgHandleObj = lookup_image_handle(ctx, handle); 92801e04c3fSmrg make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false); 92901e04c3fSmrg} 93001e04c3fSmrg 93101e04c3fSmrgvoid GLAPIENTRY 93201e04c3fSmrg_mesa_MakeImageHandleNonResidentARB(GLuint64 handle) 93301e04c3fSmrg{ 93401e04c3fSmrg struct gl_image_handle_object *imgHandleObj; 93501e04c3fSmrg 93601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 93701e04c3fSmrg 93801e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx) || 93901e04c3fSmrg !_mesa_has_ARB_shader_image_load_store(ctx)) { 94001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 94101e04c3fSmrg "glMakeImageHandleNonResidentARB(unsupported)"); 94201e04c3fSmrg return; 94301e04c3fSmrg } 94401e04c3fSmrg 94501e04c3fSmrg /* The ARB_bindless_texture spec says: 94601e04c3fSmrg * 94701e04c3fSmrg * "The error INVALID_OPERATION is generated by 94801e04c3fSmrg * MakeImageHandleNonResidentARB if <handle> is not a valid image handle, 94901e04c3fSmrg * or if <handle> is not resident in the current GL context." 95001e04c3fSmrg */ 95101e04c3fSmrg imgHandleObj = lookup_image_handle(ctx, handle); 95201e04c3fSmrg if (!imgHandleObj) { 95301e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 95401e04c3fSmrg "glMakeImageHandleNonResidentARB(handle)"); 95501e04c3fSmrg return; 95601e04c3fSmrg } 95701e04c3fSmrg 95801e04c3fSmrg if (!is_image_handle_resident(ctx, handle)) { 95901e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 96001e04c3fSmrg "glMakeImageHandleNonResidentARB(not resident)"); 96101e04c3fSmrg return; 96201e04c3fSmrg } 96301e04c3fSmrg 96401e04c3fSmrg make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false); 96501e04c3fSmrg} 96601e04c3fSmrg 96701e04c3fSmrgGLboolean GLAPIENTRY 96801e04c3fSmrg_mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle) 96901e04c3fSmrg{ 97001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 97101e04c3fSmrg return is_texture_handle_resident(ctx, handle); 97201e04c3fSmrg} 97301e04c3fSmrg 97401e04c3fSmrgGLboolean GLAPIENTRY 97501e04c3fSmrg_mesa_IsTextureHandleResidentARB(GLuint64 handle) 97601e04c3fSmrg{ 97701e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 97801e04c3fSmrg 97901e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx)) { 98001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 98101e04c3fSmrg "glIsTextureHandleResidentARB(unsupported)"); 98201e04c3fSmrg return GL_FALSE; 98301e04c3fSmrg } 98401e04c3fSmrg 98501e04c3fSmrg /* The ARB_bindless_texture spec says: 98601e04c3fSmrg * 98701e04c3fSmrg * "The error INVALID_OPERATION will be generated by 98801e04c3fSmrg * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is 98901e04c3fSmrg * not a valid texture or image handle, respectively." 99001e04c3fSmrg */ 99101e04c3fSmrg if (!lookup_texture_handle(ctx, handle)) { 99201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 99301e04c3fSmrg "glIsTextureHandleResidentARB(handle)"); 99401e04c3fSmrg return GL_FALSE; 99501e04c3fSmrg } 99601e04c3fSmrg 99701e04c3fSmrg return is_texture_handle_resident(ctx, handle); 99801e04c3fSmrg} 99901e04c3fSmrg 100001e04c3fSmrgGLboolean GLAPIENTRY 100101e04c3fSmrg_mesa_IsImageHandleResidentARB_no_error(GLuint64 handle) 100201e04c3fSmrg{ 100301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 100401e04c3fSmrg return is_image_handle_resident(ctx, handle); 100501e04c3fSmrg} 100601e04c3fSmrg 100701e04c3fSmrgGLboolean GLAPIENTRY 100801e04c3fSmrg_mesa_IsImageHandleResidentARB(GLuint64 handle) 100901e04c3fSmrg{ 101001e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 101101e04c3fSmrg 101201e04c3fSmrg if (!_mesa_has_ARB_bindless_texture(ctx) || 101301e04c3fSmrg !_mesa_has_ARB_shader_image_load_store(ctx)) { 101401e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 101501e04c3fSmrg "glIsImageHandleResidentARB(unsupported)"); 101601e04c3fSmrg return GL_FALSE; 101701e04c3fSmrg } 101801e04c3fSmrg 101901e04c3fSmrg /* The ARB_bindless_texture spec says: 102001e04c3fSmrg * 102101e04c3fSmrg * "The error INVALID_OPERATION will be generated by 102201e04c3fSmrg * IsTextureHandleResidentARB and IsImageHandleResidentARB if <handle> is 102301e04c3fSmrg * not a valid texture or image handle, respectively." 102401e04c3fSmrg */ 102501e04c3fSmrg if (!lookup_image_handle(ctx, handle)) { 102601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 102701e04c3fSmrg "glIsImageHandleResidentARB(handle)"); 102801e04c3fSmrg return GL_FALSE; 102901e04c3fSmrg } 103001e04c3fSmrg 103101e04c3fSmrg return is_image_handle_resident(ctx, handle); 103201e04c3fSmrg} 1033