[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