[Mesa-dev] [PATCH v2 03/64] mesa: implement ARB_bindless_texture
Samuel Pitoiset
samuel.pitoiset at gmail.com
Thu Jun 8 10:25:20 UTC 2017
On 06/07/2017 05:58 PM, Nicolai Hähnle wrote:
> On 30.05.2017 22:35, Samuel Pitoiset wrote:
>> v2: - s/GLboolean/bool for HandleAllocated
>> - fix _mesa_has_ARB_shader_image_load_store() checks
>> - use u_vector for texture/image handles
>> - fix use of 64-bit handles on 32-bit systems
>> - some cleanups
>>
>> Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
>> ---
>> src/mesa/main/context.c | 3 +
>> src/mesa/main/dd.h | 17 +
>> src/mesa/main/mtypes.h | 38 ++
>> src/mesa/main/samplerobj.c | 6 +
>> src/mesa/main/shared.c | 6 +
>> src/mesa/main/texobj.c | 13 +
>> src/mesa/main/texturebindless.c | 927
>> +++++++++++++++++++++++++++++++++++++++-
>> src/mesa/main/texturebindless.h | 32 ++
>> 8 files changed, 1035 insertions(+), 7 deletions(-)
>>
>> diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
>> index 9aa6fb64b2..b801322fd0 100644
>> --- a/src/mesa/main/context.c
>> +++ b/src/mesa/main/context.c
>> @@ -133,6 +133,7 @@
>> #include "varray.h"
>> #include "version.h"
>> #include "viewport.h"
>> +#include "texturebindless.h"
>> #include "program/program.h"
>> #include "math/m_matrix.h"
>> #include "main/dispatch.h" /* for _gloffset_COUNT */
>> @@ -855,6 +856,7 @@ init_attrib_groups(struct gl_context *ctx)
>> _mesa_init_transform_feedback( ctx );
>> _mesa_init_varray( ctx );
>> _mesa_init_viewport( ctx );
>> + _mesa_init_resident_handles( ctx );
>> if (!_mesa_init_texture( ctx ))
>> return GL_FALSE;
>> @@ -1339,6 +1341,7 @@ _mesa_free_context_data( struct gl_context *ctx )
>> _mesa_free_transform_feedback(ctx);
>> _mesa_free_performance_monitors(ctx);
>> _mesa_free_performance_queries(ctx);
>> + _mesa_free_resident_handles(ctx);
>> _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
>> _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
>> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
>> index a9ca43d69e..d830f5184d 100644
>> --- a/src/mesa/main/dd.h
>> +++ b/src/mesa/main/dd.h
>> @@ -1050,6 +1050,23 @@ struct dd_function_table {
>> GLintptr offset, GLsizeiptr size,
>> GLboolean commit);
>> /*@}*/
>> +
>> + /**
>> + * \name GL_ARB_bindless_texture interface
>> + */
>> + /*@{*/
>> + GLuint64 (*NewTextureHandle)(struct gl_context *ctx,
>> + struct gl_texture_object *texObj,
>> + struct gl_sampler_object *sampObj);
>> + void (*DeleteTextureHandle)(struct gl_context *ctx, GLuint64 handle);
>> + void (*MakeTextureHandleResident)(struct gl_context *ctx, GLuint64
>> handle,
>> + bool resident);
>> + GLuint64 (*NewImageHandle)(struct gl_context *ctx,
>> + struct gl_image_unit *imgObj);
>> + void (*DeleteImageHandle)(struct gl_context *ctx, GLuint64 handle);
>> + void (*MakeImageHandleResident)(struct gl_context *ctx, GLuint64
>> handle,
>> + GLenum access, bool resident);
>> + /*@}*/
>> };
>> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
>> index 29e4c67846..5b38eb1b64 100644
>> --- a/src/mesa/main/mtypes.h
>> +++ b/src/mesa/main/mtypes.h
>> @@ -47,6 +47,7 @@
>> #include "main/formats.h" /* MESA_FORMAT_COUNT */
>> #include "compiler/glsl/list.h"
>> #include "util/bitscan.h"
>> +#include "util/u_vector.h"
>> #ifdef __cplusplus
>> @@ -987,6 +988,10 @@ struct gl_sampler_object
>> GLenum CompareFunc; /**< GL_ARB_shadow */
>> GLenum sRGBDecode; /**< GL_DECODE_EXT or
>> GL_SKIP_DECODE_EXT */
>> GLboolean CubeMapSeamless; /**<
>> GL_AMD_seamless_cubemap_per_texture */
>> +
>> + /** GL_ARB_bindless_texture */
>> + struct u_vector Handles;
>> + bool HandleAllocated;
>> };
>> @@ -1051,6 +1056,11 @@ struct gl_texture_object
>> /** GL_ARB_shader_image_load_store */
>> GLenum ImageFormatCompatibilityType;
>> +
>> + /** GL_ARB_bindless_texture */
>> + struct u_vector SamplerHandles;
>> + struct u_vector ImageHandles;
>> + bool HandleAllocated;
>> };
>> @@ -1403,6 +1413,8 @@ struct gl_buffer_object
>> unsigned MinMaxCacheHitIndices;
>> unsigned MinMaxCacheMissIndices;
>> bool MinMaxCacheDirty;
>> +
>> + bool HandleAllocated; /**< GL_ARB_bindless_texture */
>> };
>> @@ -3211,6 +3223,11 @@ struct gl_shared_state
>> /** GL_ARB_sampler_objects */
>> struct _mesa_HashTable *SamplerObjects;
>> + /* GL_ARB_bindless_texture */
>> + struct hash_table *TextureHandles;
>> + struct hash_table *ImageHandles;
>> + mtx_t HandlesMutex; /**< For texture/image handles safety */
>> +
>> /**
>> * Some context in this share group was affected by a GPU reset
>> *
>> @@ -4500,6 +4517,19 @@ struct gl_subroutine_index_binding
>> GLuint *IndexPtr;
>> };
>> +struct gl_texture_handle_object
>> +{
>> + struct gl_texture_object *texObj;
>> + struct gl_sampler_object *sampObj;
>> + GLuint64 handle;
>> +};
>> +
>> +struct gl_image_handle_object
>> +{
>> + struct gl_image_unit imgObj;
>> + GLuint64 handle;
>> +};
>> +
>> /**
>> * Mesa rendering context.
>> *
>> @@ -4854,6 +4884,14 @@ struct gl_context
>> GLfloat PrimitiveBoundingBox[8];
>> struct disk_cache *Cache;
>> +
>> + /**
>> + * \name GL_ARB_bindless_texture
>> + */
>> + /*@{*/
>> + struct hash_table *ResidentTextureHandles;
>> + struct hash_table *ResidentImageHandles;
>> + /*@}*/
>> };
>> /**
>> diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c
>> index 63beaf1abb..ee15c68b4f 100644
>> --- a/src/mesa/main/samplerobj.c
>> +++ b/src/mesa/main/samplerobj.c
>> @@ -38,6 +38,7 @@
>> #include "main/macros.h"
>> #include "main/mtypes.h"
>> #include "main/samplerobj.h"
>> +#include "main/texturebindless.h"
>> struct gl_sampler_object *
>> @@ -61,6 +62,7 @@ static void
>> delete_sampler_object(struct gl_context *ctx,
>> struct gl_sampler_object *sampObj)
>> {
>> + _mesa_delete_sampler_handles(ctx, sampObj);
>> mtx_destroy(&sampObj->Mutex);
>> free(sampObj->Label);
>> free(sampObj);
>> @@ -132,6 +134,10 @@ _mesa_init_sampler_object(struct
>> gl_sampler_object *sampObj, GLuint name)
>> sampObj->CompareFunc = GL_LEQUAL;
>> sampObj->sRGBDecode = GL_DECODE_EXT;
>> sampObj->CubeMapSeamless = GL_FALSE;
>> + sampObj->HandleAllocated = GL_FALSE;
>> +
>> + /* GL_ARB_bindless_texture */
>> + _mesa_init_sampler_handles(sampObj);
>> }
>> /**
>> diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
>> index 5344812738..6926d40570 100644
>> --- a/src/mesa/main/shared.c
>> +++ b/src/mesa/main/shared.c
>> @@ -39,6 +39,7 @@
>> #include "shaderapi.h"
>> #include "shaderobj.h"
>> #include "syncobj.h"
>> +#include "texturebindless.h"
>> #include "util/hash_table.h"
>> #include "util/set.h"
>> @@ -84,6 +85,9 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
>> /* GL_ARB_sampler_objects */
>> shared->SamplerObjects = _mesa_NewHashTable();
>> + /* GL_ARB_bindless_texture */
>> + _mesa_init_shared_handles(shared);
>> +
>> /* Allocate the default buffer object */
>> shared->NullBufferObj = ctx->Driver.NewBufferObject(ctx, 0);
>> @@ -373,6 +377,8 @@ free_shared_state(struct gl_context *ctx, struct
>> gl_shared_state *shared)
>> _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx);
>> _mesa_DeleteHashTable(shared->TexObjects);
>> + _mesa_free_shared_handles(shared);
>> +
>> mtx_destroy(&shared->Mutex);
>> mtx_destroy(&shared->TexMutex);
>> diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
>> index 868e4eb7a2..1877262ed6 100644
>> --- a/src/mesa/main/texobj.c
>> +++ b/src/mesa/main/texobj.c
>> @@ -43,6 +43,7 @@
>> #include "texstate.h"
>> #include "mtypes.h"
>> #include "program/prog_instruction.h"
>> +#include "texturebindless.h"
>> @@ -311,6 +312,7 @@ _mesa_initialize_texture_object( struct gl_context
>> *ctx,
>> obj->DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED :
>> GL_LUMINANCE;
>> obj->StencilSampling = false;
>> obj->Sampler.CubeMapSeamless = GL_FALSE;
>> + obj->Sampler.HandleAllocated = GL_FALSE;
>> obj->Swizzle[0] = GL_RED;
>> obj->Swizzle[1] = GL_GREEN;
>> obj->Swizzle[2] = GL_BLUE;
>> @@ -320,6 +322,9 @@ _mesa_initialize_texture_object( struct gl_context
>> *ctx,
>> obj->BufferObjectFormat = GL_R8;
>> obj->_BufferObjectFormat = MESA_FORMAT_R_UNORM8;
>> obj->ImageFormatCompatibilityType =
>> GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
>> +
>> + /* GL_ARB_bindless_texture */
>> + _mesa_init_texture_handles(obj);
>> }
>> @@ -397,6 +402,9 @@ _mesa_delete_texture_object(struct gl_context *ctx,
>> }
>> }
>> + /* Delete all texture/image handles. */
>> + _mesa_delete_texture_handles(ctx, texObj);
>> +
>> _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
>> /* destroy the mutex -- it may have allocated memory (eg on bsd) */
>> @@ -1461,6 +1469,11 @@ _mesa_DeleteTextures( GLsizei n, const GLuint
>> *textures)
>> */
>> unbind_texobj_from_image_units(ctx, delObj);
>> + /* Make all handles that reference this texture object
>> non-resident
>> + * in the current context.
>> + */
>> + _mesa_make_texture_handles_non_resident(ctx, delObj);
>> +
>> _mesa_unlock_texture(ctx, delObj);
>> ctx->NewState |= _NEW_TEXTURE_OBJECT;
>> diff --git a/src/mesa/main/texturebindless.c
>> b/src/mesa/main/texturebindless.c
>> index 4d9c22d428..d5ef403851 100644
>> --- a/src/mesa/main/texturebindless.c
>> +++ b/src/mesa/main/texturebindless.c
>> @@ -25,61 +25,974 @@
>> #include "context.h"
>> #include "enums.h"
>> #include "imports.h"
>> -#include "macros.h"
>> #include "mtypes.h"
>> +#include "shaderimage.h"
>> +#include "teximage.h"
>> #include "texobj.h"
>> #include "texturebindless.h"
>> -#include "util/set.h"
>> +#include "util/macros.h"
>> #include "util/hash_table.h"
>> +/**
>> + * Hash table wrapper for 32-bit systems.
>> + */
>> +
>> +#if !defined(MESA_ARCH_X86_64)
>> +
>> +struct hash_key {
>> + GLuint64 value;
>> +};
>> +
>> +static uint32_t
>> +key_hash(const void *key)
>> +{
>> + return _mesa_hash_data(key, sizeof(struct hash_key));
>> +}
>> +
>> +static bool
>> +key_equals(const void *a, const void *b)
>> +{
>> + struct hash_key *aa = (struct hash_key *)a;
>> + struct hash_key *bb = (struct hash_key *)b;
>> +
>> + return aa->value == bb->value;
>> +}
>> +
>> +#endif
>> +
>> +static struct hash_entry *
>> +hash_table_search(struct hash_table *ht, GLuint64 key)
>> +{
>> +#if !defined(MESA_ARCH_X86_64)
>> + struct hash_key *_key = NULL;
>> + struct hash_entry *entry;
>> +
>> + _key = CALLOC_STRUCT(hash_key);
>> + if (!_key)
>> + return NULL;
>> + _key->value = key;
>> +
>> + entry = _mesa_hash_table_search(ht, _key);
>> +
>> + free(_key);
>
> _key doesn't have to be allocated on the heap, right?
You are right, not needed for search().
>
>
>> + return entry;
>> +#else
>> + return _mesa_hash_table_search(ht, (void *)key);
>> +#endif
>> +}
>> +
>> +static struct hash_entry *
>> +hash_table_insert(struct hash_table *ht, GLuint64 key, void *data)
>> +{
>> +#if !defined(MESA_ARCH_X86_64)
>> + struct hash_key *_key = CALLOC_STRUCT(hash_key);
>> +
>> + if (!_key)
>> + return NULL;
>> + _key->value = key;
>> +
>> + return _mesa_hash_table_insert(ht, _key, data);
>> +#else
>> + return _mesa_hash_table_insert(ht, (void *)key, data);
>> +#endif
>> +}
>> +
>> +static void
>> +hash_table_remove(struct hash_table *ht, struct hash_entry *entry)
>> +{
>> +#if !defined(MESA_ARCH_X86_64)
>> + struct hash_key *_key = (struct hash_key *)entry->key;
>> +
>> + _mesa_hash_table_remove(ht, entry);
>> + free(_key);
>> +#else
>> + _mesa_hash_table_remove(ht, entry);
>> +#endif
>> +}
>> +
>> +/**
>> + * Return the gl_texture_handle_object for a given 64-bit handle.
>> + */
>> +static struct gl_texture_handle_object *
>> +lookup_texture_handle(struct gl_context *ctx, GLuint64 id)
>> +{
>> + struct hash_entry *entry;
>> +
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + entry = hash_table_search(ctx->Shared->TextureHandles, id);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + return entry ? (struct gl_texture_handle_object *)entry->data : NULL;
>> +}
>> +
>> +/**
>> + * Return the gl_image_handle_object for a given 64-bit handle.
>> + */
>> +static struct gl_image_handle_object *
>> +lookup_image_handle(struct gl_context *ctx, GLuint64 id)
>> +{
>> + struct hash_entry *entry;
>> +
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + entry = hash_table_search(ctx->Shared->ImageHandles, id);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + return entry ? (struct gl_image_handle_object *)entry->data : NULL;
>> +}
>> +
>> +/**
>> + * Delete a texture handle in the shared state.
>> + */
>> +static void
>> +delete_texture_handle(struct gl_context *ctx, GLuint64 id)
>> +{
>> + struct hash_entry *entry;
>> +
>> + if (!lookup_texture_handle(ctx, id))
>> + return;
>
> This is redundant. It would be better to check entry below.
>
>
>> +
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + entry = hash_table_search(ctx->Shared->TextureHandles, id);
>> + hash_table_remove(ctx->Shared->TextureHandles, entry);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + ctx->Driver.DeleteTextureHandle(ctx, id);
>> +}
>> +
>> +/**
>> + * Delete an image handle in the shared state.
>> + */
>> +static void
>> +delete_image_handle(struct gl_context *ctx, GLuint64 id)
>> +{
>> + struct hash_entry *entry;
>> +
>> + if (!lookup_image_handle(ctx, id))
>> + return;
>
> Same here.
Fixed locally.
Samuel.
>
> Cheers,
> Nicolai
>
>
>> +
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + entry = hash_table_search(ctx->Shared->ImageHandles, id);
>> + hash_table_remove(ctx->Shared->ImageHandles, entry);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + ctx->Driver.DeleteImageHandle(ctx, id);
>> +}
>> +
>> +/**
>> + * Return TRUE if the texture handle is resident in the current context.
>> + */
>> +static inline bool
>> +is_texture_handle_resident(struct gl_context *ctx, GLuint64 handle)
>> +{
>> + return hash_table_search(ctx->ResidentTextureHandles, handle) !=
>> NULL;
>> +}
>> +
>> +/**
>> + * Return TRUE if the image handle is resident in the current context.
>> + */
>> +static inline bool
>> +is_image_handle_resident(struct gl_context *ctx, GLuint64 handle)
>> +{
>> + return hash_table_search(ctx->ResidentImageHandles, handle) != NULL;
>> +}
>> +
>> +/**
>> + * Make a texture handle resident/non-resident in the current context.
>> + */
>> +static void
>> +make_texture_handle_resident(struct gl_context *ctx,
>> + struct gl_texture_handle_object
>> *texHandleObj,
>> + bool resident)
>> +{
>> + GLuint64 handle = texHandleObj->handle;
>> +
>> + if (resident) {
>> + struct gl_sampler_object *sampObj = NULL;
>> + struct gl_texture_object *texObj = NULL;
>> +
>> + hash_table_insert(ctx->ResidentTextureHandles, handle,
>> texHandleObj);
>> +
>> + ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_TRUE);
>> +
>> + /* Reference the texture object (and the separate sampler if
>> needed) to
>> + * be sure it won't be deleted until it is not bound anywhere
>> and there
>> + * are no handles using the object that are resident in any
>> context.
>> + */
>> + _mesa_reference_texobj(&texObj, texHandleObj->texObj);
>> + if (texHandleObj->sampObj)
>> + _mesa_reference_sampler_object(ctx, &sampObj,
>> texHandleObj->sampObj);
>> + } else {
>> + struct hash_entry *entry;
>> +
>> + entry = hash_table_search(ctx->ResidentTextureHandles, handle);
>> + hash_table_remove(ctx->ResidentTextureHandles, entry);
>> +
>> + ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_FALSE);
>> +
>> + /* Unreference the texture object (and the separate sampler if
>> needed),
>> + * if refcount hits zero, the texture and all handles will be
>> deleted.
>> + */
>> + _mesa_reference_texobj(&texHandleObj->texObj, NULL);
>> + if (texHandleObj->sampObj)
>> + _mesa_reference_sampler_object(ctx, &texHandleObj->sampObj,
>> NULL);
>> + }
>> +}
>> +
>> +/**
>> + * Make an image handle resident/non-resident in the current context.
>> + */
>> +static void
>> +make_image_handle_resident(struct gl_context *ctx,
>> + struct gl_image_handle_object *imgHandleObj,
>> + GLenum access, bool resident)
>> +{
>> + GLuint64 handle = imgHandleObj->handle;
>> +
>> + if (resident) {
>> + struct gl_texture_object *texObj = NULL;
>> +
>> + hash_table_insert(ctx->ResidentImageHandles, handle,
>> imgHandleObj);
>> +
>> + ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_TRUE);
>> +
>> + /* Reference the texture object to be sure it won't be deleted
>> until it
>> + * is not bound anywhere and there are no handles using the
>> object that
>> + * are resident in any context.
>> + */
>> + _mesa_reference_texobj(&texObj, imgHandleObj->imgObj.TexObj);
>> + } else {
>> + struct hash_entry *entry;
>> +
>> + entry = hash_table_search(ctx->ResidentImageHandles, handle);
>> + hash_table_remove(ctx->ResidentImageHandles, entry);
>> +
>> + ctx->Driver.MakeImageHandleResident(ctx, handle, access,
>> GL_FALSE);
>> +
>> + /* Unreference the texture object, if refcount hits zero, the
>> texture and
>> + * all handles will be deleted.
>> + */
>> + _mesa_reference_texobj(&imgHandleObj->imgObj.TexObj, NULL);
>> + }
>> +}
>> +
>> +static struct gl_texture_handle_object *
>> +find_texhandleobj(struct gl_texture_object *texObj,
>> + struct gl_sampler_object *sampObj)
>> +{
>> + struct gl_texture_handle_object *texHandleObj;
>> +
>> + u_vector_foreach(texHandleObj, &texObj->SamplerHandles) {
>> + if (texHandleObj->sampObj == sampObj)
>> + return texHandleObj;
>> + }
>> + return NULL;
>> +}
>> +
>> +static GLuint64
>> +get_texture_handle(struct gl_context *ctx, struct gl_texture_object
>> *texObj,
>> + struct gl_sampler_object *sampObj)
>> +{
>> + bool separate_sampler = &texObj->Sampler != sampObj;
>> + struct gl_texture_handle_object *texHandleObj;
>> + GLuint64 handle;
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The handle for each texture or texture/sampler pair is unique;
>> the same
>> + * handle will be returned if GetTextureHandleARB is called
>> multiple times
>> + * for the same texture or if GetTextureSamplerHandleARB is
>> called multiple
>> + * times for the same texture/sampler pair."
>> + */
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + texHandleObj = find_texhandleobj(texObj, separate_sampler ?
>> sampObj : NULL);
>> + if (texHandleObj) {
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> + return texHandleObj->handle;
>> + }
>> +
>> + /* Request a new texture handle from the driver. */
>> + handle = ctx->Driver.NewTextureHandle(ctx, texObj, sampObj);
>> + if (!handle) {
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()");
>> + return 0;
>> + }
>> +
>> + /* Store the handle into the texture object. */
>> + texHandleObj = u_vector_add(&texObj->SamplerHandles);
>> + texHandleObj->texObj = texObj;
>> + texHandleObj->sampObj = separate_sampler ? sampObj : NULL;
>> + texHandleObj->handle = handle;
>> +
>> + if (&texObj->Sampler != sampObj) {
>> + /* Store a reference to the handle into the separate sampler
>> object. */
>> + struct gl_texture_handle_object **sampHandleObj;
>> +
>> + sampHandleObj = u_vector_add(&sampObj->Handles);
>> + *sampHandleObj = texHandleObj;
>> + }
>> +
>> + /* When referenced by one or more handles, texture objects are
>> immutable. */
>> + texObj->HandleAllocated = true;
>> + if (texObj->Target == GL_TEXTURE_BUFFER)
>> + texObj->BufferObject->HandleAllocated = true;
>> + sampObj->HandleAllocated = true;
>> +
>> + /* Store the handle in the shared state for all contexts. */
>> + hash_table_insert(ctx->Shared->TextureHandles, handle, texHandleObj);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + return (GLuint64)handle;
>> +}
>> +
>> +static struct gl_image_handle_object *
>> +find_imghandleobj(struct gl_texture_object *texObj, GLint level,
>> + GLboolean layered, GLint layer, GLenum format)
>> +{
>> + struct gl_image_handle_object *imgHandleObj;
>> +
>> + u_vector_foreach(imgHandleObj, &texObj->ImageHandles) {
>> + struct gl_image_unit *u = &imgHandleObj->imgObj;
>> +
>> + if (u->Level == level && u->Layered == layered &&
>> + u->Layer == layer && u->Format == format)
>> + return imgHandleObj;
>> + }
>> + return NULL;
>> +}
>> +
>> +static GLuint64
>> +get_image_handle(struct gl_context *ctx, struct gl_texture_object
>> *texObj,
>> + GLint level, GLboolean layered, GLint layer, GLenum
>> format)
>> +{
>> + struct gl_image_handle_object *imgHandleObj;
>> + struct gl_image_unit imgObj;
>> + GLuint64 handle;
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The handle returned for each combination of <texture>, <level>,
>> + * <layered>, <layer>, and <format> is unique; the same handle
>> will be
>> + * returned if GetImageHandleARB is called multiple times with the
>> same
>> + * parameters."
>> + */
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> + imgHandleObj = find_imghandleobj(texObj, level, layered, layer,
>> format);
>> + if (imgHandleObj) {
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> + return imgHandleObj->handle;
>> + }
>> +
>> + imgObj.TexObj = texObj; /* weak reference */
>> + imgObj.Level = level;
>> + imgObj.Access = GL_READ_WRITE;
>> + imgObj.Format = format;
>> + imgObj._ActualFormat = _mesa_get_shader_image_format(format);
>> +
>> + if (_mesa_tex_target_is_layered(texObj->Target)) {
>> + imgObj.Layered = layered;
>> + imgObj.Layer = layer;
>> + imgObj._Layer = (imgObj.Layered ? 0 : imgObj.Layer);
>> + } else {
>> + imgObj.Layered = GL_FALSE;
>> + imgObj.Layer = 0;
>> + }
>> +
>> + /* Request a new image handle from the driver. */
>> + handle = ctx->Driver.NewImageHandle(ctx, &imgObj);
>> + if (!handle) {
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()");
>> + return 0;
>> + }
>> +
>> + /* Store the handle into the texture object. */
>> + imgHandleObj = u_vector_add(&texObj->ImageHandles);
>> + memcpy(&imgHandleObj->imgObj, &imgObj, sizeof(struct gl_image_unit));
>> + imgHandleObj->handle = handle;
>> +
>> + /* When referenced by one or more handles, texture objects are
>> immutable. */
>> + texObj->HandleAllocated = true;
>> + if (texObj->Target == GL_TEXTURE_BUFFER)
>> + texObj->BufferObject->HandleAllocated = true;
>> + texObj->Sampler.HandleAllocated = true;
>> +
>> + /* Store the handle in the shared state for all contexts. */
>> + hash_table_insert(ctx->Shared->ImageHandles, handle, imgHandleObj);
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +
>> + return (GLuint64)handle;
>> +}
>> +
>> +/**
>> + * Init/free resident handles per-context.
>> + */
>> +void
>> +_mesa_init_resident_handles(struct gl_context *ctx)
>> +{
>> +#if !defined(MESA_ARCH_X86_64)
>> + ctx->ResidentTextureHandles =
>> + _mesa_hash_table_create(NULL, key_hash, key_equals);
>> + ctx->ResidentImageHandles =
>> + _mesa_hash_table_create(NULL, key_hash, key_equals);
>> +#else
>> + ctx->ResidentTextureHandles =
>> + _mesa_hash_table_create(NULL, _mesa_hash_pointer,
>> + _mesa_key_pointer_equal);
>> + ctx->ResidentImageHandles =
>> + _mesa_hash_table_create(NULL, _mesa_hash_pointer,
>> + _mesa_key_pointer_equal);
>> +#endif
>> +}
>> +
>> +void
>> +_mesa_free_resident_handles(struct gl_context *ctx)
>> +{
>> + _mesa_hash_table_destroy(ctx->ResidentTextureHandles, NULL);
>> + _mesa_hash_table_destroy(ctx->ResidentImageHandles, NULL);
>> +}
>> +
>> +/**
>> + * Init/free shared handles.
>> + */
>> +void
>> +_mesa_init_shared_handles(struct gl_shared_state *shared)
>> +{
>> +#if !defined(MESA_ARCH_X86_64)
>> + shared->TextureHandles =
>> + _mesa_hash_table_create(NULL, key_hash, key_equals);
>> + shared->ImageHandles =
>> + _mesa_hash_table_create(NULL, key_hash, key_equals);
>> +#else
>> + shared->TextureHandles =
>> + _mesa_hash_table_create(NULL, _mesa_hash_pointer,
>> + _mesa_key_pointer_equal);
>> + shared->ImageHandles =
>> + _mesa_hash_table_create(NULL, _mesa_hash_pointer,
>> + _mesa_key_pointer_equal);
>> +#endif
>> + mtx_init(&shared->HandlesMutex, mtx_recursive);
>> +}
>> +
>> +void
>> +_mesa_free_shared_handles(struct gl_shared_state *shared)
>> +{
>> + _mesa_hash_table_destroy(shared->TextureHandles, NULL);
>> + _mesa_hash_table_destroy(shared->ImageHandles, NULL);
>> + mtx_destroy(&shared->HandlesMutex);
>> +}
>> +
>> +/**
>> + * Init/free texture/image handles per-texture object.
>> + */
>> +void
>> +_mesa_init_texture_handles(struct gl_texture_object *texObj)
>> +{
>> + uint32_t element_size;
>> +
>> + element_size =
>> + util_next_power_of_two(sizeof(struct gl_texture_handle_object));
>> + u_vector_init(&texObj->SamplerHandles, element_size, 2 *
>> element_size);
>> +
>> + element_size =
>> + util_next_power_of_two(sizeof(struct gl_image_handle_object));
>> + u_vector_init(&texObj->ImageHandles, element_size, 2 * element_size);
>> +}
>> +
>> +void
>> +_mesa_make_texture_handles_non_resident(struct gl_context *ctx,
>> + struct gl_texture_object
>> *texObj)
>> +{
>> + struct gl_texture_handle_object *texHandleObj;
>> + struct gl_image_handle_object *imgHandleObj;
>> +
>> + mtx_lock(&ctx->Shared->HandlesMutex);
>> +
>> + u_vector_foreach(texHandleObj, &texObj->SamplerHandles) {
>> + if (is_texture_handle_resident(ctx, texHandleObj->handle))
>> + make_texture_handle_resident(ctx, texHandleObj, false);
>> + }
>> +
>> + u_vector_foreach(imgHandleObj, &texObj->ImageHandles) {
>> + if (is_image_handle_resident(ctx, imgHandleObj->handle))
>> + make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY,
>> false);
>> + }
>> +
>> + mtx_unlock(&ctx->Shared->HandlesMutex);
>> +}
>> +
>> +void
>> +_mesa_delete_texture_handles(struct gl_context *ctx,
>> + struct gl_texture_object *texObj)
>> +{
>> + struct gl_texture_handle_object *texHandleObj;
>> + struct gl_image_handle_object *imgHandleObj;
>> +
>> + /* Texture handles */
>> + u_vector_foreach(texHandleObj, &texObj->SamplerHandles)
>> + delete_texture_handle(ctx, texHandleObj->handle);
>> + u_vector_finish(&texObj->SamplerHandles);
>> +
>> + /* Image handles */
>> + u_vector_foreach(imgHandleObj, &texObj->ImageHandles)
>> + delete_image_handle(ctx, imgHandleObj->handle);
>> + u_vector_finish(&texObj->ImageHandles);
>> +}
>> +
>> +/**
>> + * Init/free texture handles per-sampler object.
>> + */
>> +void
>> +_mesa_init_sampler_handles(struct gl_sampler_object *sampObj)
>> +{
>> + uint32_t element_size;
>> +
>> + element_size =
>> + util_next_power_of_two(sizeof(struct gl_texture_handle_object));
>> + u_vector_init(&sampObj->Handles, element_size, 2 * element_size);
>> +}
>> +
>> +void
>> +_mesa_delete_sampler_handles(struct gl_context *ctx,
>> + struct gl_sampler_object *sampObj)
>> +{
>> + struct gl_texture_handle_object **sampHandleObj;
>> +
>> + u_vector_foreach(sampHandleObj, &sampObj->Handles)
>> + delete_texture_handle(ctx, (*sampHandleObj)->handle);
>> + u_vector_finish(&sampObj->Handles);
>> +}
>> +
>> +static GLboolean
>> +is_sampler_border_color_valid(struct gl_sampler_object *samp)
>> +{
>> + static const GLfloat valid_float_border_colors[4][4] = {
>> + { 0.0, 0.0, 0.0, 0.0 },
>> + { 0.0, 0.0, 0.0, 1.0 },
>> + { 1.0, 1.0, 1.0, 0.0 },
>> + { 1.0, 1.0, 1.0, 1.0 },
>> + };
>> + static const GLint valid_integer_border_colors[4][4] = {
>> + { 0, 0, 0, 0 },
>> + { 0, 0, 0, 1 },
>> + { 1, 1, 1, 0 },
>> + { 1, 1, 1, 1 },
>> + };
>> + size_t size = sizeof(samp->BorderColor.ui);
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated if the border color
>> (taken from
>> + * the embedded sampler for GetTextureHandleARB or from the
>> <sampler> for
>> + * GetTextureSamplerHandleARB) is not one of the following
>> allowed values.
>> + * If the texture's base internal format is signed or unsigned
>> integer,
>> + * allowed values are (0,0,0,0), (0,0,0,1), (1,1,1,0), and
>> (1,1,1,1). If
>> + * the base internal format is not integer, allowed values are
>> + * (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
>> + * (1.0,1.0,1.0,1.0)."
>> + */
>> + if (!memcmp(samp->BorderColor.f, valid_float_border_colors[0],
>> size) ||
>> + !memcmp(samp->BorderColor.f, valid_float_border_colors[1],
>> size) ||
>> + !memcmp(samp->BorderColor.f, valid_float_border_colors[2],
>> size) ||
>> + !memcmp(samp->BorderColor.f, valid_float_border_colors[3], size))
>> + return GL_TRUE;
>> +
>> + if (!memcmp(samp->BorderColor.ui, valid_integer_border_colors[0],
>> size) ||
>> + !memcmp(samp->BorderColor.ui, valid_integer_border_colors[1],
>> size) ||
>> + !memcmp(samp->BorderColor.ui, valid_integer_border_colors[2],
>> size) ||
>> + !memcmp(samp->BorderColor.ui, valid_integer_border_colors[3],
>> size))
>> + return GL_TRUE;
>> +
>> + return GL_FALSE;
>> +}
>> +
>> GLuint64 GLAPIENTRY
>> _mesa_GetTextureHandleARB(GLuint texture)
>> {
>> - return 0;
>> + struct gl_texture_object *texObj = NULL;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureHandleARB(unsupported)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_VALUE is generated by GetTextureHandleARB or
>> + * GetTextureSamplerHandleARB if <texture> is zero or not the
>> name of an
>> + * existing texture object."
>> + */
>> + if (texture > 0)
>> + texObj = _mesa_lookup_texture(ctx, texture);
>> +
>> + if (!texObj) {
>> + _mesa_error(ctx, GL_INVALID_VALUE,
>> "glGetTextureHandleARB(texture)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> GetTextureHandleARB or
>> + * GetTextureSamplerHandleARB if the texture object specified by
>> <texture>
>> + * is not complete."
>> + */
>> + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
>> + _mesa_test_texobj_completeness(ctx, texObj);
>> + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureHandleARB(incomplete texture)");
>> + return 0;
>> + }
>> + }
>> +
>> + if (!is_sampler_border_color_valid(&texObj->Sampler)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureHandleARB(invalid border color)");
>> + return 0;
>> + }
>> +
>> + return get_texture_handle(ctx, texObj, &texObj->Sampler);
>> }
>> GLuint64 GLAPIENTRY
>> _mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler)
>> {
>> - return 0;
>> + struct gl_texture_object *texObj = NULL;
>> + struct gl_sampler_object *sampObj;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureSamplerHandleARB(unsupported)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_VALUE is generated by GetTextureHandleARB or
>> + * GetTextureSamplerHandleARB if <texture> is zero or not the
>> name of an
>> + * existing texture object."
>> + */
>> + if (texture > 0)
>> + texObj = _mesa_lookup_texture(ctx, texture);
>> +
>> + if (!texObj) {
>> + _mesa_error(ctx, GL_INVALID_VALUE,
>> + "glGetTextureSamplerHandleARB(texture)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_VALUE is generated by
>> GetTextureSamplerHandleARB if
>> + * <sampler> is zero or is not the name of an existing sampler
>> object."
>> + */
>> + sampObj = _mesa_lookup_samplerobj(ctx, sampler);
>> + if (!sampObj) {
>> + _mesa_error(ctx, GL_INVALID_VALUE,
>> + "glGetTextureSamplerHandleARB(sampler)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> GetTextureHandleARB or
>> + * GetTextureSamplerHandleARB if the texture object specified by
>> <texture>
>> + * is not complete."
>> + */
>> + if (!_mesa_is_texture_complete(texObj, sampObj)) {
>> + _mesa_test_texobj_completeness(ctx, texObj);
>> + if (!_mesa_is_texture_complete(texObj, sampObj)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureSamplerHandleARB(incomplete
>> texture)");
>> + return 0;
>> + }
>> + }
>> +
>> + if (!is_sampler_border_color_valid(sampObj)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetTextureSamplerHandleARB(invalid border color)");
>> + return 0;
>> + }
>> +
>> + return get_texture_handle(ctx, texObj, sampObj);
>> }
>> void GLAPIENTRY
>> _mesa_MakeTextureHandleResidentARB(GLuint64 handle)
>> {
>> + struct gl_texture_handle_object *texHandleObj;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleResidentARB(unsupported)");
>> + return;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> MakeTextureHandleResidentARB
>> + * if <handle> is not a valid texture handle, or if <handle> is
>> already
>> + * resident in the current GL context."
>> + */
>> + texHandleObj = lookup_texture_handle(ctx, handle);
>> + if (!texHandleObj) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleResidentARB(handle)");
>> + return;
>> + }
>> +
>> + if (is_texture_handle_resident(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleResidentARB(already resident)");
>> + return;
>> + }
>> +
>> + make_texture_handle_resident(ctx, texHandleObj, true);
>> }
>> void GLAPIENTRY
>> _mesa_MakeTextureHandleNonResidentARB(GLuint64 handle)
>> {
>> + struct gl_texture_handle_object *texHandleObj;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleNonResidentARB(unsupported)");
>> + return;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> + * MakeTextureHandleNonResidentARB if <handle> is not a valid
>> texture
>> + * handle, or if <handle> is not resident in the current GL
>> context."
>> + */
>> + texHandleObj = lookup_texture_handle(ctx, handle);
>> + if (!texHandleObj) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleNonResidentARB(handle)");
>> + return;
>> + }
>> +
>> + if (!is_texture_handle_resident(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeTextureHandleNonResidentARB(not resident)");
>> + return;
>> + }
>> +
>> + make_texture_handle_resident(ctx, texHandleObj, false);
>> }
>> GLuint64 GLAPIENTRY
>> _mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered,
>> GLint layer, GLenum format)
>> {
>> - return 0;
>> + struct gl_texture_object *texObj = NULL;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx) ||
>> + !_mesa_has_ARB_shader_image_load_store(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetImageHandleARB(unsupported)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_VALUE is generated by GetImageHandleARB if
>> <texture>
>> + * is zero or not the name of an existing texture object, if the
>> image for
>> + * <level> does not existing in <texture>, or if <layered> is
>> FALSE and
>> + * <layer> is greater than or equal to the number of layers in
>> the image at
>> + * <level>."
>> + */
>> + if (texture > 0)
>> + texObj = _mesa_lookup_texture(ctx, texture);
>> +
>> + if (!texObj) {
>> + _mesa_error(ctx, GL_INVALID_VALUE,
>> "glGetImageHandleARB(texture)");
>> + return 0;
>> + }
>> +
>> + if (level < 0 || level >= _mesa_max_texture_levels(ctx,
>> texObj->Target)) {
>> + _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(level)");
>> + return 0;
>> + }
>> +
>> + if (!layered && layer > _mesa_get_texture_layers(texObj, level)) {
>> + _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(layer)");
>> + return 0;
>> + }
>> +
>> + if (!_mesa_is_shader_image_format_supported(ctx, format)) {
>> + _mesa_error(ctx, GL_INVALID_VALUE, "glGetImageHandleARB(format)");
>> + return 0;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by GetImageHandleARB
>> if the
>> + * texture object <texture> is not complete or if <layered> is
>> TRUE and
>> + * <texture> is not a three-dimensional, one-dimensional array, two
>> + * dimensional array, cube map, or cube map array texture."
>> + */
>> + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
>> + _mesa_test_texobj_completeness(ctx, texObj);
>> + if (!_mesa_is_texture_complete(texObj, &texObj->Sampler)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetImageHandleARB(incomplete texture)");
>> + return 0;
>> + }
>> + }
>> +
>> + if (layered && !_mesa_tex_target_is_layered(texObj->Target)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glGetImageHandleARB(not layered)");
>> + return 0;
>> + }
>> +
>> + return get_image_handle(ctx, texObj, level, layered, layer, format);
>> }
>> void GLAPIENTRY
>> _mesa_MakeImageHandleResidentARB(GLuint64 handle, GLenum access)
>> {
>> + struct gl_image_handle_object *imgHandleObj;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx) ||
>> + !_mesa_has_ARB_shader_image_load_store(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleResidentARB(unsupported)");
>> + return;
>> + }
>> +
>> + if (access != GL_READ_ONLY &&
>> + access != GL_WRITE_ONLY &&
>> + access != GL_READ_WRITE) {
>> + _mesa_error(ctx, GL_INVALID_ENUM,
>> + "glMakeImageHandleResidentARB(access)");
>> + return;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> MakeImageHandleResidentARB
>> + * if <handle> is not a valid image handle, or if <handle> is
>> already
>> + * resident in the current GL context."
>> + */
>> + imgHandleObj = lookup_image_handle(ctx, handle);
>> + if (!imgHandleObj) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleResidentARB(handle)");
>> + return;
>> + }
>> +
>> + if (is_image_handle_resident(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleResidentARB(already resident)");
>> + return;
>> + }
>> +
>> + make_image_handle_resident(ctx, imgHandleObj, access, true);
>> }
>> void GLAPIENTRY
>> _mesa_MakeImageHandleNonResidentARB(GLuint64 handle)
>> {
>> + struct gl_image_handle_object *imgHandleObj;
>> +
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx) ||
>> + !_mesa_has_ARB_shader_image_load_store(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleNonResidentARB(unsupported)");
>> + return;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION is generated by
>> + * MakeImageHandleNonResidentARB if <handle> is not a valid image
>> handle,
>> + * or if <handle> is not resident in the current GL context."
>> + */
>> + imgHandleObj = lookup_image_handle(ctx, handle);
>> + if (!imgHandleObj) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleNonResidentARB(handle)");
>> + return;
>> + }
>> +
>> + if (!is_image_handle_resident(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glMakeImageHandleNonResidentARB(not resident)");
>> + return;
>> + }
>> +
>> + make_image_handle_resident(ctx, imgHandleObj, GL_READ_ONLY, false);
>> }
>> GLboolean GLAPIENTRY
>> _mesa_IsTextureHandleResidentARB(GLuint64 handle)
>> {
>> - return GL_FALSE;
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glIsTextureHandleResidentARB(unsupported)");
>> + return GL_FALSE;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION will be generated by
>> + * IsTextureHandleResidentARB and IsImageHandleResidentARB if
>> <handle> is
>> + * not a valid texture or image handle, respectively."
>> + */
>> + if (!lookup_texture_handle(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glIsTextureHandleResidentARB(handle)");
>> + return GL_FALSE;
>> + }
>> +
>> + return is_texture_handle_resident(ctx, handle);
>> }
>> GLboolean GLAPIENTRY
>> _mesa_IsImageHandleResidentARB(GLuint64 handle)
>> {
>> - return GL_FALSE;
>> + GET_CURRENT_CONTEXT(ctx);
>> +
>> + if (!_mesa_has_ARB_bindless_texture(ctx) ||
>> + !_mesa_has_ARB_shader_image_load_store(ctx)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glIsImageHandleResidentARB(unsupported)");
>> + return GL_FALSE;
>> + }
>> +
>> + /* The ARB_bindless_texture spec says:
>> + *
>> + * "The error INVALID_OPERATION will be generated by
>> + * IsTextureHandleResidentARB and IsImageHandleResidentARB if
>> <handle> is
>> + * not a valid texture or image handle, respectively."
>> + */
>> + if (!lookup_image_handle(ctx, handle)) {
>> + _mesa_error(ctx, GL_INVALID_OPERATION,
>> + "glIsImageHandleResidentARB(handle)");
>> + return GL_FALSE;
>> + }
>> +
>> + return is_image_handle_resident(ctx, handle);
>> }
>> diff --git a/src/mesa/main/texturebindless.h
>> b/src/mesa/main/texturebindless.h
>> index 88b84ce275..d584f5cc0c 100644
>> --- a/src/mesa/main/texturebindless.h
>> +++ b/src/mesa/main/texturebindless.h
>> @@ -31,6 +31,38 @@ extern "C" {
>> #endif
>> /**
>> + * \name Internal functions
>> + */
>> +/*@{*/
>> +
>> +void
>> +_mesa_init_resident_handles(struct gl_context *ctx);
>> +void
>> +_mesa_free_resident_handles(struct gl_context *ctx);
>> +
>> +void
>> +_mesa_init_shared_handles(struct gl_shared_state *shared);
>> +void
>> +_mesa_free_shared_handles(struct gl_shared_state *shared);
>> +
>> +void
>> +_mesa_init_texture_handles(struct gl_texture_object *texObj);
>> +void
>> +_mesa_make_texture_handles_non_resident(struct gl_context *ctx,
>> + struct gl_texture_object
>> *texObj);
>> +void
>> +_mesa_delete_texture_handles(struct gl_context *ctx,
>> + struct gl_texture_object *texObj);
>> +
>> +void
>> +_mesa_init_sampler_handles(struct gl_sampler_object *sampObj);
>> +void
>> +_mesa_delete_sampler_handles(struct gl_context *ctx,
>> + struct gl_sampler_object *sampObj);
>> +
>> +/*@}*/
>> +
>> +/**
>> * \name API functions
>> */
>> /*@{*/
>>
>
>
More information about the mesa-dev
mailing list