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