[Mesa-dev] [PATCH] llvmpipe, gallivm: implement lod queries (LODQ opcode)

Jose Fonseca jfonseca at vmware.com
Mon Sep 18 15:42:24 UTC 2017


On 18/09/17 03:53, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> This uses all the existing code to calculate lod values for mip linear
> filtering. Though we'll have to disable the simplifications (if we know some
> parts of the lod calculation won't actually matter for filtering purposes due
> to mip clamps etc.). For better or worse, we'll also disable lod calculation
> hacks (mostly should make a difference for cube maps) always - the issue with
> per-pixel lod being difficult is mostly because we then have different mipmaps
> needed for the actual texel fetch, which isn't a problem with lodq.
> We still use approximation for the log2 - for that reason I believe the float
> part of the lod is only accurate to about 4-5 bits (and one bit less with 1d
> textures actually) which is hopefully good enough (though d3d10 technically
> requires 6 bits - could use quadratic interpolation instead of linear to get
> 8 bits or so).
> Since lodq requires unclamped lod, we also have to move some sampler key
> calculations to texture sampling code - even if we know we're going to access
> mipmap 0 we still have to calculate lod and apply lod_bias for lodq.
> 
> Passes piglit ARB_texture_query_lod tests, after applying some fixes there
> (pending review...)
> ---
>   docs/features.txt                                 |   2 +-
>   src/gallium/auxiliary/gallivm/lp_bld_sample.c     |  40 ++++---
>   src/gallium/auxiliary/gallivm/lp_bld_sample.h     |  10 +-
>   src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 137 +++++++++++++++-------
>   src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c   |  13 ++
>   src/gallium/drivers/llvmpipe/lp_screen.c          |   2 +-
>   6 files changed, 145 insertions(+), 59 deletions(-)
> 
> diff --git a/docs/features.txt b/docs/features.txt
> index fe412f6..c186dc7 100644
> --- a/docs/features.txt
> +++ b/docs/features.txt
> @@ -131,7 +131,7 @@ GL 4.0, GLSL 4.00 --- all DONE: i965/gen7+, nvc0, r600, radeonsi
>     GL_ARB_texture_buffer_object_rgb32                    DONE (i965/gen6+, llvmpipe, softpipe, swr)
>     GL_ARB_texture_cube_map_array                         DONE (i965/gen6+, nv50, llvmpipe, softpipe)
>     GL_ARB_texture_gather                                 DONE (i965/gen6+, nv50, llvmpipe, softpipe, swr)
> -  GL_ARB_texture_query_lod                              DONE (i965, nv50, softpipe)
> +  GL_ARB_texture_query_lod                              DONE (i965, nv50, llvmpipe, softpipe)
>     GL_ARB_transform_feedback2                            DONE (i965/gen6+, nv50, llvmpipe, softpipe, swr)
>     GL_ARB_transform_feedback3                            DONE (i965/gen7+, llvmpipe, softpipe, swr)
>   
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> index a1dc61d..db3d9d6 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
> @@ -156,19 +156,19 @@ lp_sampler_static_sampler_state(struct lp_static_sampler_state *state,
>      state->wrap_r            = sampler->wrap_r;
>      state->min_img_filter    = sampler->min_img_filter;
>      state->mag_img_filter    = sampler->mag_img_filter;
> +   state->min_mip_filter    = sampler->min_mip_filter;
>      state->seamless_cube_map = sampler->seamless_cube_map;
>   
>      if (sampler->max_lod > 0.0f) {
> -      state->min_mip_filter = sampler->min_mip_filter;
> -   } else {
> -      state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
> +      state->max_lod_pos = 1;
> +   }
> +
> +   if (sampler->lod_bias != 0.0f) {
> +      state->lod_bias_non_zero = 1;
>      }
>   
>      if (state->min_mip_filter != PIPE_TEX_MIPFILTER_NONE ||
>          state->min_img_filter != state->mag_img_filter) {
> -      if (sampler->lod_bias != 0.0f) {
> -         state->lod_bias_non_zero = 1;
> -      }
>   
>         /* If min_lod == max_lod we can greatly simplify mipmap selection.
>          * This is a case that occurs during automatic mipmap generation.
> @@ -234,7 +234,7 @@ lp_build_rho(struct lp_build_sample_context *bld,
>      unsigned length = coord_bld->type.length;
>      unsigned num_quads = length / 4;
>      boolean rho_per_quad = rho_bld->type.length != length;
> -   boolean no_rho_opt = (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) && (dims > 1);
> +   boolean no_rho_opt = bld->no_rho_approx && (dims > 1);
>      unsigned i;
>      LLVMValueRef i32undef = LLVMGetUndef(LLVMInt32TypeInContext(gallivm->context));
>      LLVMValueRef rho_xvec, rho_yvec;
> @@ -694,6 +694,7 @@ lp_build_ilog2_sqrt(struct lp_build_context *bld,
>    */
>   void
>   lp_build_lod_selector(struct lp_build_sample_context *bld,
> +                      boolean is_lodq,
>                         unsigned texture_unit,
>                         unsigned sampler_unit,
>                         LLVMValueRef s,
> @@ -704,6 +705,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>                         LLVMValueRef lod_bias, /* optional */
>                         LLVMValueRef explicit_lod, /* optional */
>                         unsigned mip_filter,
> +                      LLVMValueRef *out_lod,
>                         LLVMValueRef *out_lod_ipart,
>                         LLVMValueRef *out_lod_fpart,
>                         LLVMValueRef *out_lod_positive)
> @@ -736,7 +738,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>       * I have no clue about the (undocumented) wishes of d3d9/d3d10 here!
>       */
>   
> -   if (bld->static_sampler_state->min_max_lod_equal) {
> +   if (bld->static_sampler_state->min_max_lod_equal && !is_lodq) {
>         /* User is forcing sampling from a particular mipmap level.
>          * This is hit during mipmap generation.
>          */
> @@ -756,7 +758,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>         }
>         else {
>            LLVMValueRef rho;
> -         boolean rho_squared = ((gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
> +         boolean rho_squared = (bld->no_rho_approx &&
>                                   (bld->dims > 1)) || cube_rho;
>   
>            rho = lp_build_rho(bld, texture_unit, s, t, r, cube_rho, derivs);
> @@ -765,7 +767,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>             * Compute lod = log2(rho)
>             */
>   
> -         if (!lod_bias &&
> +         if (!lod_bias && !is_lodq &&
>                !bld->static_sampler_state->lod_bias_non_zero &&
>                !bld->static_sampler_state->apply_max_lod &&
>                !bld->static_sampler_state->apply_min_lod) {
> @@ -792,8 +794,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>                  return;
>               }
>               if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR &&
> -                !(gallivm_debug & GALLIVM_DEBUG_NO_BRILINEAR) &&
> -                !rho_squared) {
> +                !bld->no_brilinear && !rho_squared) {
>                  /*
>                   * This can't work if rho is squared. Not sure if it could be
>                   * fixed while keeping it worthwile, could also do sqrt here
> @@ -839,6 +840,10 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>            lod = LLVMBuildFAdd(builder, lod, sampler_lod_bias, "sampler_lod_bias");
>         }
>   
> +      if (is_lodq) {
> +         *out_lod = lod;
> +      }
> +
>         /* clamp lod */
>         if (bld->static_sampler_state->apply_max_lod) {
>            LLVMValueRef max_lod =
> @@ -856,13 +861,18 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>   
>            lod = lp_build_max(lodf_bld, lod, min_lod);
>         }
> +
> +      if (is_lodq) {
> +         *out_lod_fpart = lod;
> +         return;
> +      }
>      }
>   
>      *out_lod_positive = lp_build_cmp(lodf_bld, PIPE_FUNC_GREATER,
>                                       lod, lodf_bld->zero);
>   
>      if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
> -      if (!(gallivm_debug & GALLIVM_DEBUG_NO_BRILINEAR)) {
> +      if (!bld->no_brilinear) {
>            lp_build_brilinear_lod(lodf_bld, lod, BRILINEAR_FACTOR,
>                                   out_lod_ipart, out_lod_fpart);
>         }
> @@ -1679,9 +1689,7 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
>      maxasat = lp_build_max(coord_bld, as, at);
>      ar_ge_as_at = lp_build_cmp(coord_bld, PIPE_FUNC_GEQUAL, ar, maxasat);
>   
> -   if (need_derivs && (derivs_in ||
> -       ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
> -        (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX)))) {
> +   if (need_derivs && (derivs_in || (bld->no_quad_lod && bld->no_rho_approx))) {
>         /*
>          * XXX: This is really really complex.
>          * It is a bit overkill to use this for implicit derivatives as well,
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> index 9ec051a..c00997b 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h
> @@ -82,7 +82,8 @@ enum lp_sampler_lod_control {
>   enum lp_sampler_op_type {
>      LP_SAMPLER_OP_TEXTURE,
>      LP_SAMPLER_OP_FETCH,
> -   LP_SAMPLER_OP_GATHER
> +   LP_SAMPLER_OP_GATHER,
> +   LP_SAMPLER_OP_LODQ
>   };
>   
>   
> @@ -165,6 +166,7 @@ struct lp_static_sampler_state
>      unsigned normalized_coords:1;
>      unsigned min_max_lod_equal:1;  /**< min_lod == max_lod ? */
>      unsigned lod_bias_non_zero:1;
> +   unsigned max_lod_pos:1;
>      unsigned apply_min_lod:1;  /**< min_lod > 0 ? */
>      unsigned apply_max_lod:1;  /**< max_lod < last_level ? */
>      unsigned seamless_cube_map:1;
> @@ -321,6 +323,10 @@ struct lp_build_sample_context
>      /** number of lod values (valid are 1, length/4, length) */
>      unsigned num_lods;
>   
> +   boolean no_quad_lod;
> +   boolean no_brilinear;
> +   boolean no_rho_approx;
> +
>      /** regular scalar float type */
>      struct lp_type float_type;
>      struct lp_build_context float_bld;
> @@ -486,6 +492,7 @@ lp_sampler_static_texture_state(struct lp_static_texture_state *state,
>   
>   void
>   lp_build_lod_selector(struct lp_build_sample_context *bld,
> +                      boolean is_lodq,
>                         unsigned texture_index,
>                         unsigned sampler_index,
>                         LLVMValueRef s,
> @@ -496,6 +503,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
>                         LLVMValueRef lod_bias, /* optional */
>                         LLVMValueRef explicit_lod, /* optional */
>                         unsigned mip_filter,
> +                      LLVMValueRef *out_lod,
>                         LLVMValueRef *out_lod_ipart,
>                         LLVMValueRef *out_lod_fpart,
>                         LLVMValueRef *out_lod_positive);
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> index 1539849..b67a089 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
> @@ -1829,6 +1829,7 @@ lp_build_layer_coord(struct lp_build_sample_context *bld,
>    */
>   static void
>   lp_build_sample_common(struct lp_build_sample_context *bld,
> +                       boolean is_lodq,
>                          unsigned texture_index,
>                          unsigned sampler_index,
>                          LLVMValueRef *coords,
> @@ -1836,6 +1837,7 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
>                          LLVMValueRef lod_bias, /* optional */
>                          LLVMValueRef explicit_lod, /* optional */
>                          LLVMValueRef *lod_pos_or_zero,
> +                       LLVMValueRef *lod,
>                          LLVMValueRef *lod_fpart,
>                          LLVMValueRef *ilevel0,
>                          LLVMValueRef *ilevel1)
> @@ -1908,15 +1910,44 @@ lp_build_sample_common(struct lp_build_sample_context *bld,
>       * Compute the level of detail (float).
>       */
>      if (min_filter != mag_filter ||
> -       mip_filter != PIPE_TEX_MIPFILTER_NONE) {
> +       mip_filter != PIPE_TEX_MIPFILTER_NONE || is_lodq) {
>         /* Need to compute lod either to choose mipmap levels or to
>          * distinguish between minification/magnification with one mipmap level.
>          */
> -      lp_build_lod_selector(bld, texture_index, sampler_index,
> +      lp_build_lod_selector(bld, is_lodq, texture_index, sampler_index,
>                               coords[0], coords[1], coords[2], cube_rho,
>                               derivs, lod_bias, explicit_lod,
> -                            mip_filter,
> +                            mip_filter, lod,
>                               &lod_ipart, lod_fpart, lod_pos_or_zero);
> +      if (is_lodq) {
> +         LLVMValueRef last_level;
> +         last_level = bld->dynamic_state->last_level(bld->dynamic_state,
> +                                                     bld->gallivm,
> +                                                     bld->context_ptr,
> +                                                     texture_index);
> +         first_level = bld->dynamic_state->first_level(bld->dynamic_state,
> +                                                       bld->gallivm,
> +                                                       bld->context_ptr,
> +                                                       texture_index);
> +         last_level = lp_build_sub(&bld->int_bld, last_level, first_level);
> +         last_level = lp_build_int_to_float(&bld->float_bld, last_level);
> +         last_level = lp_build_broadcast_scalar(&bld->lodf_bld, last_level);
> +
> +         switch (mip_filter) {
> +         case PIPE_TEX_MIPFILTER_NONE:
> +            *lod_fpart = bld->lodf_bld.zero;
> +            break;
> +         case PIPE_TEX_MIPFILTER_NEAREST:
> +             *lod_fpart = lp_build_round(&bld->lodf_bld, *lod_fpart);
> +             /* fallthrough */
> +         case PIPE_TEX_MIPFILTER_LINEAR:
> +            *lod_fpart = lp_build_clamp(&bld->lodf_bld, *lod_fpart,
> +                                        bld->lodf_bld.zero, last_level);
> +            break;
> +         }
> +         return;
> +      }
> +
>      } else {
>         lod_ipart = bld->lodi_bld.zero;
>         *lod_pos_or_zero = bld->lodi_bld.zero;
> @@ -2522,7 +2553,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>      enum lp_sampler_op_type op_type;
>      LLVMValueRef lod_bias = NULL;
>      LLVMValueRef explicit_lod = NULL;
> -   boolean op_is_tex;
> +   boolean op_is_tex, op_is_lodq, op_is_gather;
>   
>      if (0) {
>         enum pipe_format fmt = static_texture_state->format;
> @@ -2537,6 +2568,8 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>                    LP_SAMPLER_OP_TYPE_SHIFT;
>   
>      op_is_tex = op_type == LP_SAMPLER_OP_TEXTURE;
> +   op_is_lodq = op_type == LP_SAMPLER_OP_LODQ;
> +   op_is_gather = op_type == LP_SAMPLER_OP_GATHER;
>   
>      if (lod_control == LP_SAMPLER_LOD_BIAS) {
>         lod_bias = lod;
> @@ -2582,6 +2615,16 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>      bld.format_desc = util_format_description(static_texture_state->format);
>      bld.dims = dims;
>   
> +   if (gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD || op_is_lodq) {
> +      bld.no_quad_lod = TRUE;
> +   }
> +   if (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX || op_is_lodq) {
> +      bld.no_rho_approx = TRUE;
> +   }
> +   if (gallivm_debug & GALLIVM_DEBUG_NO_BRILINEAR || op_is_lodq) {
> +      bld.no_brilinear = TRUE;
> +   }
> +
>      bld.vector_width = lp_type_width(type);
>   
>      bld.float_type = lp_type_float(32);
> @@ -2611,12 +2654,13 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>         bld.texel_type = lp_type_int_vec(type.width, type.width * type.length);
>      }
>   
> -   if (!static_texture_state->level_zero_only) {
> +   if (!static_texture_state->level_zero_only ||
> +       !static_sampler_state->max_lod_pos || op_is_lodq) {
>         derived_sampler_state.min_mip_filter = static_sampler_state->min_mip_filter;
>      } else {
>         derived_sampler_state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
>      }
> -   if (op_type == LP_SAMPLER_OP_GATHER) {
> +   if (op_is_gather) {
>         /*
>          * gather4 is exactly like GL_LINEAR filtering but in the end skipping
>          * the actual filtering. Using mostly the same paths, so cube face
> @@ -2677,11 +2721,11 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>       */
>      bld.num_mips = bld.num_lods = 1;
>   
> -   if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
> -       (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
> -       (static_texture_state->target == PIPE_TEXTURE_CUBE ||
> -        static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
> -       (op_is_tex && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
> +   if (bld.no_quad_lod && bld.no_rho_approx &&
> +       ((mip_filter != PIPE_TEX_MIPFILTER_NONE && op_is_tex &&
> +         (static_texture_state->target == PIPE_TEXTURE_CUBE ||
> +          static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY)) ||
> +        op_is_lodq)) {
>         /*
>          * special case for using per-pixel lod even for implicit lod,
>          * which is generally never required (ok by APIs) except to please
> @@ -2689,6 +2733,8 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>          * can cause derivatives to be different for pixels outside the primitive
>          * due to the major axis division even if pre-project derivatives are
>          * looking normal).
> +       * For lodq, we do it to simply avoid scalar pack / unpack (albeit for
> +       * cube maps we do indeed get per-pixel lod values).
>          */
>         bld.num_mips = type.length;
>         bld.num_lods = type.length;
> @@ -2802,6 +2848,32 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>         newcoords[i] = coords[i];
>      }
>   
> +   if (util_format_is_pure_integer(static_texture_state->format) &&
> +       !util_format_has_depth(bld.format_desc) && op_is_tex &&
> +       (static_sampler_state->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR ||
> +        static_sampler_state->min_img_filter == PIPE_TEX_FILTER_LINEAR ||
> +        static_sampler_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR)) {
> +      /*
> +       * Bail if impossible filtering is specified (the awkard additional
> +       * depth check is because it is legal in gallium to have things like S8Z24
> +       * here which would say it's pure int despite such formats should sample
> +       * the depth component).
> +       * In GL such filters make the texture incomplete, this makes it robust
> +       * against state trackers which set this up regardless (we'd crash in the
> +       * lerp later otherwise).
> +       * At least in some apis it may be legal to use such filters with lod
> +       * queries and/or gather (at least for gather d3d10 says only the wrap
> +       * bits are really used hence filter bits are likely simply ignored).
> +       * For fetch, we don't get valid samplers either way here.
> +       */
> +      unsigned chan;
> +      LLVMValueRef zero = lp_build_zero(gallivm, type);
> +      for (chan = 0; chan < 4; chan++) {
> +         texel_out[chan] = zero;
> +      }
> +      return;
> +   }
> +
>      if (0) {
>         /* For debug: no-op texture sampling */
>         lp_build_sample_nop(gallivm,
> @@ -2818,33 +2890,9 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>   
>      else {
>         LLVMValueRef lod_fpart = NULL, lod_positive = NULL;
> -      LLVMValueRef ilevel0 = NULL, ilevel1 = NULL;
> +      LLVMValueRef ilevel0 = NULL, ilevel1 = NULL, lod = NULL;
>         boolean use_aos;
>   
> -      if (util_format_is_pure_integer(static_texture_state->format) &&
> -          !util_format_has_depth(bld.format_desc) &&
> -          (static_sampler_state->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR ||
> -           static_sampler_state->min_img_filter == PIPE_TEX_FILTER_LINEAR ||
> -           static_sampler_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR)) {
> -         /*
> -          * Bail if impossible filtering is specified (the awkard additional
> -          * depth check is because it is legal in gallium to have things like S8Z24
> -          * here which would say it's pure int despite such formats should sample
> -          * the depth component).
> -          * In GL such filters make the texture incomplete, this makes it robust
> -          * against state trackers which set this up regardless (we'd crash in the
> -          * lerp later (except for gather)).
> -          * Must do this after fetch_texel code since with GL state tracker we'll
> -          * get some junk sampler for buffer textures.
> -          */
> -         unsigned chan;
> -         LLVMValueRef zero = lp_build_zero(gallivm, type);
> -         for (chan = 0; chan < 4; chan++) {
> -            texel_out[chan] = zero;
> -         }
> -         return;
> -      }
> -
>         use_aos = util_format_fits_8unorm(bld.format_desc) &&
>                   op_is_tex &&
>                   /* not sure this is strictly needed or simply impossible */
> @@ -2885,12 +2933,19 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>                         derived_sampler_state.wrap_r);
>         }
>   
> -      lp_build_sample_common(&bld, texture_index, sampler_index,
> +      lp_build_sample_common(&bld, op_is_lodq, texture_index, sampler_index,
>                                newcoords,
>                                derivs, lod_bias, explicit_lod,
> -                             &lod_positive, &lod_fpart,
> +                             &lod_positive, &lod, &lod_fpart,
>                                &ilevel0, &ilevel1);
>   
> +      if (op_is_lodq) {
> +         texel_out[0] = lod_fpart;
> +         texel_out[1] = lod;
> +         texel_out[2] = texel_out[3] = bld.coord_bld.zero;
> +         return;
> +      }
> +
>         if (use_aos && static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) {
>            /* The aos path doesn't do seamless filtering so simply add cube layer
>             * to face now.
> @@ -2937,6 +2992,9 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>   
>            /* Setup our build context */
>            memset(&bld4, 0, sizeof bld4);
> +         bld4.no_quad_lod = bld.no_quad_lod;
> +         bld4.no_rho_approx = bld.no_rho_approx;
> +         bld4.no_brilinear = bld.no_brilinear;
>            bld4.gallivm = bld.gallivm;
>            bld4.context_ptr = bld.context_ptr;
>            bld4.static_texture_state = bld.static_texture_state;
> @@ -2964,8 +3022,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
>            bld4.texel_type.length = 4;
>   
>            bld4.num_mips = bld4.num_lods = 1;
> -         if ((gallivm_debug & GALLIVM_DEBUG_NO_QUAD_LOD) &&
> -             (gallivm_debug & GALLIVM_DEBUG_NO_RHO_APPROX) &&
> +         if (bld4.no_quad_lod && bld4.no_rho_approx &&
>                (static_texture_state->target == PIPE_TEXTURE_CUBE ||
>                 static_texture_state->target == PIPE_TEXTURE_CUBE_ARRAY) &&
>                (op_is_tex && mip_filter != PIPE_TEX_MIPFILTER_NONE)) {
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index f16c579..3e47372 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -3146,6 +3146,18 @@ tg4_emit(
>   }
>   
>   static void
> +lodq_emit(
> +   const struct lp_build_tgsi_action * action,
> +   struct lp_build_tgsi_context * bld_base,
> +   struct lp_build_emit_data * emit_data)
> +{
> +   struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
> +
> +   emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE,
> +            emit_data->output, 1, LP_SAMPLER_OP_LODQ);
> +}
> +
> +static void
>   txq_emit(
>      const struct lp_build_tgsi_action * action,
>      struct lp_build_tgsi_context * bld_base,
> @@ -3875,6 +3887,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm,
>      bld.bld_base.op_actions[TGSI_OPCODE_TXB2].emit = txb2_emit;
>      bld.bld_base.op_actions[TGSI_OPCODE_TXL2].emit = txl2_emit;
>      bld.bld_base.op_actions[TGSI_OPCODE_TG4].emit = tg4_emit;
> +   bld.bld_base.op_actions[TGSI_OPCODE_LODQ].emit = lodq_emit;
>      /* DX10 sampling ops */
>      bld.bld_base.op_actions[TGSI_OPCODE_SAMPLE].emit = sample_emit;
>      bld.bld_base.op_actions[TGSI_OPCODE_SAMPLE_B].emit = sample_b_emit;
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
> index dba7ae3..fcad5da 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -252,7 +252,6 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>      case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
>         return 4;
>      case PIPE_CAP_TEXTURE_GATHER_SM5:
> -   case PIPE_CAP_TEXTURE_QUERY_LOD:
>      case PIPE_CAP_SAMPLE_SHADING:
>      case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
>         return 0;
> @@ -265,6 +264,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
>         return 1;
>      case PIPE_CAP_FAKE_SW_MSAA:
>         return 1;
> +   case PIPE_CAP_TEXTURE_QUERY_LOD:
>      case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
>      case PIPE_CAP_TGSI_ARRAY_COMPONENTS:
>      case PIPE_CAP_DOUBLES:
> 

LGTM.

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>


More information about the mesa-dev mailing list