Luca,

Thanks for looking into this - this is a bit of a grey area for me.

One question - do we need a full floating point value to represent
max_anisotropy?  What is the typical maximum value for max_anisotropy in
hardware, and how may levels are there?  From the patch below, most
DX9-level hardware seems to support only one or two levels - is newer
hardware significantly more flexible?

I'm a bit swamped by an email backlog from christmas & are working
through your previous patches and threads.  Hopefully will be caught up
soon.

Keith

On Fri, 2010-01-01 at 14:32 -0800, Luca Barbieri wrote:
> Currently Gallium defines a specific filtering mode for anisotropic filtering.
> 
> This however prevents proper implementation of 
> GL_EXT_texture_filter_anisotropic.
> 
> The spec (written by nVidia) contains the following text:
> <<<
>     A texture's maximum degree of anisotropy is specified independent
>     from the texture's minification and magnification filter (as
>     opposed to being supported as an entirely new filtering mode).
>     Implementations are free to use the specified minification and
>     magnification filter to select a particular anisotropic texture
>     filtering scheme.  For example, a NEAREST filter with a maximum
>     degree of anisotropy of two could be treated as a 2-tap filter that
>     accounts for the direction of anisotropy.  Implementations are also
>     permitted to ignore the minification or magnification filter and
>     implement the highest quality of anisotropic filtering possible.
> >>
> 
> and
> 
> <<<
>     Should there be a particular anisotropic texture filtering minification
>     and magnification mode?
> 
>       RESOLUTION:  NO.  The maximum degree of anisotropy should control
>       when anisotropic texturing is used.  Making this orthogonal to
>       the minification and magnification filtering modes allows these
>       settings to influence the anisotropic scheme used.  Yes, such
>       an anisotropic filtering scheme exists in hardware.
> >>>
> 
> Gallium does the opposite, and this prevents use of nearest anisotropic 
> filtering which is supported in nVidia hardware and also introduces redundant 
> state.
> 
> This patch removes PIPE_TEX_FILTER_ANISO.
> Anisotropic filtering is enabled if and only if max_anisotropy > 1.0.
> Values between 0.0 and 1.0, inclusive, of max_anisotropy are to be considered 
> equivalent, and meaning to turn off anisotropic filtering.
> 
> This approach has the small drawback of eliminating the possibility of 
> enabling anisotropic filter on either minification or magnification 
> separately, which Radeon hardware seems to support, is currently support by 
> Gallium but not exposed to OpenGL.
> If this is actually useful it could be handled by splitting max_anisotropy in 
> two values and adding an appropriate OpenGL extension.
> 
> How does Radeon anisotropic magnification differ from linear magnification?
> ---
>  src/gallium/auxiliary/util/u_debug_dump.c        |    6 +--
>  src/gallium/drivers/cell/spu/spu_command.c       |    4 --
>  src/gallium/drivers/i915/i915_state.c            |    5 +-
>  src/gallium/drivers/i965/brw_pipe_sampler.c      |    2 -
>  src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c |    1 -
>  src/gallium/drivers/llvmpipe/lp_tex_sample_c.c   |    3 -
>  src/gallium/drivers/nv50/nv50_state.c            |    2 -
>  src/gallium/drivers/r300/r300_state.c            |    2 +-
>  src/gallium/drivers/r300/r300_state_inlines.h    |   58 ++++++++++-----------
>  src/gallium/drivers/svga/svga_pipe_sampler.c     |    3 +-
>  src/gallium/include/pipe/p_defines.h             |    4 +-
>  src/gallium/state_trackers/vega/image.c          |    2 +-
>  src/mesa/state_tracker/st_atom_sampler.c         |    4 --
>  13 files changed, 40 insertions(+), 56 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_debug_dump.c 
> b/src/gallium/auxiliary/util/u_debug_dump.c
> index 0986688..61624d0 100644
> --- a/src/gallium/auxiliary/util/u_debug_dump.c
> +++ b/src/gallium/auxiliary/util/u_debug_dump.c
> @@ -255,15 +255,13 @@ DEFINE_DEBUG_DUMP_CONTINUOUS(tex_mipfilter)
>  static const char *
>  debug_dump_tex_filter_names[] = {
>     "PIPE_TEX_FILTER_NEAREST",
> -   "PIPE_TEX_FILTER_LINEAR",
> -   "PIPE_TEX_FILTER_ANISO"
> +   "PIPE_TEX_FILTER_LINEAR"
>  };
> 
>  static const char *
>  debug_dump_tex_filter_short_names[] = {
>     "nearest",
> -   "linear",
> -   "aniso"
> +   "linear"
>  };
> 
>  DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter)
> diff --git a/src/gallium/drivers/cell/spu/spu_command.c 
> b/src/gallium/drivers/cell/spu/spu_command.c
> index 5c0179d..12b855a 100644
> --- a/src/gallium/drivers/cell/spu/spu_command.c
> +++ b/src/gallium/drivers/cell/spu/spu_command.c
> @@ -405,8 +405,6 @@ cmd_state_sampler(const struct cell_command_sampler 
> *sampler)
>     case PIPE_TEX_FILTER_LINEAR:
>        spu.min_sample_texture_2d[unit] = sample_texture_2d_bilinear;
>        break;
> -   case PIPE_TEX_FILTER_ANISO:
> -      /* fall-through, for now */
>     case PIPE_TEX_FILTER_NEAREST:
>        spu.min_sample_texture_2d[unit] = sample_texture_2d_nearest;
>        break;
> @@ -418,8 +416,6 @@ cmd_state_sampler(const struct cell_command_sampler 
> *sampler)
>     case PIPE_TEX_FILTER_LINEAR:
>        spu.mag_sample_texture_2d[unit] = sample_texture_2d_bilinear;
>        break;
> -   case PIPE_TEX_FILTER_ANISO:
> -      /* fall-through, for now */
>     case PIPE_TEX_FILTER_NEAREST:
>        spu.mag_sample_texture_2d[unit] = sample_texture_2d_nearest;
>        break;
> diff --git a/src/gallium/drivers/i915/i915_state.c 
> b/src/gallium/drivers/i915/i915_state.c
> index 1528afc..5f5b6f8 100644
> --- a/src/gallium/drivers/i915/i915_state.c
> +++ b/src/gallium/drivers/i915/i915_state.c
> @@ -74,8 +74,6 @@ static unsigned translate_img_filter( unsigned filter )
>        return FILTER_NEAREST;
>     case PIPE_TEX_FILTER_LINEAR:
>        return FILTER_LINEAR;
> -   case PIPE_TEX_FILTER_ANISO:
> -      return FILTER_ANISOTROPIC;
>     default:
>        assert(0);
>        return FILTER_NEAREST;
> @@ -221,6 +219,9 @@ i915_create_sampler_state(struct pipe_context *pipe,
>     minFilt = translate_img_filter( sampler->min_img_filter );
>     magFilt = translate_img_filter( sampler->mag_img_filter );
> 
> +   if (sampler->max_anisotropy > 1.0)
> +      minFilt = magFilt = FILTER_ANISOTROPIC;
> +
>     if (sampler->max_anisotropy > 2.0) {
>        cso->state[0] |= SS2_MAX_ANISO_4;
>     }
> diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c 
> b/src/gallium/drivers/i965/brw_pipe_sampler.c
> index 5ddc63f..8171279 100644
> --- a/src/gallium/drivers/i965/brw_pipe_sampler.c
> +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c
> @@ -48,8 +48,6 @@ static GLuint translate_img_filter( unsigned filter )
>        return BRW_MAPFILTER_NEAREST;
>     case PIPE_TEX_FILTER_LINEAR:
>        return BRW_MAPFILTER_LINEAR;
> -   case PIPE_TEX_FILTER_ANISO:
> -      return BRW_MAPFILTER_ANISOTROPIC;
>     default:
>        assert(0);
>        return BRW_MAPFILTER_NEAREST;
> diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c 
> b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
> index 47b68b7..c46fef5 100644
> --- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
> +++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
> @@ -577,7 +577,6 @@ lp_build_sample_soa(LLVMBuilderRef builder,
>        lp_build_sample_2d_nearest_soa(&bld, s, t, width, height, stride, 
> data_ptr, texel);
>        break;
>     case PIPE_TEX_FILTER_LINEAR:
> -   case PIPE_TEX_FILTER_ANISO:
>        if(lp_format_is_rgba8(bld.format_desc))
>           lp_build_sample_2d_linear_aos(&bld, s, t, width, height, stride, 
> data_ptr, texel);
>        else
> diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c 
> b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
> index 0d01c07..91a3aed 100644
> --- a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
> +++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
> @@ -1131,7 +1131,6 @@ lp_get_samples_2d_common(struct tgsi_sampler 
> *tgsi_sampler,
>        }
>        break;
>     case PIPE_TEX_FILTER_LINEAR:
> -   case PIPE_TEX_FILTER_ANISO:
>        {
>           int x0[4], y0[4], x1[4], y1[4];
>           float xw[4], yw[4]; /* weights */
> @@ -1283,7 +1282,6 @@ lp_get_samples_3d(struct tgsi_sampler *tgsi_sampler,
>        }
>        break;
>     case PIPE_TEX_FILTER_LINEAR:
> -   case PIPE_TEX_FILTER_ANISO:
>        {
>           int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
>           float xw[4], yw[4], zw[4]; /* interpolation weights */
> @@ -1414,7 +1412,6 @@ lp_get_samples_rect(struct tgsi_sampler *tgsi_sampler,
>        }
>        break;
>     case PIPE_TEX_FILTER_LINEAR:
> -   case PIPE_TEX_FILTER_ANISO:
>        {
>           int x0[4], y0[4], x1[4], y1[4];
>           float xw[4], yw[4]; /* weights */
> diff --git a/src/gallium/drivers/nv50/nv50_state.c 
> b/src/gallium/drivers/nv50/nv50_state.c
> index 30b2b0f..ce4b5c8 100644
> --- a/src/gallium/drivers/nv50/nv50_state.c
> +++ b/src/gallium/drivers/nv50/nv50_state.c
> @@ -146,7 +146,6 @@ nv50_sampler_state_create(struct pipe_context *pipe,
>                   (wrap_mode(cso->wrap_r) << 6));
> 
>         switch (cso->mag_img_filter) {
> -       case PIPE_TEX_FILTER_ANISO:
>         case PIPE_TEX_FILTER_LINEAR:
>                 tsc[1] |= NV50TSC_1_1_MAGF_LINEAR;
>                 break;
> @@ -157,7 +156,6 @@ nv50_sampler_state_create(struct pipe_context *pipe,
>         }
> 
>         switch (cso->min_img_filter) {
> -       case PIPE_TEX_FILTER_ANISO:
>         case PIPE_TEX_FILTER_LINEAR:
>                 tsc[1] |= NV50TSC_1_1_MINF_LINEAR;
>                 break;
> diff --git a/src/gallium/drivers/r300/r300_state.c 
> b/src/gallium/drivers/r300/r300_state.c
> index 4907246..dcff7b7 100644
> --- a/src/gallium/drivers/r300/r300_state.c
> +++ b/src/gallium/drivers/r300/r300_state.c
> @@ -556,7 +556,7 @@ static void*
> 
>      sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter,
>                                                     state->mag_img_filter,
> -                                                   state->min_mip_filter);
> +                                                   state->min_mip_filter, 
> state->max_anisotropy > 1.0);
> 
>      /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */
>      /* We must pass these to the emit function to clamp them properly. */
> diff --git a/src/gallium/drivers/r300/r300_state_inlines.h 
> b/src/gallium/drivers/r300/r300_state_inlines.h
> index dbe42ed..7852465 100644
> --- a/src/gallium/drivers/r300/r300_state_inlines.h
> +++ b/src/gallium/drivers/r300/r300_state_inlines.h
> @@ -257,38 +257,36 @@ static INLINE uint32_t r300_translate_wrap(int wrap)
>      }
>  }
> 
> -static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip)
> +static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip, 
> int is_anisotropic)
>  {
>      uint32_t retval = 0;
> -    switch (min) {
> -        case PIPE_TEX_FILTER_NEAREST:
> -            retval |= R300_TX_MIN_FILTER_NEAREST;
> -            break;
> -        case PIPE_TEX_FILTER_LINEAR:
> -            retval |= R300_TX_MIN_FILTER_LINEAR;
> -            break;
> -        case PIPE_TEX_FILTER_ANISO:
> -            retval |= R300_TX_MIN_FILTER_ANISO;
> -            break;
> -        default:
> -            debug_printf("r300: Unknown texture filter %d\n", min);
> -            assert(0);
> -            break;
> -    }
> -    switch (mag) {
> -        case PIPE_TEX_FILTER_NEAREST:
> -            retval |= R300_TX_MAG_FILTER_NEAREST;
> -            break;
> -        case PIPE_TEX_FILTER_LINEAR:
> -            retval |= R300_TX_MAG_FILTER_LINEAR;
> -            break;
> -        case PIPE_TEX_FILTER_ANISO:
> -            retval |= R300_TX_MAG_FILTER_ANISO;
> -            break;
> -        default:
> -            debug_printf("r300: Unknown texture filter %d\n", mag);
> -            assert(0);
> -            break;
> +    if(is_anisotropic)
> +        retval |= R300_TX_MIN_FILTER_ANISO | R300_TX_MAG_FILTER_ANISO;
> +    else {
> +        switch (min) {
> +            case PIPE_TEX_FILTER_NEAREST:
> +                retval |= R300_TX_MIN_FILTER_NEAREST;
> +                break;
> +            case PIPE_TEX_FILTER_LINEAR:
> +                retval |= R300_TX_MIN_FILTER_LINEAR;
> +                break;
> +            default:
> +                debug_printf("r300: Unknown texture filter %d\n", min);
> +                assert(0);
> +                break;
> +        }
> +        switch (mag) {
> +            case PIPE_TEX_FILTER_NEAREST:
> +                retval |= R300_TX_MAG_FILTER_NEAREST;
> +                break;
> +            case PIPE_TEX_FILTER_LINEAR:
> +                retval |= R300_TX_MAG_FILTER_LINEAR;
> +                break;
> +            default:
> +                debug_printf("r300: Unknown texture filter %d\n", mag);
> +                assert(0);
> +                break;
> +        }
>      }
>      switch (mip) {
>          case PIPE_TEX_MIPFILTER_NONE:
> diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c 
> b/src/gallium/drivers/svga/svga_pipe_sampler.c
> index 78053e7..460a101 100644
> --- a/src/gallium/drivers/svga/svga_pipe_sampler.c
> +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c
> @@ -76,7 +76,6 @@ static INLINE unsigned translate_img_filter( unsigned 
> filter )
>     switch (filter) {
>     case PIPE_TEX_FILTER_NEAREST: return SVGA3D_TEX_FILTER_NEAREST;
>     case PIPE_TEX_FILTER_LINEAR:  return SVGA3D_TEX_FILTER_LINEAR;
> -   case PIPE_TEX_FILTER_ANISO:   return SVGA3D_TEX_FILTER_ANISOTROPIC;
>     default:
>        assert(0);
>        return SVGA3D_TEX_FILTER_NEAREST;
> @@ -107,6 +106,8 @@ svga_create_sampler_state(struct pipe_context *pipe,
>     cso->magfilter = translate_img_filter( sampler->mag_img_filter );
>     cso->minfilter = translate_img_filter( sampler->min_img_filter );
>     cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 );
> +   if(cso->aniso_level != 1)
> +      cso->magfilter = cso->minfilter = SVGA3D_TEX_FILTER_ANISOTROPIC;
>     cso->lod_bias = sampler->lod_bias;
>     cso->addressu = translate_wrap_mode(sampler->wrap_s);
>     cso->addressv = translate_wrap_mode(sampler->wrap_t);
> diff --git a/src/gallium/include/pipe/p_defines.h 
> b/src/gallium/include/pipe/p_defines.h
> index 2cda408..a1ed2be 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -171,7 +171,9 @@ enum pipe_texture_target {
>   */
>  #define PIPE_TEX_FILTER_NEAREST      0
>  #define PIPE_TEX_FILTER_LINEAR       1
> -#define PIPE_TEX_FILTER_ANISO        2
> +
> +/* obsolete: max_anisotropy is now used to determine whether anisotropic 
> filtering is enabled */
> +#define PIPE_TEX_FILTER_ANISO        PIPE_TEX_FILTER_LINEAR
> 
> 
>  #define PIPE_TEX_COMPARE_NONE          0
> diff --git a/src/gallium/state_trackers/vega/image.c 
> b/src/gallium/state_trackers/vega/image.c
> index 278ba6d..1112ad9 100644
> --- a/src/gallium/state_trackers/vega/image.c
> +++ b/src/gallium/state_trackers/vega/image.c
> @@ -644,7 +644,7 @@ VGint image_sampler_filter(struct vg_context *ctx)
>         return PIPE_TEX_FILTER_NEAREST;
>         break;
>      case VG_IMAGE_QUALITY_BETTER:
> -       /*return PIPE_TEX_FILTER_ANISO;*/
> +       /* possibly use anisotropic filtering */
>         return PIPE_TEX_FILTER_LINEAR;
>         break;
>      default:
> diff --git a/src/mesa/state_tracker/st_atom_sampler.c 
> b/src/mesa/state_tracker/st_atom_sampler.c
> index d6e3a3e..48ff342 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -213,10 +213,6 @@ update_samplers(struct st_context *st)
>                              sampler->border_color);
> 
>          sampler->max_anisotropy = texobj->MaxAnisotropy;
> -         if (sampler->max_anisotropy > 1.0) {
> -            sampler->min_img_filter = PIPE_TEX_FILTER_ANISO;
> -            sampler->mag_img_filter = PIPE_TEX_FILTER_ANISO;
> -         }
> 
>           /* only care about ARB_shadow, not SGI shadow */
>           if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
> --
> 1.6.3.3
> 
> 
> ------------------------------------------------------------------------------
> This SF.Net email is sponsored by the Verizon Developer Community
> Take advantage of Verizon's best-in-class app development support
> A streamlined, 14 day to market process makes app distribution fast and easy
> Join now and get one step closer to millions of Verizon customers
> http://p.sf.net/sfu/verizon-dev2dev
> _______________________________________________
> Mesa3d-dev mailing list
> Mesa3d-dev@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/mesa3d-dev



------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to