mesa: rename _mesa_free_errors_data
[mesa.git] / src / mesa / main / texobj.c
index fa8a4d88dcbc4d17af87c4f1a99c99ad92926ef9..3e058975db86c50a044248502559f344d17bda5a 100644 (file)
@@ -35,7 +35,7 @@
 #include "fbobject.h"
 #include "formats.h"
 #include "hash.h"
-#include "imports.h"
+
 #include "macros.h"
 #include "shaderimage.h"
 #include "teximage.h"
@@ -44,6 +44,7 @@
 #include "mtypes.h"
 #include "program/prog_instruction.h"
 #include "texturebindless.h"
+#include "util/u_memory.h"
 
 
 
@@ -218,6 +219,42 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
 }
 
 
+/**
+ * Get the texture object for given target and texunit
+ * Proxy targets are accepted only allowProxyTarget is true.
+ * Return NULL if any error (and record the error).
+ */
+struct gl_texture_object *
+_mesa_get_texobj_by_target_and_texunit(struct gl_context *ctx, GLenum target,
+                                       GLuint texunit, bool allowProxyTarget,
+                                       const char* caller)
+{
+   struct gl_texture_unit *texUnit;
+   int targetIndex;
+
+   if (_mesa_is_proxy_texture(target) && allowProxyTarget) {
+      return _mesa_get_current_tex_object(ctx, target);
+   }
+
+   if (texunit >= ctx->Const.MaxCombinedTextureImageUnits) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(texunit=%d)", caller, texunit);
+      return NULL;
+   }
+
+   texUnit = _mesa_get_tex_unit(ctx, texunit);
+
+   targetIndex = _mesa_tex_target_to_index(ctx, target);
+   if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller);
+      return NULL;
+   }
+   assert(targetIndex < NUM_TEXTURE_TARGETS);
+
+   return texUnit->CurrentTex[targetIndex];
+}
+
+
 /**
  * Allocate and initialize a new texture object.  But don't put it into the
  * texture object hash table.
@@ -272,8 +309,6 @@ _mesa_initialize_texture_object( struct gl_context *ctx,
           target == GL_TEXTURE_2D_MULTISAMPLE ||
           target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
 
-   GLenum filter = GL_LINEAR;
-
    memset(obj, 0, sizeof(*obj));
    /* init the non-zero fields */
    simple_mtx_init(&obj->Mutex, mtx_plain);
@@ -294,30 +329,20 @@ _mesa_initialize_texture_object( struct gl_context *ctx,
    obj->RequiredTextureImageUnits = 1;
 
    /* sampler state */
-   switch (target) {
-      case GL_TEXTURE_2D_MULTISAMPLE:
-      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
-         filter = GL_NEAREST;
-         /* fallthrough */
-
-      case GL_TEXTURE_RECTANGLE_NV:
-      case GL_TEXTURE_EXTERNAL_OES:
-         obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
-         obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
-         obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
-         obj->Sampler.MinFilter = filter;
-         obj->Sampler.MagFilter = filter;
-         break;
-
-      default:
-         obj->Sampler.WrapS = GL_REPEAT;
-         obj->Sampler.WrapT = GL_REPEAT;
-         obj->Sampler.WrapR = GL_REPEAT;
-         obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
-         obj->Sampler.MagFilter = GL_LINEAR;
-         break;
+   if (target == GL_TEXTURE_RECTANGLE_NV ||
+       target == GL_TEXTURE_EXTERNAL_OES) {
+      obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
+      obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
+      obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
+      obj->Sampler.MinFilter = GL_LINEAR;
    }
-
+   else {
+      obj->Sampler.WrapS = GL_REPEAT;
+      obj->Sampler.WrapT = GL_REPEAT;
+      obj->Sampler.WrapR = GL_REPEAT;
+      obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
+   }
+   obj->Sampler.MagFilter = GL_LINEAR;
    obj->Sampler.MinLod = -1000.0;
    obj->Sampler.MaxLod = 1000.0;
    obj->Sampler.LodBias = 0.0;
@@ -733,7 +758,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
       /* Adjust max level for views: the data store may have more levels than
        * the view exposes.
        */
-      t->_MaxLevel = MIN2(t->_MaxLevel, t->NumLevels - 1);
+      t->_MaxLevel = MAX2(MIN2(t->_MaxLevel, t->NumLevels - 1), 0);
    }
 
    /* Compute _MaxLambda = q - p in the spec used during mipmapping */
@@ -1489,6 +1514,10 @@ delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures)
              */
             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
 
