[Mesa-dev] [PATCH 2/2] st/mesa: Prevent huge lastlevel values from being computed.

Brian Paul brianp at vmware.com
Tue Sep 4 15:08:51 PDT 2012


On 09/04/2012 01:15 PM, Stéphane Marchesin wrote:
> The current computation for the lastlevel is based on the level size and can
> lead to writing past the end of the texture array. Instead we clamp according
> to hardware limits.
> ---
>   src/mesa/state_tracker/st_cb_texture.c |   28 +++++++++++++++++++++++++++-
>   1 files changed, 27 insertions(+), 1 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index ed3bbc7..51c76e3 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -67,6 +67,24 @@
>
>   #define DBG if (0) printf
>
> +static enum pipe_cap
> +pipe_to_param(enum pipe_texture_target target)
> +{
> +   switch(target) {
> +   case PIPE_TEXTURE_1D:
> +   case PIPE_TEXTURE_2D:
> +   case PIPE_TEXTURE_RECT:
> +      return PIPE_CAP_MAX_TEXTURE_2D_LEVELS;
> +   case PIPE_TEXTURE_3D:
> +   case PIPE_TEXTURE_2D_ARRAY:
> +      return PIPE_CAP_MAX_TEXTURE_3D_LEVELS;
> +   case PIPE_TEXTURE_CUBE:
> +      return PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS;
> +   default:
> +      assert(0);
> +      return 0;
> +   }
> +}
>
>   static enum pipe_texture_target
>   gl_target_to_pipe(GLenum target)
> @@ -333,6 +351,9 @@ guess_and_alloc_texture(struct st_context *st,
>      GLuint bindings;
>      GLuint ptWidth, ptHeight, ptDepth, ptLayers;
>      enum pipe_format fmt;
> +   enum pipe_texture_target pipe_target = gl_target_to_pipe(stObj->base.Target);
> +   struct pipe_context *pipe = st->pipe;
> +   struct pipe_screen *screen = pipe->screen;
>
>      DBG("%s\n", __FUNCTION__);
>
> @@ -374,7 +395,12 @@ guess_and_alloc_texture(struct st_context *st,
>         GLuint l2width = util_logbase2(width);
>         GLuint l2height = util_logbase2(height);
>         GLuint l2depth = util_logbase2(depth);
> +      int target_param = pipe_to_param(pipe_target);
> +      int max_level = screen->get_param(screen, target_param);

I think you could use the _mesa_max_texture_levels() function here.


>         lastLevel = MAX2(MAX2(l2width, l2height), l2depth);
> +
> +      /* Clamp the last level against what the hw can do */
> +      lastLevel = MIN2(lastLevel, max_level - 1);
>      }
>
>      /* Save the level=0 dimensions */
> @@ -391,7 +417,7 @@ guess_and_alloc_texture(struct st_context *st,
>                                      &ptWidth,&ptHeight,&ptDepth,&ptLayers);
>
>      stObj->pt = st_texture_create(st,
> -                                 gl_target_to_pipe(stObj->base.Target),
> +                                 pipe_target,
>                                    fmt,
>                                    lastLevel,
>                                    ptWidth,

Do you have a test case for this?  I'd like to understand the problem 
a bit beter.

-Brian


More information about the mesa-dev mailing list