inline void generate_mipmaps_1d
(
    texture_type & Texture, fetch_func Fetch, write_func Write,
    typename texture_type::size_type BaseLayer, typename texture_type::size_type MaxLayer,
    typename texture_type::size_type BaseFace, typename texture_type::size_type MaxFace,
    typename texture_type::size_type BaseLevel, typename texture_type::size_type MaxLevel,
    filter Min
)
{
    typedef typename detail::interpolate<sampler_value_type>::type interpolate_type;
    typedef typename texture_type::texelcoord_type texelcoord_type;
    typedef typename texture_type::size_type size_type;
    typedef typename texelcoord_type::value_type component_type;
    typedef typename detail::filterBase<detail::DIMENSION_1D, texture_type, interpolate_type, samplecoord_type, fetch_func, texel_type>::filterFunc filter_func;

    filter_func const Filter = detail::get_filter<filter_func, detail::DIMENSION_1D, texture_type, interpolate_type, samplecoord_type, fetch_func, texel_type, sampler_value_type>(FILTER_NEAREST, Min, false);
    GLI_ASSERT(Filter);

    for(size_type Layer = BaseLayer; Layer <= MaxLayer; ++Layer)
        for(size_type Face = BaseFace; Face <= MaxFace; ++Face)
            for(size_type Level = BaseLevel; Level < MaxLevel; ++Level)
            {
                texelcoord_type const& DimDst = Texture.dimensions(Level + 1);
                samplecoord_type const& Scale = samplecoord_type(1) / samplecoord_type(max(DimDst - texelcoord_type(1), texelcoord_type(1)));

                for(component_type i = 0; i < DimDst.x; ++i)
                {
                    samplecoord_type const& SamplePosition(samplecoord_type(static_cast<typename samplecoord_type::value_type>(i)) * Scale);
                    texel_type const& Texel = Filter(Texture, Fetch, SamplePosition, Layer, Face, static_cast<sampler_value_type>(Level), texel_type(0));
                    Write(Texture, texelcoord_type(i), Layer, Face, Level + 1, Texel);
                }
            }
}
		static texel_type call(texture_type const & Texture, fetch_type Fetch, samplecoord_type const & SampleCoordWrap, size_type Layer, size_type Face, interpolate_type Level, texel_type const & BorderColor)
		{
			size_type const LevelIndex = static_cast<size_type>(Level);
			coord_type const & Coord = make_coord_linear(Texture.dimensions(LevelIndex), SampleCoordWrap);

			texel_type const & Texel000 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelFloor.t, Coord.TexelFloor.p), Layer, Face, LevelIndex);
			texel_type const & Texel100 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelFloor.t, Coord.TexelFloor.p), Layer, Face, LevelIndex);
			texel_type const & Texel110 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelCeil.t, Coord.TexelFloor.p), Layer, Face, LevelIndex);
			texel_type const & Texel010 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelCeil.t, Coord.TexelFloor.p), Layer, Face, LevelIndex);
			texel_type const & Texel001 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelFloor.t, Coord.TexelCeil.p), Layer, Face, LevelIndex);
			texel_type const & Texel101 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelFloor.t, Coord.TexelCeil.p), Layer, Face, LevelIndex);
			texel_type const & Texel111 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelCeil.t, Coord.TexelCeil.p), Layer, Face, LevelIndex);
			texel_type const & Texel011 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelCeil.t, Coord.TexelCeil.p), Layer, Face, LevelIndex);

			texel_type const ValueA(mix(Texel000, Texel100, Coord.Blend.s));
			texel_type const ValueB(mix(Texel010, Texel110, Coord.Blend.s));

			texel_type const ValueC(mix(Texel001, Texel101, Coord.Blend.s));
			texel_type const ValueD(mix(Texel011, Texel111, Coord.Blend.s));

			texel_type const ValueE(mix(ValueA, ValueB, Coord.Blend.t));
			texel_type const ValueF(mix(ValueC, ValueD, Coord.Blend.t));

			return mix(ValueE, ValueF, Coord.Blend.p);
		}
		static texel_type call(texture_type const & Texture, fetch_type Fetch, samplecoord_type const & SampleCoordWrap, size_type Layer, size_type Face, interpolate_type Level, texel_type const & BorderColor)
		{
			size_type const LevelIndex = static_cast<typename texture_type::size_type>(Level);
			coord_type const & Coord = make_coord_linear_border(Texture.dimensions(LevelIndex), SampleCoordWrap);

			texel_type Texel00(BorderColor);
			if(Coord.UseTexelFloor.s && Coord.UseTexelFloor.t)
				Texel00 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelFloor.t), Layer, Face, LevelIndex);

			texel_type Texel10(BorderColor);
			if(Coord.UseTexelCeil.s && Coord.UseTexelFloor.t)
				Texel10 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelFloor.t), Layer, Face, LevelIndex);

			texel_type Texel11(BorderColor);
			if(Coord.UseTexelCeil.s && Coord.UseTexelCeil.t)
				Texel11 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s, Coord.TexelCeil.t), Layer, Face, LevelIndex);

			texel_type Texel01(BorderColor);
			if(Coord.UseTexelFloor.s && Coord.UseTexelCeil.t)
				Texel01 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s, Coord.TexelCeil.t), Layer, Face, LevelIndex);

			texel_type const ValueA(mix(Texel00, Texel10, Coord.Blend.s));
			texel_type const ValueB(mix(Texel01, Texel11, Coord.Blend.s));
			return mix(ValueA, ValueB, Coord.Blend.t);
		}
		static texel_type call(texture_type const & Texture, fetch_type Fetch, samplecoord_type const & SampleCoordWrap, size_type Layer, size_type Face, interpolate_type Level, texel_type const & BorderColor)
		{
			size_type const LevelIndex = static_cast<size_type>(Level);
			samplecoord_type const TexelLast(samplecoord_type(Texture.dimensions(LevelIndex)) - samplecoord_type(1));
			texelcoord_type const TexelCoord = texelcoord_type(round(SampleCoordWrap * TexelLast));

			return Fetch(Texture, TexelCoord, Layer, Face, LevelIndex);
		}
		static texel_type call(texture_type const & Texture, fetch_type Fetch, samplecoord_type const & SampleCoordWrap, size_type Layer, size_type Face, interpolate_type Level, texel_type const & BorderColor)
		{
			size_type const LevelIndex = static_cast<size_type>(Level);
			coord_type const & Coord = make_coord_linear(Texture.dimensions(LevelIndex), SampleCoordWrap);

			texel_type const Texel0 = Fetch(Texture, texelcoord_type(Coord.TexelFloor.s), Layer, Face, LevelIndex);
			texel_type const Texel1 = Fetch(Texture, texelcoord_type(Coord.TexelCeil.s), Layer, Face, LevelIndex);

			return mix(Texel0, Texel1, Coord.Blend.s);
		}
		static texel_type call(texture_type const & Texture, fetch_type Fetch, samplecoord_type const & SampleCoordWrap, size_type Layer, size_type Face, interpolate_type Level, texel_type const & BorderColor)
		{
			size_type const LevelIndex = static_cast<size_type>(Level);
			texelcoord_type const TexelDim(Texture.dimensions(LevelIndex));
			samplecoord_type const TexelLast(samplecoord_type(TexelDim) - samplecoord_type(1));
			texelcoord_type const TexelCoord = texelcoord_type(round(SampleCoordWrap * TexelLast));
			typename texelcoord_type::bool_type const UseTexelCoord = in_interval(TexelCoord, texelcoord_type(0), TexelDim - 1);

			texel_type Texel(BorderColor);
			if(all(UseTexelCoord))
				Texel = Fetch(Texture, TexelCoord, Layer, Face, LevelIndex);

			return Texel;
		}