[Mesa-dev] [PATCH 7/8] mesa: Add skeleton implementations of glInvalidateTex{Sub, }Image

Brian Paul brian.e.paul at gmail.com
Mon Aug 13 20:01:39 PDT 2012


On Mon, Aug 13, 2012 at 7:24 PM, Ian Romanick <idr at freedesktop.org> wrote:
> From: Ian Romanick <ian.d.romanick at intel.com>
>
> These are part of GL_ARB_invalidate_subdata (but not OpenGL ES 3.0).
>
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
>  src/mesa/main/api_exec.c |    5 +
>  src/mesa/main/texobj.c   |  194 ++++++++++++++++++++++++++++++++++++++++++++++
>  src/mesa/main/texobj.h   |    8 ++
>  3 files changed, 207 insertions(+), 0 deletions(-)
>
> diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
> index 66c4a67..59a9aeb 100644
> --- a/src/mesa/main/api_exec.c
> +++ b/src/mesa/main/api_exec.c
> @@ -827,6 +827,11 @@ _mesa_create_exec_table(struct gl_context *ctx)
>     _mesa_init_sampler_object_dispatch(exec);
>  #endif
>
> +   if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE) {
> +      SET_InvalidateTexSubImage(exec, _mesa_InvalidateTexSubImage);
> +      SET_InvalidateTexImage(exec, _mesa_InvalidateTexImage);
> +   }
> +
>     if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE
>         || (ctx->API == API_OPENGLES2 && ctx->Version >= 30)) {
>        SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer);
> diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
> index 02e37be..36ad7c6 100644
> --- a/src/mesa/main/texobj.c
> +++ b/src/mesa/main/texobj.c
> @@ -877,7 +877,58 @@ _mesa_total_texture_memory(struct gl_context *ctx)
>     return total;
>  }
>
> +static struct gl_texture_object *
> +invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture,
> +                                 GLint level, const char *name)
> +{
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "If <texture> is zero or is not the name of a texture, the error
> +    *     INVALID_VALUE is generated."
> +    *
> +    * This performs the error check in a different order than listed in the
> +    * spec.  We have to get the texture object before we can validate the
> +    * other parameters against values in the texture object.
> +    */
> +   struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture);
> +   if (texture == 0 || t == NULL) {
> +      _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name);
> +      return NULL;
> +   }
> +
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "If <level> is less than zero or greater than the base 2 logarithm
> +    *     of the maximum texture width, height, or depth, the error
> +    *     INVALID_VALUE is generated."
> +    */
> +   if (level < 0 || level > t->MaxLevel) {
> +      _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
> +      return NULL;
> +   }
> +
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
> +    *     TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
> +    *     is not zero, the error INVALID_VALUE is generated."
> +    */
> +   if (level != 0) {
> +      switch (t->Target) {
> +      case GL_TEXTURE_RECTANGLE:
> +      case GL_TEXTURE_BUFFER:
> +      case GL_TEXTURE_2D_MULTISAMPLE:
> +      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> +         _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
> +         return NULL;
> +
> +      default:
> +         break;
> +      }
> +   }
>
> +   return t;
> +}
>
>  /*@}*/
>
> @@ -1346,4 +1397,147 @@ _mesa_unlock_context_textures( struct gl_context *ctx )
>     _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
>  }
>
> +void GLAPIENTRY
> +_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
> +                            GLint yoffset, GLint zoffset, GLsizei width,
> +                            GLsizei height, GLsizei depth)
> +{
> +   struct gl_texture_object *t;
> +   struct gl_texture_image *image;
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   ASSERT_OUTSIDE_BEGIN_END(ctx);
> +
> +   t = invalidate_tex_image_error_check(ctx, texture, level,
> +                                        "glInvalidateTexSubImage");
> +
> +   /* The GL_ARB_invalidate_subdata spec says:
> +    *
> +    *     "...the specified subregion must be between -<b> and <dim>+<b> where
> +    *     <dim> is the size of the dimension of the texture image, and <b> is
> +    *     the size of the border of that texture image, otherwise
> +    *     INVALID_VALUE is generated (border is not applied to dimensions that
> +    *     don't exist in a given texture target)."
> +    */
> +   image = t->Image[0][level];
> +   if (image) {
> +      int xBorder;
> +      int yBorder;
> +      int zBorder;
> +      int imageWidth;
> +      int imageHeight;
> +      int imageDepth;
> +
> +      switch (t->Target) {
> +      case GL_TEXTURE_BUFFER:
> +         xBorder = 0;
> +         yBorder = 0;
> +         zBorder = 0;
> +         imageWidth = 1;
> +         imageHeight = 1;
> +         imageDepth = 1;

I haven't checked the spec yet, but is imageWidth=1 right?  It looks
peculiar.  Maybe add a comment?

> +         break;
> +      case GL_TEXTURE_1D:
> +         xBorder = image->Border;
> +         yBorder = 0;
> +         zBorder = 0;
> +         imageWidth = image->Width;
> +         imageHeight = 1;
> +         imageDepth = 1;
> +         break;
> +      case GL_TEXTURE_1D_ARRAY:
> +         xBorder = image->Border;
> +         yBorder = 0;
> +         zBorder = 0;
> +         imageWidth = image->Width;
> +         imageHeight = image->Height;
> +         imageDepth = 1;
> +         break;
> +      case GL_TEXTURE_2D:
> +      case GL_TEXTURE_CUBE_MAP:
> +      case GL_TEXTURE_RECTANGLE:
> +      case GL_TEXTURE_2D_MULTISAMPLE:
> +         xBorder = image->Border;
> +         yBorder = image->Border;
> +         zBorder = 0;
> +         imageWidth = image->Width;
> +         imageHeight = image->Height;
> +         imageDepth = 1;
> +         break;
> +      case GL_TEXTURE_2D_ARRAY:
> +      case GL_TEXTURE_CUBE_MAP_ARRAY:
> +         xBorder = image->Border;
> +         yBorder = image->Border;
> +         zBorder = 0;
> +         imageWidth = image->Width;
> +         imageHeight = image->Height;
> +         imageDepth = image->Depth;
> +         break;
> +      case GL_TEXTURE_3D:
> +         xBorder = image->Border;
> +         yBorder = image->Border;
> +         zBorder = image->Border;
> +         imageWidth = image->Width;
> +         imageHeight = image->Height;
> +         imageDepth = image->Depth;
> +         break;
> +      }

I think there should be a default case above, both to catch potential
oversights when new texture targets are added and because I think some
compilers will complain about unitialized values for the border and
size vars.


> +
> +      if (xoffset < -xBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)");
> +         return;
> +      }
> +
> +      if (xoffset + width > imageWidth + xBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE,
> +                     "glInvalidateSubTexImage(xoffset+width)");
> +         return;
> +      }
> +
> +      if (yoffset < -yBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)");
> +         return;
> +      }
> +
> +      if (yoffset + height > imageHeight + yBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE,
> +                     "glInvalidateSubTexImage(yoffset+height)");
> +         return;
> +      }
> +
> +      if (zoffset < -zBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE,
> +                     "glInvalidateSubTexImage(zoffset)");
> +         return;
> +      }
> +
> +      if (zoffset + depth  > imageDepth + zBorder) {
> +         _mesa_error(ctx, GL_INVALID_VALUE,
> +                     "glInvalidateSubTexImage(zoffset+depth)");
> +         return;
> +      }
> +   }
> +
> +   /* We don't actually do anything for this yet.  Just return after
> +    * validating the parameters and generating the required errors.
> +    */
> +   return;
> +}
> +
> +void GLAPIENTRY
> +_mesa_InvalidateTexImage(GLuint texture, GLint level)
> +{
> +   GET_CURRENT_CONTEXT(ctx);
> +
> +   ASSERT_OUTSIDE_BEGIN_END(ctx);
> +
> +   invalidate_tex_image_error_check(ctx, texture, level,
> +                                    "glInvalidateTexImage");
> +
> +   /* We don't actually do anything for this yet.  Just return after
> +    * validating the parameters and generating the required errors.
> +    */
> +   return;
> +}
> +
>  /*@}*/
> diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
> index 23e1ade..93e0d77 100644
> --- a/src/mesa/main/texobj.h
> +++ b/src/mesa/main/texobj.h
> @@ -152,6 +152,14 @@ _mesa_AreTexturesResident( GLsizei n, const GLuint *textures,
>  extern GLboolean GLAPIENTRY
>  _mesa_IsTexture( GLuint texture );
>
> +extern void GLAPIENTRY
> +_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
> +                            GLint yoffset, GLint zoffset, GLsizei width,
> +                            GLsizei height, GLsizei depth);
> +
> +extern void GLAPIENTRY
> +_mesa_InvalidateTexImage(GLuint texture, GLint level);
> +
>  /*@}*/
>


More information about the mesa-dev mailing list