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

Marek Olšák maraeo at gmail.com
Sat Apr 13 12:35:42 PDT 2013


PIPE_CAP_TEXTURE_SWIZZLE_AFFECTS_BORDER_COLOR would be a better name (note
the meaning is inverted). Other than that, this looks good.

Marek


On Sat, Apr 13, 2013 at 4:31 PM, Christoph Bumiller <
e0425955 at student.tuwien.ac.at> wrote:

> 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 name of the cap could be changed to be more descriptive, like
> PIPE_CAP_TEXTURE_SWIZZLE_AFFECTS_BORDER_COLOR.
>
> The dependency of update_sampler on the texture updates was
> introduced to avoid doing the apply_depthmode to the swizzle twice.
>
> More detailed explanation of driver situation:
>
> No, really, don't suggest doing this in the driver. The driver has
> elegantly separated texture view and sampler states (which are each
> a structure in a table in VRAM and should not be updated to avoid
> performance loss), and table are bound to the independent (!) texture
> and sampler slots in shaders which must be separately indexable
> indirectly).
> So, if I was to do this in the driver, I'd have to add separate sampler
> state object instances for each texture view with appropriately swizzled
> border color, and there's only 16 slots, so I'd be limited to 4 texture
> units.
> Not to mention the sheer insanity, ugliness and emotional pain incurred
> when writing that code when it COULD be so easy and simple in the state
> tracker where you know that textures and samplers are tightly coupled,
> while in gallium I cannot assume that to be the case.
> ---
>  src/gallium/docs/source/cso/sampler.rst          |    7 ++-
>  src/gallium/docs/source/screen.rst               |    2 +
>  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           |    1 +
>  src/gallium/drivers/nvc0/nvc0_screen.c           |    1 +
>  src/gallium/drivers/r300/r300_screen.c           |    1 +
>  src/gallium/drivers/r600/r600_pipe.c             |    1 +
>  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             |    3 +-
>  src/mesa/state_tracker/st_atom.c                 |    2 +-
>  src/mesa/state_tracker/st_atom_sampler.c         |   65
> +++++++++++++++++++++-
>  src/mesa/state_tracker/st_context.c              |    2 +
>  src/mesa/state_tracker/st_context.h              |    1 +
>  18 files changed, 89 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/docs/source/cso/sampler.rst
> b/src/gallium/docs/source/cso/sampler.rst
> index 26ffc18..1911cea 100644
> --- a/src/gallium/docs/source/cso/sampler.rst
> +++ b/src/gallium/docs/source/cso/sampler.rst
> @@ -101,7 +101,10 @@ 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_BORDER_COLOR_QUIRK, in which case this value is substituted
> for
> +    the texture color exactly as specified, the sampler view format and
> swizzle
> +    have no effect on it.
>  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 +114,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..495398b 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -151,6 +151,8 @@ 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_BORDER_COLOR_QUIRK``: Whether the sampler view's format and
> swizzle
> +  affect the border color.
>
>
>  .. _pipe_capf:
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 283d07f..5b60401 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_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..4c3d52f 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_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..9506162 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_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..52a3ec9 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_BORDER_COLOR_QUIRK: /* TODO: check */
>        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..39e0e63 100644
> --- a/src/gallium/drivers/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nv50/nv50_screen.c
> @@ -161,6 +161,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_CONDITIONAL_RENDER:
>     case PIPE_CAP_TEXTURE_BARRIER:
>     case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
> +   case PIPE_CAP_BORDER_COLOR_QUIRK:
>     case PIPE_CAP_START_INSTANCE:
>        return 1;
>     case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
> diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c
> b/src/gallium/drivers/nvc0/nvc0_screen.c
> index ccdf2cd..4768e9d 100644
> --- a/src/gallium/drivers/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nvc0/nvc0_screen.c
> @@ -153,6 +153,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
>     case PIPE_CAP_CONDITIONAL_RENDER:
>     case PIPE_CAP_TEXTURE_BARRIER:
>     case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
> +   case PIPE_CAP_BORDER_COLOR_QUIRK:
>     case PIPE_CAP_START_INSTANCE:
>        return 1;
>     case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
> diff --git a/src/gallium/drivers/r300/r300_screen.c
> b/src/gallium/drivers/r300/r300_screen.c
> index 3175b3b..f8bd5ce 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_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..ec05732 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -611,6 +611,7 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>         case PIPE_CAP_VERTEX_COLOR_CLAMPED:
>         case PIPE_CAP_USER_VERTEX_BUFFERS:
>         case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> +       case PIPE_CAP_BORDER_COLOR_QUIRK:
>                 return 0;
>
>         /* Stream output. */
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> index 5c25b2f..b1f50bf 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_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..fb602ba 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_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..a8235b8 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_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 c790660..35d2707 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -505,7 +505,8 @@ 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_BORDER_COLOR_QUIRK = 82
>  };
>
>  /**
> 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..1a78144 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -123,6 +123,54 @@ gl_filter_to_img_filter(GLenum filter)
>  }
>
>
> +static INLINE unsigned
> +get_sampler_view_swz(const struct pipe_sampler_view *view, unsigned
> component)
> +{
> +   switch (component) {
> +   case 1: return view->swizzle_g;
> +   case 2: return view->swizzle_b;
> +   case 3: return view->swizzle_a;
> +   default:
> +      assert(component == 0);
> +      return view->swizzle_r;
> +   }
> +}
> +
> +static void
> +apply_swizzle(union pipe_color_union *dst, const union pipe_color_union
> *src,
> +              const struct pipe_sampler_view *view, boolean is_integer)
> +{
> +   unsigned c;
> +
> +   if (is_integer) {
> +      for (c = 0; c < 4; ++c) {
> +         unsigned swz = get_sampler_view_swz(view, c);
> +         switch (swz) {
> +         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 == PIPE_SWIZZLE_ONE) ? 1 : 0;
> +            break;
> +         }
> +      }
> +   } else {
> +      for (c = 0; c < 4; ++c) {
> +         unsigned swz = get_sampler_view_swz(view, c);
> +         switch (swz) {
> +         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 == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
> +            break;
> +         }
> +      }
> +   }
> +}
> +
>  static void
>  convert_sampler(struct st_context *st,
>                  struct pipe_sampler_state *sampler,
> @@ -172,8 +220,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 +231,18 @@ 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) {
> +         st_translate_color(&msamp->BorderColor,
> +                            &border_color,
> +                            teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +
> +         apply_swizzle(&sampler->border_color, &border_color,
> +                       stobj->sampler_view, 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..a6aee69 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -188,6 +188,8 @@ 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_BORDER_COLOR_QUIRK);
>
>     /* 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130413/bdf26e6a/attachment-0001.html>


More information about the mesa-dev mailing list