[Mesa-dev] [PATCH 2/2] st/mesa: overhaul texture / sample swizzle code

Marek Olšák maraeo at gmail.com
Wed Mar 26 14:52:17 PDT 2014


Is this just a workaround for the fbo-blending-formats test? It should
test if GL_DST_ALPHA is equivalent to GL_ONE if the format is RGBX. I
don't think the test has anything to do with texturing.

Marek

On Wed, Mar 26, 2014 at 8:58 PM, Brian Paul <brianp at vmware.com> wrote:
> Previously we only examined the GL_DEPTH_MODE state to determine the
> sampler view swizzle for depth textures.  Now we also consider the
> texture base format for color textures too.
>
> The basic idea is if we're sampling from a RGB texture we always
> want to get A=1, even if the actual hardware format might be RGBA.
> We had assumed that the texture's A values were always one since that's
> what Mesa's texstore code does.  But if we render to the RGBA texture,
> the A values might not be 1.  Subsequent sampling didn't return the
> right values.
>
> Now we examine the user-specified texture base format vs. the actual
> gallium format to determine the right swizzle.
>
> Fixes several fbo-blending-formats, fbo-clear-formats and fbo-tex-rgbx
> failures with VMware/svga driver (and possibly other drivers).
> No other piglit regressions with softpipe or VMware/svga.
> ---
>  src/mesa/state_tracker/st_atom_texture.c |  167 ++++++++++++++++++++----------
>  1 file changed, 114 insertions(+), 53 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
> index c445213..c9bffce 100644
> --- a/src/mesa/state_tracker/st_atom_texture.c
> +++ b/src/mesa/state_tracker/st_atom_texture.c
> @@ -83,67 +83,132 @@ swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
>
>
>  /**
> - * Combine depth texture mode with "swizzle" so that depth mode swizzling
> - * takes place before texture swizzling, and return the resulting swizzle.
> - * If the format is not a depth format, return "swizzle" unchanged.
> + * Given a user-specified texture base format, the actual gallium texture
> + * format and the current GL_DEPTH_MODE, return a texture swizzle.
>   *
> - * \param format     PIPE_FORMAT_*.
> - * \param swizzle    Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
> - * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA, GL_RED.
> + * Consider the case where the user requests a GL_RGB internal texture
> + * format the driver actually uses an RGBA format.  The A component should
> + * be ignored and sampling from the texture should always return (r,g,b,1).
> + * But if we rendered to the texture we might have written A values != 1.
> + * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
> + * This function computes the texture swizzle needed to get the expected
> + * values.
> + *
> + * In the case of depth textures, the GL_DEPTH_MODE state determines the
> + * texture swizzle.
> + *
> + * This result must be composed with the user-specified swizzle to get
> + * the final swizzle.
>   */
> -static GLuint
> -apply_depthmode(enum pipe_format format, GLuint swizzle, GLenum depthmode)
> +static unsigned
> +compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
> +                               enum pipe_format actualFormat)
>  {
> -   const struct util_format_description *desc =
> -         util_format_description(format);
> -   unsigned swz;
> -
> -   if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
> -       desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
> -      /* Not a depth format. */
> -      return swizzle;
> -   }
> -
> -   switch (depthmode) {
> +   switch (baseFormat) {
> +   case GL_RGBA:
> +      return SWIZZLE_XYZW;
> +   case GL_RGB:
> +      if (util_format_has_alpha(actualFormat))
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
> +      else
> +         return SWIZZLE_XYZW;
> +   case GL_RG:
> +      if (util_format_get_nr_components(actualFormat) > 2)
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
> +      else
> +         return SWIZZLE_XYZW;
> +   case GL_RED:
> +      if (util_format_get_nr_components(actualFormat) > 1)
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
> +                              SWIZZLE_ZERO, SWIZZLE_ONE);
> +      else
> +         return SWIZZLE_XYZW;
> +   case GL_ALPHA:
> +      if (util_format_get_nr_components(actualFormat) > 1)
> +         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
> +                              SWIZZLE_ZERO, SWIZZLE_W);
> +      else
> +         return SWIZZLE_XYZW;
>     case GL_LUMINANCE:
> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
> -      break;
> +      if (util_format_get_nr_components(actualFormat) > 1)
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
> +      else
> +         return SWIZZLE_XYZW;
> +   case GL_LUMINANCE_ALPHA:
> +      if (util_format_get_nr_components(actualFormat) > 2)
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
> +      else
> +         return SWIZZLE_XYZW;
>     case GL_INTENSITY:
> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
> -      break;
> -   case GL_ALPHA:
> -      swz = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_X);
> -      break;
> -   case GL_RED:
> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
> -      break;
> +      if (util_format_get_nr_components(actualFormat) > 1)
> +         return SWIZZLE_XXXX;
> +      else
> +         return SWIZZLE_XYZW;
> +   case GL_STENCIL_INDEX:
> +      return SWIZZLE_XYZW;
> +   case GL_DEPTH_STENCIL:
> +      /* fall-through */
> +   case GL_DEPTH_COMPONENT:
> +      /* Now examine the depth mode */
> +      switch (depthMode) {
> +      case GL_LUMINANCE:
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
> +      case GL_INTENSITY:
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
> +      case GL_ALPHA:
> +         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
> +                              SWIZZLE_ZERO, SWIZZLE_X);
> +      case GL_RED:
> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
> +                              SWIZZLE_ZERO, SWIZZLE_ONE);
> +      default:
> +         assert(!"Unexpected depthMode");
> +         return SWIZZLE_XYZW;
> +      }
> +   default:
> +      assert(!"Unexpected baseFormat");
> +      return SWIZZLE_XYZW;
>     }
> -
> -   return swizzle_swizzle(swizzle, swz);
>  }
>
>
> +static unsigned
> +get_texture_format_swizzle(const struct st_texture_object *stObj)
> +{
> +   const struct gl_texture_image *texImage =
> +      stObj->base.Image[0][stObj->base.BaseLevel];
> +   unsigned tex_swizzle;
> +
> +   if (texImage) {
> +      tex_swizzle = compute_texture_format_swizzle(texImage->_BaseFormat,
> +                                                   stObj->base.DepthMode,
> +                                                   stObj->pt->format);
> +   }
> +   else {
> +      tex_swizzle = SWIZZLE_XYZW;
> +   }
> +
> +   /* Combine the texture format swizzle with user's swizzle */
> +   return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
> +}
> +
> +
>  /**
> - * Return TRUE if the swizzling described by "swizzle" and
> - * "depthmode" (for depth textures only) is different from the swizzling
> - * set in the given sampler view.
> + * Return TRUE if the texture's sampler view swizzle is equal to
> + * the texture's swizzle.
>   *
> - * \param sv         A sampler view.
> - * \param swizzle    Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
> - * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
> + * \param stObj  the st texture object,
>   */
>  static boolean
> -check_sampler_swizzle(struct pipe_sampler_view *sv,
> -                      GLuint swizzle, GLenum depthmode)
> +check_sampler_swizzle(const struct st_texture_object *stObj)
>  {
> -   swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
> -
> -   if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
> -       (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
> -       (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
> -       (sv->swizzle_a != GET_SWZ(swizzle, 3)))
> -      return TRUE;
> -   return FALSE;
> +   const struct pipe_sampler_view *sv = stObj->sampler_view;
> +   unsigned swizzle = get_texture_format_swizzle(stObj);
> +
> +   return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
> +           (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
> +           (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
> +           (sv->swizzle_a != GET_SWZ(swizzle, 3)));
>  }
>
>
> @@ -154,9 +219,7 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
>                                           enum pipe_format format)
>  {
>     struct pipe_sampler_view templ;
> -   GLuint swizzle = apply_depthmode(stObj->pt->format,
> -                                    stObj->base._Swizzle,
> -                                    stObj->base.DepthMode);
> +   unsigned swizzle = get_texture_format_swizzle(stObj);
>
>     u_sampler_view_default_template(&templ,
>                                     stObj->pt,
> @@ -269,9 +332,7 @@ update_single_texture(struct st_context *st,
>
>     /* if sampler view has changed dereference it */
>     if (stObj->sampler_view) {
> -      if (check_sampler_swizzle(stObj->sampler_view,
> -                               stObj->base._Swizzle,
> -                               stObj->base.DepthMode) ||
> +      if (check_sampler_swizzle(stObj) ||
>           (view_format != stObj->sampler_view->format) ||
>           stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
>          pipe_sampler_view_release(pipe, &stObj->sampler_view);
> --
> 1.7.10.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list