[Mesa-dev] [RFC PATCH] st/mesa: skip texture validation logic when nothing has changed

Marek Olšák maraeo at gmail.com
Sun Jun 11 14:40:00 UTC 2017


If it's copied from i965, it must be correct, right? ;) It probably is.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Sat, Jun 10, 2017 at 6:52 AM, Timothy Arceri <tarceri at itsqueeze.com> wrote:
> Based on the same logic in the i965 driver 2f225f61451abd51 and
> 16060c5adcd4.
>
> perf reports st_finalize_texture() going from 0.60% -> 0.16% with
> this change when running the Xonotic benchmark from PTS.
> ---
>
>  A full run of piglit on radeonsi produced no regressions. No other drivers
>  have been tested.
>
>  src/mesa/state_tracker/st_cb_texture.c | 28 ++++++++++++++++++++++++++++
>  src/mesa/state_tracker/st_manager.c    |  2 ++
>  src/mesa/state_tracker/st_texture.h    |  9 +++++++++
>  3 files changed, 39 insertions(+)
>
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index 99c59f7..443bb7b 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -147,20 +147,22 @@ st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
>
>  /** called via ctx->Driver.NewTextureObject() */
>  static struct gl_texture_object *
>  st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
>  {
>     struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
>
>     DBG("%s\n", __func__);
>     _mesa_initialize_texture_object(ctx, &obj->base, name, target);
>
> +   obj->needs_validation = true;
> +
>     return &obj->base;
>  }
>
>  /** called via ctx->Driver.DeleteTextureObject() */
>  static void
>  st_DeleteTextureObject(struct gl_context *ctx,
>                         struct gl_texture_object *texObj)
>  {
>     struct st_context *st = st_context(ctx);
>     struct st_texture_object *stObj = st_texture_object(texObj);
> @@ -599,20 +601,22 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
>     struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
>     const GLuint level = texImage->Level;
>     GLuint width = texImage->Width;
>     GLuint height = texImage->Height;
>     GLuint depth = texImage->Depth;
>
>     DBG("%s\n", __func__);
>
>     assert(!stImage->pt); /* xxx this might be wrong */
>
> +   stObj->needs_validation = true;
> +
>     etc_fallback_allocate(st, stImage);
>
>     /* Look if the parent texture object has space for this image */
>     if (stObj->pt &&
>         level <= stObj->pt->last_level &&
>         st_texture_match_image(st, stObj->pt, texImage)) {
>        /* this image will fit in the existing texture object's memory */
>        pipe_resource_reference(&stImage->pt, stObj->pt);
>        return GL_TRUE;
>     }
> @@ -2478,20 +2482,30 @@ st_finalize_texture(struct gl_context *ctx,
>           pipe_resource_reference(&stObj->pt, st_obj->buffer);
>           st_texture_release_all_sampler_views(st, stObj);
>        }
>        return GL_TRUE;
>
>     }
>
>     firstImage = st_texture_image_const(stObj->base.Image[cubeMapFace][stObj->base.BaseLevel]);
>     assert(firstImage);
>
> +   /* Skip the loop over images in the common case of no images having
> +    * changed.  But if the GL_BASE_LEVEL or GL_MAX_LEVEL change to something we
> +    * haven't looked at, then we do need to look at those new images.
> +    */
> +   if (!stObj->needs_validation &&
> +       stObj->base.BaseLevel >= stObj->validated_first_level &&
> +       stObj->lastLevel <= stObj->validated_last_level) {
> +      return GL_TRUE;
> +   }
> +
>     /* If both firstImage and stObj point to a texture which can contain
>      * all active images, favour firstImage.  Note that because of the
>      * completeness requirement, we know that the image dimensions
>      * will match.
>      */
>     if (firstImage->pt &&
>         firstImage->pt != stObj->pt &&
>         (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
>        pipe_resource_reference(&stObj->pt, firstImage->pt);
>        st_texture_release_all_sampler_views(st, stObj);
> @@ -2624,20 +2638,24 @@ st_finalize_texture(struct gl_context *ctx,
>                  (stImage->base.Width == u_minify(ptWidth, level) &&
>                   stImage->base.Height == height &&
>                   stImage->base.Depth == depth)) {
>                 /* src image fits expected dest mipmap level size */
>                 copy_image_data_to_texture(st, stObj, level, stImage);
>              }
>           }
>        }
>     }
>
> +   stObj->validated_first_level = stObj->base.BaseLevel;
> +   stObj->validated_last_level = stObj->lastLevel;
> +   stObj->needs_validation = false;
> +
>     return GL_TRUE;
>  }
>
>
>  /**
>   * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
>   * for a whole mipmap stack.
>   */
>  static GLboolean
>  st_AllocTextureStorage(struct gl_context *ctx,
> @@ -2705,20 +2723,25 @@ st_AllocTextureStorage(struct gl_context *ctx,
>        GLuint face;
>        for (face = 0; face < numFaces; face++) {
>           struct st_texture_image *stImage =
>              st_texture_image(texObj->Image[face][level]);
>           pipe_resource_reference(&stImage->pt, stObj->pt);
>
>           etc_fallback_allocate(st, stImage);
>        }
>     }
>
> +   /* The texture is in a validated state, so no need to check later. */
> +   stObj->needs_validation = false;
> +   stObj->validated_first_level = 0;
> +   stObj->validated_last_level = levels - 1;
> +
>     return GL_TRUE;
>  }
>
>
>  static GLboolean
>  st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
>                       GLuint numLevels, GLint level,
>                       mesa_format format, GLuint numSamples,
>                       GLint width, GLint height, GLint depth)
>  {
> @@ -2803,20 +2826,25 @@ st_TextureView(struct gl_context *ctx,
>     tex->surface_format =
>        st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
>
>     tex->lastLevel = numLevels - 1;
>
>     /* free texture sampler views.  They need to be recreated when we
>      * change the texture view parameters.
>      */
>     st_texture_release_all_sampler_views(st, tex);
>
> +   /* The texture is in a validated state, so no need to check later. */
> +   tex->needs_validation = false;
> +   tex->validated_first_level = 0;
> +   tex->validated_last_level = numLevels - 1;
> +
>     return GL_TRUE;
>  }
>
>  static void
>  st_ClearTexSubImage(struct gl_context *ctx,
>                      struct gl_texture_image *texImage,
>                      GLint xoffset, GLint yoffset, GLint zoffset,
>                      GLsizei width, GLsizei height, GLsizei depth,
>                      const void *clearValue)
>  {
> diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c
> index f4c78ae..085f54e 100644
> --- a/src/mesa/state_tracker/st_manager.c
> +++ b/src/mesa/state_tracker/st_manager.c
> @@ -585,20 +585,22 @@ st_context_teximage(struct st_context_iface *stctxi,
>        }
>     }
>     else {
>        _mesa_clear_texture_image(ctx, texImage);
>        width = height = depth = 0;
>     }
>
>     pipe_resource_reference(&stImage->pt, tex);
>     stObj->surface_format = pipe_format;
>
> +   stObj->needs_validation = true;
> +
>     _mesa_dirty_texobj(ctx, texObj);
>     _mesa_unlock_texture(ctx, texObj);
>
>     return TRUE;
>  }
>
>  static void
>  st_context_copy(struct st_context_iface *stctxi,
>                  struct st_context_iface *stsrci, unsigned mask)
>  {
> diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
> index 1b4d1a3..070b593 100644
> --- a/src/mesa/state_tracker/st_texture.h
> +++ b/src/mesa/state_tracker/st_texture.h
> @@ -77,20 +77,23 @@ struct st_texture_image
>   * Subclass of gl_texure_object.
>   */
>  struct st_texture_object
>  {
>     struct gl_texture_object base;       /* The "parent" object */
>
>     /* The texture must include at levels [0..lastLevel] once validated:
>      */
>     GLuint lastLevel;
>
> +   unsigned int validated_first_level;
> +   unsigned int validated_last_level;
> +
>     /* On validation any active images held in main memory or in other
>      * textures will be copied to this texture and the old storage freed.
>      */
>     struct pipe_resource *pt;
>
>     /* Number of views in sampler_views array */
>     GLuint num_sampler_views;
>
>     /* Array of sampler views (one per context) attached to this texture
>      * object. Created lazily on first binding in context.
> @@ -114,20 +117,26 @@ struct st_texture_object
>      * This is used for VDPAU interop, where imported pipe_resources may be
>      * array textures (containing layers with different fields) even though the
>      * GL state describes one non-array texture per field.
>      */
>     uint layer_override;
>
>     /** The glsl version of the shader seen during the previous validation */
>     unsigned prev_glsl_version;
>     /** The value of the sampler's sRGBDecode state at the previous validation */
>     GLenum prev_sRGBDecode;
> +
> +    /**
> +     * Set when the texture images of this texture object might not all be the
> +     * pipe_resource *pt above.
> +     */
> +    bool needs_validation;
>  };
>
>
>  static inline struct st_texture_image *
>  st_texture_image(struct gl_texture_image *img)
>  {
>     return (struct st_texture_image *) img;
>  }
>
>  static inline const struct st_texture_image *
> --
> 2.9.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list