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