+            if (ctx->Driver.TextureRemovedFromShared) {
+               ctx->Driver.TextureRemovedFromShared(ctx, delObj);
+            }
+
             /* Unreference the texobj.  If refcount hits zero, the texture
              * will be deleted.
              */
@@ -1703,26 +1732,35 @@ _mesa_bind_texture(struct gl_context *ctx, GLenum target,
    bind_texture_object(ctx, ctx->Texture.CurrentUnit, tex_obj);
 }
 
-/**
- * Implement glBindTexture().  Do error checking, look-up or create a new
- * texture object, then bind it in the current texture unit.
- *
- * \param target texture target.
- * \param texName texture name.
- * \param texunit texture unit.
- */
-static ALWAYS_INLINE void
-bind_texture(struct gl_context *ctx, GLenum target, GLuint texName,
-             GLenum texunit, bool no_error, const char *caller)
+struct gl_texture_object *
+_mesa_lookup_or_create_texture(struct gl_context *ctx, GLenum target,
+                               GLuint texName, bool no_error, bool is_ext_dsa,
+                               const char *caller)
 {
    struct gl_texture_object *newTexObj = NULL;
    int targetIndex;
 
+   if (is_ext_dsa) {
+      if (_mesa_is_proxy_texture(target)) {
+         /* EXT_dsa allows proxy targets only when texName is 0 */
+         if (texName != 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target = %s)", caller,
+                        _mesa_enum_to_string(target));
+            return NULL;
+         }
+         return _mesa_get_current_tex_object(ctx, target);
+      }
+      if (GL_TEXTURE_CUBE_MAP_POSITIVE_X <= target &&
+          target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
+         target = GL_TEXTURE_CUBE_MAP;
+      }
+   }
+
    targetIndex = _mesa_tex_target_to_index(ctx, target);
    if (!no_error && targetIndex < 0) {
       _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller,
                   _mesa_enum_to_string(target));
-      return;
+      return NULL;
    }
    assert(targetIndex < NUM_TEXTURE_TARGETS);
 
@@ -1744,24 +1782,23 @@ bind_texture(struct gl_context *ctx, GLenum target, GLuint texName,
              */
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(target mismatch)", caller);
-            return;
+            return NULL;
          }
          if (newTexObj->Target == 0) {
             finish_texture_init(ctx, target, newTexObj, targetIndex);
          }
-      }
-      else {
+      } else {
          if (!no_error && ctx->API == API_OPENGL_CORE) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
                         "%s(non-gen name)", caller);
-            return;
+            return NULL;
          }
 
          /* if this is a new texture id, allocate a texture object now */
          newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
          if (!newTexObj) {
             _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
-            return;
+            return NULL;
          }
 
          /* and insert it into hash table */
@@ -1772,6 +1809,27 @@ bind_texture(struct gl_context *ctx, GLenum target, GLuint texName,
    assert(newTexObj->Target == target);
    assert(newTexObj->TargetIndex == targetIndex);
 
+   return newTexObj;
+}
+
+/**
+ * Implement glBindTexture().  Do error checking, look-up or create a new
+ * texture object, then bind it in the current texture unit.
+ *
+ * \param target texture target.
+ * \param texName texture name.
+ * \param texunit texture unit.
+ */
+static ALWAYS_INLINE void
+bind_texture(struct gl_context *ctx, GLenum target, GLuint texName,
+             GLenum texunit, bool no_error, const char *caller)
+{
+   struct gl_texture_object *newTexObj =
+      _mesa_lookup_or_create_texture(ctx, target, texName, no_error, false,
+                                     "glBindTexture");
+   if (!newTexObj)
+      return;
+
    bind_texture_object(ctx, texunit, newTexObj);
 }