X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexobj.c;h=8cd70c3eaea8804d651adb4354d52329c2edd8ac;hb=ab6d383e32311800ae8bbe0e9d63a4e8d80a66de;hp=fbd498dd93547301a414195972e55390e660f76c;hpb=a710c21ac200fc1c80a6209862e837f0a75f4cc5;p=mesa.git diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index fbd498dd935..8cd70c3eaea 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" @@ -116,9 +117,10 @@ _mesa_lookup_texture(struct gl_context *ctx, GLuint id) struct gl_texture_object * _mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func) { - struct gl_texture_object *texObj; + struct gl_texture_object *texObj = NULL; - texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */ + if (id > 0) + texObj = _mesa_lookup_texture(ctx, id); /* Returns NULL if not found. */ if (!texObj) _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture)", func); @@ -126,19 +128,6 @@ _mesa_lookup_texture_err(struct gl_context *ctx, GLuint id, const char* func) return texObj; } -void -_mesa_begin_texture_lookups(struct gl_context *ctx) -{ - _mesa_HashLockMutex(ctx->Shared->TexObjects); -} - - -void -_mesa_end_texture_lookups(struct gl_context *ctx) -{ - _mesa_HashUnlockMutex(ctx->Shared->TexObjects); -} - struct gl_texture_object * _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) @@ -245,11 +234,14 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) * \return pointer to new texture object. */ struct gl_texture_object * -_mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target ) +_mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target) { struct gl_texture_object *obj; - (void) ctx; + obj = MALLOC_STRUCT(gl_texture_object); + if (!obj) + return NULL; + _mesa_initialize_texture_object(ctx, obj, name, target); return obj; } @@ -323,6 +315,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; @@ -332,6 +325,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); } @@ -341,13 +337,13 @@ _mesa_initialize_texture_object( struct gl_context *ctx, */ static void finish_texture_init(struct gl_context *ctx, GLenum target, - struct gl_texture_object *obj) + struct gl_texture_object *obj, int targetIndex) { GLenum filter = GL_LINEAR; assert(obj->Target == 0); obj->Target = target; - obj->TargetIndex = _mesa_tex_target_to_index(ctx, target); + obj->TargetIndex = targetIndex; assert(obj->TargetIndex < NUM_TEXTURE_TARGETS); switch (target) { @@ -409,6 +405,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) */ @@ -578,16 +577,10 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr, /* reference new texture */ assert(valid_texture_object(tex)); mtx_lock(&tex->Mutex); - if (tex->RefCount == 0) { - /* this texture's being deleted (look just above) */ - /* Not sure this can every really happen. Warn if it does. */ - _mesa_problem(NULL, "referencing deleted texture object"); - *ptr = NULL; - } - else { - tex->RefCount++; - *ptr = tex; - } + assert(tex->RefCount > 0); + + tex->RefCount++; + *ptr = tex; mtx_unlock(&tex->Mutex); } } @@ -931,7 +924,7 @@ _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj) { texObj->_BaseComplete = GL_FALSE; texObj->_MipmapComplete = GL_FALSE; - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE_OBJECT; } @@ -1202,14 +1195,6 @@ create_textures(struct gl_context *ctx, GLenum target, GLuint first; GLint i; - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "%s %d\n", caller, n); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller); - return; - } - if (!textures) return; @@ -1227,7 +1212,7 @@ create_textures(struct gl_context *ctx, GLenum target, texObj = ctx->Driver.NewTextureObject(ctx, name, target); if (!texObj) { _mesa_HashUnlockMutex(ctx->Shared->TexObjects); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sTextures", caller); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return; } @@ -1240,6 +1225,22 @@ create_textures(struct gl_context *ctx, GLenum target, _mesa_HashUnlockMutex(ctx->Shared->TexObjects); } + +static void +create_textures_err(struct gl_context *ctx, GLenum target, + GLsizei n, GLuint *textures, const char *caller) +{ + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "%s %d\n", caller, n); + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", caller); + return; + } + + create_textures(ctx, target, n, textures, caller); +} + /*@}*/ @@ -1264,7 +1265,7 @@ void GLAPIENTRY _mesa_GenTextures(GLsizei n, GLuint *textures) { GET_CURRENT_CONTEXT(ctx); - create_textures(ctx, 0, n, textures, "glGenTextures"); + create_textures_err(ctx, 0, n, textures, "glGenTextures"); } /** @@ -1297,7 +1298,7 @@ _mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures) return; } - create_textures(ctx, target, n, textures, "glCreateTextures"); + create_textures_err(ctx, target, n, textures, "glCreateTextures"); } /** @@ -1411,7 +1412,7 @@ unbind_textures_from_unit(struct gl_context *ctx, GLuint unit) ctx->Driver.BindTexture(ctx, unit, 0, texObj); texUnit->_BoundTextures &= ~(1 << index); - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE_OBJECT; } } @@ -1479,9 +1480,14 @@ _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; + ctx->NewState |= _NEW_TEXTURE_OBJECT; /* The texture _name_ is now free for re-use. * Remove it from the hash table now. @@ -1497,47 +1503,6 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures) } } -/** - * This deletes a texObj without altering the hash table. - */ -void -_mesa_delete_nameless_texture(struct gl_context *ctx, - struct gl_texture_object *texObj) -{ - if (!texObj) - return; - - FLUSH_VERTICES(ctx, 0); - - _mesa_lock_texture(ctx, texObj); - { - /* Check if texture is bound to any framebuffer objects. - * If so, unbind. - * See section 4.4.2.3 of GL_EXT_framebuffer_object. - */ - unbind_texobj_from_fbo(ctx, texObj); - - /* Check if this texture is currently bound to any texture units. - * If so, unbind it. - */ - unbind_texobj_from_texunits(ctx, texObj); - - /* Check if this texture is currently bound to any shader - * image unit. If so, unbind it. - * See section 3.9.X of GL_ARB_shader_image_load_store. - */ - unbind_texobj_from_image_units(ctx, texObj); - } - _mesa_unlock_texture(ctx, texObj); - - ctx->NewState |= _NEW_TEXTURE; - - /* Unreference the texobj. If refcount hits zero, the texture - * will be deleted. - */ - _mesa_reference_texobj(&texObj, NULL); -} - /** * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D @@ -1618,9 +1583,10 @@ bind_texture(struct gl_context *ctx, assert(targetIndex < NUM_TEXTURE_TARGETS); /* Check if this texture is only used by this context and is already bound. - * If so, just return. + * If so, just return. For GL_OES_image_external, rebinding the texture + * always must invalidate cached resources. */ - { + if (targetIndex != TEXTURE_EXTERNAL_INDEX) { bool early_out; mtx_lock(&ctx->Shared->Mutex); early_out = ((ctx->Shared->RefCount == 1) @@ -1632,7 +1598,7 @@ bind_texture(struct gl_context *ctx, } /* flush before changing binding */ - FLUSH_VERTICES(ctx, _NEW_TEXTURE); + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT); /* If the refcount on the previously bound texture is decremented to * zero, it'll be deleted here. @@ -1666,15 +1632,15 @@ _mesa_BindTexture( GLenum target, GLuint texName ) { GET_CURRENT_CONTEXT(ctx); struct gl_texture_object *newTexObj = NULL; - GLint targetIndex; if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glBindTexture %s %d\n", _mesa_enum_to_string(target), (GLint) texName); - targetIndex = _mesa_tex_target_to_index(ctx, target); + int targetIndex = _mesa_tex_target_to_index(ctx, target); if (targetIndex < 0) { - _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target = %s)", + _mesa_enum_to_string(target)); return; } assert(targetIndex < NUM_TEXTURE_TARGETS); @@ -1700,7 +1666,7 @@ _mesa_BindTexture( GLenum target, GLuint texName ) return; } if (newTexObj->Target == 0) { - finish_texture_init(ctx, target, newTexObj); + finish_texture_init(ctx, target, newTexObj, targetIndex); } } else { @@ -1742,21 +1708,12 @@ _mesa_BindTexture( GLenum target, GLuint texName ) * If the named texture is not 0 or a recognized texture name, this throws * GL_INVALID_OPERATION. */ -void GLAPIENTRY -_mesa_BindTextureUnit(GLuint unit, GLuint texture) +static ALWAYS_INLINE void +bind_texture_unit(struct gl_context *ctx, GLuint unit, GLuint texture, + bool no_error) { - GET_CURRENT_CONTEXT(ctx); struct gl_texture_object *texObj; - if (unit >= _mesa_max_tex_unit(ctx)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindTextureUnit(unit=%u)", unit); - return; - } - - if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - _mesa_debug(ctx, "glBindTextureUnit %s %d\n", - _mesa_enum_to_string(GL_TEXTURE0+unit), (GLint) texture); - /* Section 8.1 (Texture Objects) of the OpenGL 4.5 core profile spec * (20141030) says: * "When texture is zero, each of the targets enumerated at the @@ -1770,24 +1727,53 @@ _mesa_BindTextureUnit(GLuint unit, GLuint texture) /* Get the non-default texture object */ texObj = _mesa_lookup_texture(ctx, texture); + if (!no_error) { + /* Error checking */ + if (!texObj) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindTextureUnit(non-gen name)"); + return; + } - /* Error checking */ - if (!texObj) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindTextureUnit(non-gen name)"); - return; - } - if (texObj->Target == 0) { - /* Texture object was gen'd but never bound so the target is not set */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTextureUnit(target)"); - return; + if (texObj->Target == 0) { + /* Texture object was gen'd but never bound so the target is not set */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTextureUnit(target)"); + return; + } } + assert(valid_texture_object(texObj)); bind_texture(ctx, unit, texObj); } +void GLAPIENTRY +_mesa_BindTextureUnit_no_error(GLuint unit, GLuint texture) +{ + GET_CURRENT_CONTEXT(ctx); + bind_texture_unit(ctx, unit, texture, true); +} + + +void GLAPIENTRY +_mesa_BindTextureUnit(GLuint unit, GLuint texture) +{ + GET_CURRENT_CONTEXT(ctx); + + if (unit >= _mesa_max_tex_unit(ctx)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindTextureUnit(unit=%u)", unit); + return; + } + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glBindTextureUnit %s %d\n", + _mesa_enum_to_string(GL_TEXTURE0+unit), (GLint) texture); + + bind_texture_unit(ctx, unit, texture, false); +} + + /** * OpenGL 4.4 / GL_ARB_multi_bind glBindTextures(). */ @@ -1831,7 +1817,7 @@ _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) * their parameters are valid and no other error occurs." */ - _mesa_begin_texture_lookups(ctx); + _mesa_HashLockMutex(ctx->Shared->TexObjects); for (i = 0; i < count; i++) { if (textures[i] != 0) { @@ -1863,7 +1849,7 @@ _mesa_BindTextures(GLuint first, GLsizei count, const GLuint *textures) } } - _mesa_end_texture_lookups(ctx); + _mesa_HashUnlockMutex(ctx->Shared->TexObjects); } else { /* Unbind all textures in the range through +-1 */ for (i = 0; i < count; i++) @@ -1913,7 +1899,7 @@ _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, } } - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE_OBJECT; } @@ -2017,7 +2003,7 @@ _mesa_lock_context_textures( struct gl_context *ctx ) mtx_lock(&ctx->Shared->TexMutex); if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { - ctx->NewState |= _NEW_TEXTURE; + ctx->NewState |= _NEW_TEXTURE_OBJECT; ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp; } }