[Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color v2

Jose Fonseca jfonseca at vmware.com
Tue Apr 16 13:38:26 PDT 2013


Thanks for the update.

Looks good to me FWIW.

Jose

----- Original Message -----
> From: Christoph Bumiller <christoph.bumiller at speed.at>
> 
> This is the only sane solution for nv50 and nvc0 (really, trust me),
> but since on other hardware the border colour is tightly coupled with
> texture state they'd have to undo the swizzle, so I've added a cap.
> 
> The dependency of update_sampler on the texture updates was
> introduced to avoid doing the apply_depthmode to the swizzle twice.
> 
> v2: Moved swizzling helper to u_format.c, extended the CAP to
> provide more accurate information.
> ---
>  src/gallium/auxiliary/util/u_format.c            |   34
>  ++++++++++++++++++++++
>  src/gallium/auxiliary/util/u_format.h            |   12 ++++++++
>  src/gallium/docs/source/cso/sampler.rst          |    6 ++-
>  src/gallium/docs/source/screen.rst               |   11 +++++++
>  src/gallium/drivers/freedreno/freedreno_screen.c |    1 +
>  src/gallium/drivers/i915/i915_screen.c           |    1 +
>  src/gallium/drivers/llvmpipe/lp_screen.c         |    2 +
>  src/gallium/drivers/nv30/nv30_screen.c           |    1 +
>  src/gallium/drivers/nv50/nv50_screen.c           |    2 +
>  src/gallium/drivers/nvc0/nvc0_screen.c           |    2 +
>  src/gallium/drivers/r300/r300_screen.c           |    1 +
>  src/gallium/drivers/r600/r600_pipe.c             |    3 ++
>  src/gallium/drivers/radeonsi/radeonsi_pipe.c     |    1 +
>  src/gallium/drivers/softpipe/sp_screen.c         |    2 +
>  src/gallium/drivers/svga/svga_screen.c           |    2 +
>  src/gallium/include/pipe/p_defines.h             |    7 ++++-
>  src/mesa/state_tracker/st_atom.c                 |    2 +-
>  src/mesa/state_tracker/st_atom_sampler.c         |   27 +++++++++++++++--
>  src/mesa/state_tracker/st_context.c              |    3 ++
>  src/mesa/state_tracker/st_context.h              |    1 +
>  20 files changed, 114 insertions(+), 7 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_format.c
> b/src/gallium/auxiliary/util/u_format.c
> index 1845637..9bdc2ea 100644
> --- a/src/gallium/auxiliary/util/u_format.c
> +++ b/src/gallium/auxiliary/util/u_format.c
> @@ -632,6 +632,40 @@ void util_format_compose_swizzles(const unsigned char
> swz1[4],
>     }
>  }
>  
> +void util_format_apply_color_swizzle(union pipe_color_union *dst,
> +                                     const union pipe_color_union *src,
> +                                     const unsigned char swz[4],
> +                                     const boolean is_integer)
> +{
> +   unsigned c;
> +
> +   if (is_integer) {
> +      for (c = 0; c < 4; ++c) {
> +         switch (swz[c]) {
> +         case PIPE_SWIZZLE_RED:   dst->ui[c] = src->ui[0]; break;
> +         case PIPE_SWIZZLE_GREEN: dst->ui[c] = src->ui[1]; break;
> +         case PIPE_SWIZZLE_BLUE:  dst->ui[c] = src->ui[2]; break;
> +         case PIPE_SWIZZLE_ALPHA: dst->ui[c] = src->ui[3]; break;
> +         default:
> +            dst->ui[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1 : 0;
> +            break;
> +         }
> +      }
> +   } else {
> +      for (c = 0; c < 4; ++c) {
> +         switch (swz[c]) {
> +         case PIPE_SWIZZLE_RED:   dst->f[c] = src->f[0]; break;
> +         case PIPE_SWIZZLE_GREEN: dst->f[c] = src->f[1]; break;
> +         case PIPE_SWIZZLE_BLUE:  dst->f[c] = src->f[2]; break;
> +         case PIPE_SWIZZLE_ALPHA: dst->f[c] = src->f[3]; break;
> +         default:
> +            dst->f[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
> +            break;
> +         }
> +      }
> +   }
> +}
> +
>  void util_format_swizzle_4f(float *dst, const float *src,
>                              const unsigned char swz[4])
>  {
> diff --git a/src/gallium/auxiliary/util/u_format.h
> b/src/gallium/auxiliary/util/u_format.h
> index ed942fb..e4b9c36 100644
> --- a/src/gallium/auxiliary/util/u_format.h
> +++ b/src/gallium/auxiliary/util/u_format.h
> @@ -33,6 +33,9 @@
>  #include "pipe/p_format.h"
>  #include "util/u_debug.h"
>  
> +union pipe_color_union;
> +
> +
>  #ifdef __cplusplus
>  extern "C" {
>  #endif
> @@ -1117,6 +1120,15 @@ void util_format_compose_swizzles(const unsigned char
> swz1[4],
>                                    const unsigned char swz2[4],
>                                    unsigned char dst[4]);
>  
> +/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
> + * to \param src and store the result in \param dst.
> + * \param is_integer determines the value written for PIPE_SWIZZLE_ONE.
> + */
> +void util_format_apply_color_swizzle(union pipe_color_union *dst,
> +                                     const union pipe_color_union *src,
> +                                     const unsigned char swz[4],
> +                                     const boolean is_integer);
> +
>  void util_format_swizzle_4f(float *dst, const float *src,
>                              const unsigned char swz[4]);
>  
> diff --git a/src/gallium/docs/source/cso/sampler.rst
> b/src/gallium/docs/source/cso/sampler.rst
> index 26ffc18..9959793 100644
> --- a/src/gallium/docs/source/cso/sampler.rst
> +++ b/src/gallium/docs/source/cso/sampler.rst
> @@ -101,7 +101,9 @@ max_lod
>  border_color
>      Color union used for texel coordinates that are outside the [0,width-1],
>      [0, height-1] or [0, depth-1] ranges. Interpreted according to sampler
> -    view format.
> +    view format, unless the driver reports
> +    PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK, in which case special care has to
> be
> +    taken (see description of the cap).
>  max_anisotropy
>      Maximum anistropy ratio to use when sampling from textures.  For
>      example,
>      if max_anistropy=4, a region of up to 1 by 4 texels will be sampled.
> @@ -111,4 +113,4 @@ max_anisotropy
>  seamless_cube_map
>      If set, the bilinear filter of a cube map may take samples from adjacent
>      cube map faces when sampled near a texture border to produce a seamless
> -    look.
> \ No newline at end of file
> +    look.
> diff --git a/src/gallium/docs/source/screen.rst
> b/src/gallium/docs/source/screen.rst
> index 4b01d77..3ab7e9e 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -151,6 +151,17 @@ The integer capabilities:
>    dedicated memory should return 1 and all software rasterizers should
>    return 0.
>  * ``PIPE_CAP_QUERY_PIPELINE_STATISTICS``: Whether
>  PIPE_QUERY_PIPELINE_STATISTICS
>    is supported.
> +* ``PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK``: Bitmask indicating whether
> special
> +  considerations have to be given to the interaction between the border
> color
> +  in the sampler object and the sampler view used with it.
> +  If PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 is set, the border color
> +  may be affected in undefined ways for any kind of permutational swizzle
> +  (any swizzle XYZW where X/Y/Z/W are not ZERO, ONE, or R/G/B/A
> respectively)
> +  in the sampler view.
> +  If PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 is set, the border color
> +  state should be swizzled manually according to the swizzle in the sampler
> +  view it is intended to be used with, or herein undefined results may occur
> +  for permutational swizzles.
>  
>  
>  .. _pipe_capf:
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 283d07f..4a9a54e 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -200,6 +200,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>  	case PIPE_CAP_USER_VERTEX_BUFFERS:
>  	case PIPE_CAP_USER_INDEX_BUFFERS:
>  	case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> +	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>  		return 0;
>  
>  	/* Stream output. */
> diff --git a/src/gallium/drivers/i915/i915_screen.c
> b/src/gallium/drivers/i915/i915_screen.c
> index 54b2154..dfb76b3 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -213,6 +213,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap
> cap)
>     case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
>     case PIPE_CAP_TEXTURE_MULTISAMPLE:
>     case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>        return 0;
>  
>     case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c
> b/src/gallium/drivers/llvmpipe/lp_screen.c
> index ebcf680..1eed5f6 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -138,6 +138,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>        return 1;
>     case PIPE_CAP_TEXTURE_SWIZZLE:
>        return 1;
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +      return 0;
>     case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
>        return LP_MAX_TEXTURE_2D_LEVELS;
>     case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
> diff --git a/src/gallium/drivers/nv30/nv30_screen.c
> b/src/gallium/drivers/nv30/nv30_screen.c
> index e33710e..5b3b470 100644
> --- a/src/gallium/drivers/nv30/nv30_screen.c
> +++ b/src/gallium/drivers/nv30/nv30_screen.c
> @@ -123,6 +123,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>     case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
>     case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
>     case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>        return 0;
>     case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
>     case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
> diff --git a/src/gallium/drivers/nv50/nv50_screen.c
> b/src/gallium/drivers/nv50/nv50_screen.c
> index 55081be..5aa8ef3 100644
> --- a/src/gallium/drivers/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nv50/nv50_screen.c
> @@ -186,6 +186,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>        return 1;
>     case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
>        return 0;
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +      return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
>     default:
>        NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
>        return 0;
> diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c
> b/src/gallium/drivers/nvc0/nvc0_screen.c
> index ccdf2cd..8dfd4d1 100644
> --- a/src/gallium/drivers/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nvc0/nvc0_screen.c
> @@ -176,6 +176,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
>        return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
>     case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
>        return 1;
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +      return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
>     default:
>        NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
>        return 0;
> diff --git a/src/gallium/drivers/r300/r300_screen.c
> b/src/gallium/drivers/r300/r300_screen.c
> index 3175b3b..a932be9 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -162,6 +162,7 @@ static int r300_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>          case PIPE_CAP_CUBE_MAP_ARRAY:
>          case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
>          case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
> +        case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>              return 0;
>  
>          /* SWTCL-only features. */
> diff --git a/src/gallium/drivers/r600/r600_pipe.c
> b/src/gallium/drivers/r600/r600_pipe.c
> index 3f36e63..0f0864b 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -653,6 +653,9 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>  
>  	case PIPE_CAP_MAX_TEXEL_OFFSET:
>  		return 7;
> +
> +	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +		return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600;
>  	}
>  	return 0;
>  }
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> index 5c25b2f..4e97f51 100644
> --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> @@ -380,6 +380,7 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>  	case PIPE_CAP_CUBE_MAP_ARRAY:
>  	case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
>  	case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
> +	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
>  		return 0;
>  
>  	/* Stream output. */
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c
> b/src/gallium/drivers/softpipe/sp_screen.c
> index 6915f91..88f9ecd 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -94,6 +94,8 @@ softpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
>        return 1;
>     case PIPE_CAP_TEXTURE_SWIZZLE:
>        return 1;
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +      return 0;
>     case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
>        return SP_MAX_TEXTURE_2D_LEVELS;
>     case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
> diff --git a/src/gallium/drivers/svga/svga_screen.c
> b/src/gallium/drivers/svga/svga_screen.c
> index 6213535..60e0442 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -166,6 +166,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap
> param)
>        return 1;
>     case PIPE_CAP_TEXTURE_SWIZZLE:
>        return 1;
> +   case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> +      return 0;
>     case PIPE_CAP_USER_VERTEX_BUFFERS:
>     case PIPE_CAP_USER_INDEX_BUFFERS:
>        return 0;
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index 9939325..95fc788 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -505,9 +505,14 @@ enum pipe_cap {
>     PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78,
>     PIPE_CAP_TGSI_TEXCOORD = 79,
>     PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER = 80,
> -   PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81
> +   PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81,
> +   PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82
>  };
>  
> +#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
> +#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 (1 << 1)
> +
> +
>  /**
>   * Implementation limits which are queried through
>   * pipe_screen::get_paramf()
> diff --git a/src/mesa/state_tracker/st_atom.c
> b/src/mesa/state_tracker/st_atom.c
> index 32bcc26..7d38392 100644
> --- a/src/mesa/state_tracker/st_atom.c
> +++ b/src/mesa/state_tracker/st_atom.c
> @@ -55,10 +55,10 @@ static const struct st_tracked_state *atoms[] =
>     &st_update_viewport,
>     &st_update_scissor,
>     &st_update_blend,
> -   &st_update_sampler,
>     &st_update_vertex_texture,
>     &st_update_fragment_texture,
>     &st_update_geometry_texture,
> +   &st_update_sampler, /* depends on update_*_texture for swizzle */
>     &st_update_framebuffer,
>     &st_update_msaa,
>     &st_update_vs_constants,
> diff --git a/src/mesa/state_tracker/st_atom_sampler.c
> b/src/mesa/state_tracker/st_atom_sampler.c
> index 3eba5b1..db51eea 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -48,6 +48,8 @@
>  
>  #include "cso_cache/cso_context.h"
>  
> +#include "util/u_format.h"
> +
>  
>  /**
>   * Convert GLenum texcoord wrap tokens to pipe tokens.
> @@ -172,8 +174,10 @@ convert_sampler(struct st_context *st,
>         msamp->BorderColor.ui[1] ||
>         msamp->BorderColor.ui[2] ||
>         msamp->BorderColor.ui[3]) {
> +      struct st_texture_object *stobj = st_texture_object(texobj);
>        struct gl_texture_image *teximg;
>        GLboolean is_integer = GL_FALSE;
> +      union pipe_color_union border_color;
>  
>        teximg = texobj->Image[0][texobj->BaseLevel];
>  
> @@ -181,9 +185,26 @@ convert_sampler(struct st_context *st,
>           is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat);
>        }
>  
> -      st_translate_color(&msamp->BorderColor,
> -                         &sampler->border_color,
> -                         teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +      if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view)
> {
> +         const unsigned char swz[4] =
> +         {
> +            stobj->sampler_view->swizzle_r,
> +            stobj->sampler_view->swizzle_g,
> +            stobj->sampler_view->swizzle_b,
> +            stobj->sampler_view->swizzle_a,
> +         };
> +
> +         st_translate_color(&msamp->BorderColor,
> +                            &border_color,
> +                            teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +
> +         util_format_apply_color_swizzle(&sampler->border_color,
> +                                         &border_color, swz, is_integer);
> +      } else {
> +         st_translate_color(&msamp->BorderColor,
> +                            &sampler->border_color,
> +                            teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +      }
>     }
>  
>     sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
> diff --git a/src/mesa/state_tracker/st_context.c
> b/src/mesa/state_tracker/st_context.c
> index 2042be3..bb216e2 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -188,6 +188,9 @@ st_create_context_priv( struct gl_context *ctx, struct
> pipe_context *pipe,
>  
>     st->needs_texcoord_semantic =
>        screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
> +   st->apply_texture_swizzle_to_border_color =
> +      !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
> +         PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50);
>  
>     /* GL limits and extensions */
>     st_init_limits(st);
> diff --git a/src/mesa/state_tracker/st_context.h
> b/src/mesa/state_tracker/st_context.h
> index 8786a03..807453e 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -87,6 +87,7 @@ struct st_context
>     boolean prefer_blit_based_texture_transfer;
>  
>     boolean needs_texcoord_semantic;
> +   boolean apply_texture_swizzle_to_border_color;
>  
>     /* On old libGL's for linux we need to invalidate the drawables
>      * on glViewpport calls, this is set via a option.
> --
> 1.7.3.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