[Mesa-dev] [PATCH 11/38] main: Major refactor of get_texture_for_framebuffer.

Fredrik Höglund fredrik at kde.org
Sun Apr 12 08:39:51 PDT 2015


This looks like a very nice cleanup indeed!

One thing I noticed though is that fbobject.c seems to use two blank
lines between function definitions, although it's not consistent about it.
The functions introduced in this patch only have one blank line between
them.

Some more comments (mostly nitpicks) below.

On Wednesday 04 March 2015, Laura Ekstrand wrote:
> This splits off the (still) rather large chunk that is
> get_texture_for_framebuffer into lots of smaller functions specialized to
> service the wide variety of unique needs of *FramebufferTexture* entry points.
> The result is much cleaner because, rather than having a pile of branches and
> confusing conditions (like the boolean layered), the uniqueness is baked into
> the entry points. The entry points know whether or not they are layered or use
> a textarget.
> ---
>  src/mesa/main/fbobject.c | 457 +++++++++++++++++++++++++----------------------
>  src/mesa/main/fbobject.h |   2 +-
>  2 files changed, 247 insertions(+), 212 deletions(-)
> 
> diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
> index f634aed..4df0b6b 100644
> --- a/src/mesa/main/fbobject.c
> +++ b/src/mesa/main/fbobject.c
> @@ -2415,14 +2415,7 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
>  
>  /**
>   * Common code called by gl*FramebufferTexture*() to retrieve the correct
> - * texture object pointer and check for associated errors.
> - *
> - * \param textarget is the textarget that was passed to the
> - * glFramebufferTexture...() function, or 0 if the corresponding function
> - * doesn't have a textarget parameter.
> - *
> - * \param layered is true if this function was called from
> - * gl*FramebufferTexture(), false otherwise.
> + * texture object pointer.
>   *
>   * \param texObj where the pointer to the texture object is returned.  Note
>   * that a successful call may return texObj = NULL.
> @@ -2430,20 +2423,12 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb,
>   * \return true if no errors, false if errors
>   */
>  static bool
> -get_texture_for_framebuffer(struct gl_context *ctx,
> -                            GLuint texture, GLenum textarget,
> -                            GLint level, GLuint zoffset, GLboolean *layered,
> -                            const char *caller,
> +get_texture_for_framebuffer(struct gl_context *ctx, GLuint texture,
> +                            bool layered, const char *caller,
>                              struct gl_texture_object **texObj)
>  {
> -   GLenum maxLevelsTarget;
> -   GLboolean err = GL_TRUE;
> -
>     *texObj = NULL; /* This will get returned if texture = 0. */
>  
> -   /* The textarget, level, and zoffset parameters are only validated if
> -    * texture is non-zero.
> -    */
>     if (!texture)
>        return true;
>  
> @@ -2458,27 +2443,40 @@ get_texture_for_framebuffer(struct gl_context *ctx,
>         * value, while the other commands throw invalid operation (where
>         * *layered = GL_FALSE).
>         */
> -      GLenum no_texobj_err = *layered ? GL_INVALID_VALUE :
> +      GLenum no_texobj_err = layered ? GL_INVALID_VALUE :
>                               GL_INVALID_OPERATION;
>        _mesa_error(ctx, no_texobj_err,
>                    "%s(non-generated texture %u)", caller, texture);
>        return false;
>     }
>  
> -   if (textarget == 0) {
> -      if (*layered) {
> -         /* We're being called by gl*FramebufferTexture() and textarget
> -          * is not used.
> -          */
> -         switch ((*texObj)->Target) {
> +   return true;
> +}
> +
> +/**
> + * Common code called by gl*FramebufferTexture() to verify the texture target
> + * and decide whether or not the attachment should truly be considered
> + * layered.
> + *
> + * \param layered true if attachment should be considered layered, false if
> + * not
> + *
> + * \return true if no errors, false if errors
> + */
> +static bool
> +check_layered_texture_target(struct gl_context *ctx, GLenum target,
> +                             const char *caller, bool *layered)

I don't think layered should be a bool here, because it's stored as a
GLboolean in gl_renderbuffer_attachment, and can be queried with
glGetFramebufferAttachmentParameteriv.

> +{
> +   *layered = true;
> +
> +         switch (target) {
>           case GL_TEXTURE_3D:
>           case GL_TEXTURE_1D_ARRAY_EXT:
>           case GL_TEXTURE_2D_ARRAY_EXT:
>           case GL_TEXTURE_CUBE_MAP:
>           case GL_TEXTURE_CUBE_MAP_ARRAY:
>           case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> -            err = false;
> -            break;
> +            return true;
>           case GL_TEXTURE_1D:
>           case GL_TEXTURE_2D:
>           case GL_TEXTURE_RECTANGLE:
> @@ -2486,41 +2484,139 @@ get_texture_for_framebuffer(struct gl_context *ctx,
>              /* These texture types are valid to pass to
>               * glFramebufferTexture(), but since they aren't layered, it
>               * is equivalent to calling glFramebufferTexture{1D,2D}().
> +             *
> +             * textarget can remain 0 since CUBE MAP is not valid here.

This comment is a bit confusing since the function no longer has a
textarget parameter.  I would also say that it's cube map faces
that are not valid, since GL_TEXTURE_CUBE_MAP is valid.

>               */
> -            err = false;
>              *layered = false;
> -            textarget = (*texObj)->Target;
> -            break;
> -         default:
> -            err = true;
> -            break;
> +            return true;
>           }
> -      } else {
> +
> +      _mesa_error(ctx, GL_INVALID_OPERATION,
> +                  "%s(invalid texture target %s)", caller,
> +                  _mesa_lookup_enum_by_nr(target));
> +      return false;
> +}
> +
> +/**
> + * Common code called by gl*FramebufferTextureLayer() to verify the texture
> + * target.
> + *
> + * \return true if no errors, false if errors
> + */
> +static bool
> +check_texture_target(struct gl_context *ctx, GLenum target,
> +                     const char *caller)
> +{
>           /* We're being called by glFramebufferTextureLayer() and
>            * textarget is not used.  The only legal texture types for
>            * that function are 3D and 1D/2D arrays textures.
>            */

This comment is not true when ARB_direct_state_access is supported;
all texture targets that are valid in FrameBufferTexture are now also
valid in FrameBufferTextureLayer.  See issues 30 and 36 in the
ARB_direct_state_access specification.

The code also needs to be updated to reflect that, but that should
probably be done in a separate patch.

> -         err = ((*texObj)->Target != GL_TEXTURE_3D) &&
> -            ((*texObj)->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
> -            ((*texObj)->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
> -            ((*texObj)->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
> -            ((*texObj)->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
> +         switch (target) {
> +         case GL_TEXTURE_3D:
> +         case GL_TEXTURE_1D_ARRAY_EXT:
> +         case GL_TEXTURE_2D_ARRAY_EXT:
> +         case GL_TEXTURE_CUBE_MAP_ARRAY:
> +         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> +            return true;
> +         }

I think this is an opportunity to remove the EXT suffixes here.

> +
> +      _mesa_error(ctx, GL_INVALID_OPERATION,
> +                  "%s(invalid texture target %s)", caller,
> +                  _mesa_lookup_enum_by_nr(target));
> +      return false;
> +}
> +
> +/**
> + * Common code called by glFramebufferTexture*D() to verify the texture
> + * target.
> + *
> + * \return true if no errors, false if errors
> + */
> +static bool
> +check_textarget(struct gl_context *ctx, int dims, GLenum target,
> +                GLenum textarget, const char *caller)
> +{
> +   bool err = false;
> +
> +   switch (dims) {
> +   case 1:
> +      switch (textarget) {
> +      case GL_TEXTURE_1D:
> +         break;
> +      case GL_TEXTURE_1D_ARRAY:
> +         err = !ctx->Extensions.EXT_texture_array;
> +         break;
> +      default:
> +         err = true;
>        }
> +      break;
> +   case 2:
> +      switch (textarget) {
> +      case GL_TEXTURE_2D:
> +         break;
> +      case GL_TEXTURE_RECTANGLE:
> +         err = _mesa_is_gles(ctx)
> +            || !ctx->Extensions.NV_texture_rectangle;
> +         break;
> +      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
> +      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
> +      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
> +      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
> +      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
> +      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
> +         err = !ctx->Extensions.ARB_texture_cube_map;
> +         break;
> +      case GL_TEXTURE_2D_ARRAY:
> +         err = (_mesa_is_gles(ctx) && ctx->Version < 30)
> +               || !ctx->Extensions.EXT_texture_array;
> +         break;
> +      case GL_TEXTURE_2D_MULTISAMPLE:
> +      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> +         err = _mesa_is_gles(ctx)
> +               || !ctx->Extensions.ARB_texture_multisample;
> +         break;
> +      default:
> +         err = true;
> +      }
> +      break;
> +   case 3:
> +      if (textarget != GL_TEXTURE_3D)
> +         err = true;
> +      break;
> +   default:
> +      err = true;
>     }
> -   else {
> -      /* Make sure textarget is consistent with the texture's type */
> -      err = ((*texObj)->Target == GL_TEXTURE_CUBE_MAP)
> -          ? !_mesa_is_cube_face(textarget)
> -          : ((*texObj)->Target != textarget);
> +
> +   if (err) {
> +      _mesa_error(ctx, GL_INVALID_OPERATION,
> +                  "%s(invalid texture target)", caller);

I think it would be nice if the error message mentioned the value
of the target.

> +      return false;
>     }
>  
> +   /* Make sure textarget is consistent with the texture's type */
> +   err = (target == GL_TEXTURE_CUBE_MAP) ?
> +          !_mesa_is_cube_face(textarget): (target != textarget);
> +
>     if (err) {
>        _mesa_error(ctx, GL_INVALID_OPERATION,
> -                  "%s(invalid or mismatched texture target)", caller);
> +                  "%s(mismatched texture target)", caller);
>        return false;
>     }
>  
> -   if ((*texObj)->Target == GL_TEXTURE_3D) {
> +   return true;
> +}
> +
> +/**
> + * Common code called by gl*FramebufferTextureLayer() and
> + * glFramebufferTexture3D() to verify the zoffset.
> + *
> + * \return true if no errors, false if errors
> + */
> +static bool
> +check_zoffset(struct gl_context *ctx, GLenum target, GLuint zoffset,
> +              const char *caller)
> +{
> +   if (target == GL_TEXTURE_3D) {
>        const GLuint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
>        if (zoffset >= maxSize) {
>           _mesa_error(ctx, GL_INVALID_VALUE,
> @@ -2528,10 +2624,10 @@ get_texture_for_framebuffer(struct gl_context *ctx,
>           return false;
>        }
>     }
> -   else if (((*texObj)->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
> -            ((*texObj)->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
> -            ((*texObj)->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
> -            ((*texObj)->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
> +   else if ((target == GL_TEXTURE_1D_ARRAY_EXT) ||
> +            (target == GL_TEXTURE_2D_ARRAY_EXT) ||
> +            (target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
> +            (target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {

The EXT suffixes could be removed here too.

>        if (zoffset >= ctx->Const.MaxArrayTextureLayers) {
>           _mesa_error(ctx, GL_INVALID_VALUE,
>                       "%s(invalid layer %u)", caller, zoffset);
> @@ -2539,9 +2635,21 @@ get_texture_for_framebuffer(struct gl_context *ctx,
>        }
>     }
>  
> -   maxLevelsTarget = textarget ? textarget : (*texObj)->Target;
> +   return true;
> +}
> +
> +/**
> + * Common code called by all gl*FramebufferTexture*() entry points to verify
> + * the level.
> + *
> + * \return true if no errors, false if errors
> + */
> +static bool
> +check_level(struct gl_context *ctx, GLenum target, GLint level,
> +            const char *caller)
> +{
>     if ((level < 0) ||
> -       (level >= _mesa_max_texture_levels(ctx, maxLevelsTarget))) {
> +       (level >= _mesa_max_texture_levels(ctx, target))) {
>        _mesa_error(ctx, GL_INVALID_VALUE,
>                    "%s(invalid level %d)", caller, level);
>        return false;
> @@ -2554,7 +2662,7 @@ void
>  _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
>                            GLenum attachment,
>                            struct gl_texture_object *texObj, GLenum textarget,
> -                          GLint level, GLuint zoffset, GLboolean layered,
> +                          GLint level, GLuint zoffset, bool layered,

layered should remain a GLboolean here too.

>                            const char *caller)
>  {
>     struct gl_renderbuffer_attachment *att;
> @@ -2639,127 +2747,58 @@ _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
>  }
>  
>  
> -void GLAPIENTRY
> -_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
> -                           GLenum textarget, GLuint texture, GLint level)
> +static void
> +framebuffer_texture_with_dims(int dims, GLenum target,
> +                              GLenum attachment, GLenum textarget,
> +                              GLuint texture, GLint level, GLint zoffset,
> +                              const char *caller)
>  {
>     GET_CURRENT_CONTEXT(ctx);
>     struct gl_framebuffer *fb;
>     struct gl_texture_object *texObj;
> -   GLboolean layered = GL_FALSE;
> -
> -   if (texture != 0) {
> -      GLboolean error;
> -
> -      switch (textarget) {
> -      case GL_TEXTURE_1D:
> -         error = GL_FALSE;
> -         break;
> -      case GL_TEXTURE_1D_ARRAY:
> -         error = !ctx->Extensions.EXT_texture_array;
> -         break;
> -      default:
> -         error = GL_TRUE;
> -      }
> -
> -      if (error) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "glFramebufferTexture1D(invalid texture target %s)",
> -                     _mesa_lookup_enum_by_nr(textarget));
> -         return;
> -      }
> -   }
>  
>     /* Get the framebuffer object */
>     fb = get_framebuffer_target(ctx, target);
>     if (!fb) {
> -      _mesa_error(ctx, GL_INVALID_ENUM,
> -                  "glFramebufferTexture1D(invalid target %s)",
> +      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
>                    _mesa_lookup_enum_by_nr(target));
>        return;
>     }
>  
>     /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, textarget, level, 0,
> -                                    &layered, "glFramebufferTexture1D",
> -                                    &texObj)) {
> -      /* Error already recorded */
> +   if (!get_texture_for_framebuffer(ctx, texture, false, caller, &texObj))
>        return;
> +
> +   if (texObj) {
> +      if (!check_textarget(ctx, dims, texObj->Target, textarget, caller))
> +         return;
> +
> +      if ((dims == 3) && !check_zoffset(ctx, texObj->Target, zoffset, caller))
> +         return;
> +
>     }

There should be an empty line here.

> +   if (!check_level(ctx, textarget, level, caller))
> +      return;
>  
>     _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
> -                             0, layered, "glFramebufferTexture1D");
> +                             zoffset, false, caller);
>  }
>  
> -
>  void GLAPIENTRY
> -_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
> +_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
>                             GLenum textarget, GLuint texture, GLint level)
>  {
> -   GET_CURRENT_CONTEXT(ctx);
> -   struct gl_framebuffer *fb;
> -   struct gl_texture_object *texObj;
> -   GLboolean layered = GL_FALSE;
> -
> -   if (texture != 0) {
> -      GLboolean error;
> -
> -      switch (textarget) {
> -      case GL_TEXTURE_2D:
> -         error = GL_FALSE;
> -         break;
> -      case GL_TEXTURE_RECTANGLE:
> -         error = _mesa_is_gles(ctx)
> -            || !ctx->Extensions.NV_texture_rectangle;
> -         break;
> -      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
> -      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
> -      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
> -      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
> -      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
> -      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
> -         error = !ctx->Extensions.ARB_texture_cube_map;
> -         break;
> -      case GL_TEXTURE_2D_ARRAY:
> -         error = (_mesa_is_gles(ctx) && ctx->Version < 30)
> -            || !ctx->Extensions.EXT_texture_array;
> -         break;
> -      case GL_TEXTURE_2D_MULTISAMPLE:
> -      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
> -         error = _mesa_is_gles(ctx)
> -            || !ctx->Extensions.ARB_texture_multisample;
> -         break;
> -      default:
> -         error = GL_TRUE;
> -      }
> -
> -      if (error) {
> -         _mesa_error(ctx, GL_INVALID_OPERATION,
> -                     "glFramebufferTexture2D(invalid texture target %s)",
> -                     _mesa_lookup_enum_by_nr(textarget));
> -         return;
> -      }
> -   }
> +   framebuffer_texture_with_dims(1, target, attachment, textarget, texture,
> +                                 level, 0, "glFramebufferTexture1D");
> +}
>  
> -   /* Get the framebuffer object */
> -   fb = get_framebuffer_target(ctx, target);
> -   if (!fb) {
> -      _mesa_error(ctx, GL_INVALID_ENUM,
> -                  "glFramebufferTexture2D(invalid target %s)",
> -                  _mesa_lookup_enum_by_nr(target));
> -      return;
> -   }
>  
> -   /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, textarget, level, 0,
> -                                    &layered, "glFramebufferTexture2D",
> -                                    &texObj)) {
> -      /* Error already recorded */
> -      return;
> -   }
> -
> -   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
> -                             0, layered, "glFramebufferTexture2D");
> +void GLAPIENTRY
> +_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
> +                           GLenum textarget, GLuint texture, GLint level)
> +{
> +   framebuffer_texture_with_dims(2, target, attachment, textarget, texture,
> +                                 level, 0, "glFramebufferTexture2D");
>  }
>  
>  
> @@ -2768,37 +2807,8 @@ _mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
>                             GLenum textarget, GLuint texture,
>                             GLint level, GLint zoffset)
>  {
> -   GET_CURRENT_CONTEXT(ctx);
> -   struct gl_framebuffer *fb;
> -   struct gl_texture_object *texObj;
> -   GLboolean layered = GL_FALSE;
> -
> -   if ((texture != 0) && (textarget != GL_TEXTURE_3D)) {
> -      _mesa_error(ctx, GL_INVALID_OPERATION,
> -                  "glFramebufferTexture3D(invalid texture target %s)",
> -                  _mesa_lookup_enum_by_nr(textarget));
> -      return;
> -   }
> -
> -   /* Get the framebuffer object */
> -   fb = get_framebuffer_target(ctx, target);
> -   if (!fb) {
> -      _mesa_error(ctx, GL_INVALID_ENUM,
> -                  "glFramebufferTexture3D(invalid target %s)",
> -                  _mesa_lookup_enum_by_nr(target));
> -      return;
> -   }
> -
> -   /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, textarget, level, zoffset,
> -                                    &layered, "glFramebufferTexture3D",
> -                                    &texObj)) {
> -      /* Error already recorded */
> -      return;
> -   }
> -
> -   _mesa_framebuffer_texture(ctx, fb, attachment, texObj, textarget, level,
> -                             zoffset, layered, "glFramebufferTexture3D");
> +   framebuffer_texture_with_dims(3, target, attachment, textarget, texture,
> +                                 level, zoffset, "glFramebufferTexture3D");
>  }
>  
>  
> @@ -2809,7 +2819,8 @@ _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
>     GET_CURRENT_CONTEXT(ctx);
>     struct gl_framebuffer *fb;
>     struct gl_texture_object *texObj;
> -   GLboolean layered = GL_FALSE;
> +
> +   const char *func = "glFramebufferTextureLayer";
>  
>     /* Get the framebuffer object */
>     fb = get_framebuffer_target(ctx, target);
> @@ -2821,15 +2832,22 @@ _mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
>     }
>  
>     /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, 0, level, layer,
> -                                    &layered, "glFramebufferTextureLayer",
> -                                    &texObj)) {
> -      /* Error already recorded */
> +   if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
>        return;
> +
> +   if (texObj) {
> +      if (!check_texture_target(ctx, texObj->Target, func))
> +         return;
> +
> +      if (!check_zoffset(ctx, texObj->Target, layer, func))
> +         return;
> +
> +      if (!check_level(ctx, texObj->Target, level, func))
> +         return;
>     }
>  
>     _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
> -                             layer, layered, "glFramebufferTextureLayer");
> +                             layer, false, func);
>  }
>  
>  void GLAPIENTRY
> @@ -2839,26 +2857,31 @@ _mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment,
>     GET_CURRENT_CONTEXT(ctx);
>     struct gl_framebuffer *fb;
>     struct gl_texture_object *texObj;
> -   GLboolean layered = GL_FALSE;
> +
> +   const char *func = "glNamedFramebufferTextureLayer";
>  
>     /* Get the framebuffer object */
> -   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
> -                                     "glNamedFramebufferTextureLayer");
> +   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
>     if (!fb)
>        return;
>  
>     /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, 0, level, layer,
> -                                    &layered,
> -                                    "glNamedFramebufferTextureLayer",
> -                                    &texObj)) {
> -      /* Error already recorded */
> +   if (!get_texture_for_framebuffer(ctx, texture, false, func, &texObj))
>        return;
> +
> +   if (texObj) {
> +      if (!check_texture_target(ctx, texObj->Target, func))
> +         return;
> +
> +      if (!check_zoffset(ctx, texObj->Target, layer, func))
> +         return;
> +
> +      if (!check_level(ctx, texObj->Target, level, func))
> +         return;
>     }
>  
>     _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
> -                             layer, layered,
> -                             "glNamedFramebufferTextureLayer");
> +                             layer, false, func);
>  }
>  
>  
> @@ -2869,7 +2892,9 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
>     GET_CURRENT_CONTEXT(ctx);
>     struct gl_framebuffer *fb;
>     struct gl_texture_object *texObj;
> -   GLboolean layered = GL_TRUE;
> +   bool layered;
> +
> +   const char *func = "FramebufferTexture";
>  
>     if (!_mesa_has_geometry_shaders(ctx)) {
>        _mesa_error(ctx, GL_INVALID_OPERATION,
> @@ -2887,15 +2912,19 @@ _mesa_FramebufferTexture(GLenum target, GLenum attachment,
>     }
>  
>     /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, 0, level, 0,
> -                                    &layered, "glFramebufferTexture",
> -                                    &texObj)) {
> -      /* Error already recorded */
> +   if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
>        return;
> +
> +   if (texObj) {
> +      if (!check_layered_texture_target(ctx, texObj->Target, func, &layered))
> +         return;
> +
> +      if (!check_level(ctx, texObj->Target, level, func))
> +         return;
>     }
>  
>     _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
> -                             0, layered, "glFramebufferTexture");
> +                             0, layered, func);
>  }
>  
>  void GLAPIENTRY
> @@ -2905,7 +2934,9 @@ _mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
>     GET_CURRENT_CONTEXT(ctx);
>     struct gl_framebuffer *fb;
>     struct gl_texture_object *texObj;
> -   GLboolean layered = GL_TRUE;
> +   bool layered;
> +
> +   const char *func = "glNamedFramebufferTexture";
>  
>     if (!_mesa_has_geometry_shaders(ctx)) {
>        _mesa_error(ctx, GL_INVALID_OPERATION,
> @@ -2914,21 +2945,25 @@ _mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment,
>     }
>  
>     /* Get the framebuffer object */
> -   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer,
> -                                     "glNamedFramebufferTexture");
> +   fb = _mesa_lookup_framebuffer_err(ctx, framebuffer, func);
>     if (!fb)
>        return;
>  
>     /* Get the texture object */
> -   if (!get_texture_for_framebuffer(ctx, texture, 0, level, 0,
> -                                    &layered, "glNamedFramebufferTexture",
> -                                    &texObj)) {
> -      /* Error already recorded */
> +   if (!get_texture_for_framebuffer(ctx, texture, true, func, &texObj))
>        return;
> +
> +   if (texObj) {
> +      if (!check_layered_texture_target(ctx, texObj->Target, func,
> +                                        &layered))
> +         return;
> +
> +      if (!check_level(ctx, texObj->Target, level, func))
> +         return;
>     }
>  
>     _mesa_framebuffer_texture(ctx, fb, attachment, texObj, 0, level,
> -                             0, layered, "glNamedFramebufferTexture");
> +                             0, layered, func);
>  }
>  
>  
> diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
> index 7487f02..96d39a7 100644
> --- a/src/mesa/main/fbobject.h
> +++ b/src/mesa/main/fbobject.h
> @@ -119,7 +119,7 @@ extern void
>  _mesa_framebuffer_texture(struct gl_context *ctx, struct gl_framebuffer *fb,
>                            GLenum attachment,
>                            struct gl_texture_object *texObj, GLenum textarget,
> -                          GLint level, GLuint zoffset, GLboolean layered,
> +                          GLint level, GLuint zoffset, bool layered,
>                            const char *caller);
>  
>  
> 



More information about the mesa-dev mailing list