From a8b104d9bd83f050c26adb88985f5c546a413787 Mon Sep 17 00:00:00 2001 From: Konstantin Seurer Date: Thu, 30 Jan 2025 18:24:59 +0100 Subject: [PATCH] llvmpipe: Handle nir_tex_src_min_lod Reviewed-by: Mike Blumenkrantz Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_jit_sample.c | 2 ++ src/gallium/auxiliary/gallivm/lp_bld_jit_types.c | 3 +++ src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c | 8 ++++++++ src/gallium/auxiliary/gallivm/lp_bld_sample.c | 10 +++++++--- src/gallium/auxiliary/gallivm/lp_bld_sample.h | 6 +++++- src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c | 8 ++++++-- src/gallium/drivers/llvmpipe/lp_texture_handle.c | 6 +++++- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_jit_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_jit_sample.c index f3e4fa3f22e..22093e9d512 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_jit_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_jit_sample.c @@ -254,6 +254,8 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base enum lp_sampler_lod_control lod_control = (params->sample_key & LP_SAMPLER_LOD_CONTROL_MASK) >> LP_SAMPLER_LOD_CONTROL_SHIFT; if (lod_control == LP_SAMPLER_LOD_BIAS || lod_control == LP_SAMPLER_LOD_EXPLICIT) args[num_args++] = params->lod; + if (params->sample_key & LP_SAMPLER_MIN_LOD) + args[num_args++] = params->min_lod; if (params->type.length != lp_native_vector_width / 32) for (uint32_t i = 0; i < num_args; i++) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c b/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c index 5a82d586172..7fb81b8d85f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c @@ -807,6 +807,9 @@ lp_build_sample_function_type(struct gallivm_state *gallivm, uint32_t sample_key if (lod_control == LP_SAMPLER_LOD_BIAS || lod_control == LP_SAMPLER_LOD_EXPLICIT) arg_types[num_params++] = coord_type; + if (sample_key & LP_SAMPLER_MIN_LOD) + arg_types[num_params++] = coord_type; + val_type[0] = val_type[1] = val_type[2] = val_type[3] = lp_build_vec_type(gallivm, type); val_type[4] = lp_build_int_vec_type(gallivm, type); ret_type = LLVMStructTypeInContext(gallivm->context, val_type, 5, 0); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 6b1df034a87..4d821431be9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -5273,6 +5273,11 @@ lp_build_nir_sample_key(gl_shader_stage stage, nir_tex_instr *instr) explicit_lod = true; lod_src = i; break; + case nir_tex_src_min_lod: + sample_key |= LP_SAMPLER_MIN_LOD; + explicit_lod = true; + lod_src = i; + break; case nir_tex_src_offset: sample_key |= LP_SAMPLER_OFFSETS; break; @@ -5364,6 +5369,9 @@ visit_tex(struct lp_build_nir_soa_context *bld, nir_tex_instr *instr) else explicit_lod = cast_type(bld, get_src(bld, &instr->src[i].src, 0), nir_type_float, 32); break; + case nir_tex_src_min_lod: + params.min_lod = cast_type(bld, get_src(bld, &instr->src[i].src, 0), nir_type_float, 32); + break; case nir_tex_src_ddx: { int deriv_cnt = instr->coord_components; if (instr->is_array) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 81df86e99e5..80384e39dd2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -827,6 +827,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, const struct lp_derivatives *derivs, LLVMValueRef lod_bias, /* optional */ LLVMValueRef explicit_lod, /* optional */ + LLVMValueRef min_lod, /* optional */ enum pipe_tex_mipfilter mip_filter, LLVMValueRef *out_lod, LLVMValueRef *out_lod_ipart, @@ -992,14 +993,17 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, lod = lp_build_min(lodf_bld, lod, max_lod); } if (bld->static_sampler_state->apply_min_lod) { - LLVMValueRef min_lod = + LLVMValueRef desc_min_lod = dynamic_state->min_lod(bld->gallivm, bld->resources_type, bld->resources_ptr, sampler_unit); - min_lod = lp_build_broadcast_scalar(lodf_bld, min_lod); + desc_min_lod = lp_build_broadcast_scalar(lodf_bld, desc_min_lod); - lod = lp_build_max(lodf_bld, lod, min_lod); + lod = lp_build_max(lodf_bld, lod, desc_min_lod); } + if (min_lod) + lod = lp_build_max(lodf_bld, lod, min_lod); + if (is_lodq) { *out_lod_fpart = lod; return; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.h b/src/gallium/auxiliary/gallivm/lp_bld_sample.h index f21b7359942..b37cbb56ded 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.h @@ -99,7 +99,8 @@ enum lp_sampler_op_type { #define LP_SAMPLER_GATHER_COMP_MASK (3 << 8) #define LP_SAMPLER_FETCH_MS (1 << 10) #define LP_SAMPLER_RESIDENCY (1 << 11) -#define LP_SAMPLE_KEY_COUNT (1 << 12) +#define LP_SAMPLER_MIN_LOD (1 << 12) +#define LP_SAMPLE_KEY_COUNT (1 << 13) /* Parameters used to handle TEX instructions */ @@ -118,6 +119,7 @@ struct lp_sampler_params const LLVMValueRef *offsets; LLVMValueRef ms_index; LLVMValueRef lod; + LLVMValueRef min_lod; const struct lp_derivatives *derivs; LLVMValueRef *texel; @@ -666,6 +668,7 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, const struct lp_derivatives *derivs, LLVMValueRef lod_bias, /* optional */ LLVMValueRef explicit_lod, /* optional */ + LLVMValueRef min_lod, /* optional */ enum pipe_tex_mipfilter mip_filter, LLVMValueRef *out_lod, LLVMValueRef *out_lod_ipart, @@ -811,6 +814,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm, const LLVMValueRef *offsets, const struct lp_derivatives *derivs, /* optional */ LLVMValueRef lod, /* optional */ + LLVMValueRef min_lod, /* optional */ LLVMValueRef ms_index, /* optional */ LLVMValueRef *texel_out); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index b6991092cad..c82f5a3e611 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -2354,6 +2354,7 @@ lp_build_sample_common(struct lp_build_sample_context *bld, const struct lp_derivatives *derivs, /* optional */ LLVMValueRef lod_bias, /* optional */ LLVMValueRef explicit_lod, /* optional */ + LLVMValueRef min_lod, /* optional */ LLVMValueRef *lod_pos_or_zero, LLVMValueRef *lod, LLVMValueRef *lod_fpart, @@ -2455,7 +2456,7 @@ lp_build_sample_common(struct lp_build_sample_context *bld, first_level_vec, coords[0], coords[1], coords[2], derivs, lod_bias, explicit_lod, - mip_filter, lod, + min_lod, mip_filter, lod, &lod_ipart, lod_fpart, lod_pos_or_zero, aniso_values); if (is_lodq) { @@ -3162,6 +3163,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm, const LLVMValueRef *offsets, const struct lp_derivatives *derivs, /* optional */ LLVMValueRef lod, /* optional */ + LLVMValueRef min_lod, /* optional */ LLVMValueRef ms_index, /* optional */ LLVMValueRef *texel_out) { @@ -3611,7 +3613,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm, lp_build_sample_common(&bld, op_is_lodq, texture_index, sampler_index, newcoords, derivs, lod_bias, explicit_lod, - &lod_positive, &lod, &lod_fpart, + min_lod, &lod_positive, &lod, &lod_fpart, &ilevel0, &ilevel1, &aniso_values); if (op_is_lodq) { @@ -3987,6 +3989,7 @@ lp_build_sample_gen_func(struct gallivm_state *gallivm, offsets, deriv_ptr, lod, + NULL, ms_index, texel_out); @@ -4251,6 +4254,7 @@ lp_build_sample_soa(const struct lp_static_texture_state *static_texture_state, params->offsets, params->derivs, params->lod, + NULL, params->ms_index, params->texel); } diff --git a/src/gallium/drivers/llvmpipe/lp_texture_handle.c b/src/gallium/drivers/llvmpipe/lp_texture_handle.c index a7980da5ba8..cd41557c5ae 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture_handle.c +++ b/src/gallium/drivers/llvmpipe/lp_texture_handle.c @@ -536,6 +536,10 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s if (lod_control == LP_SAMPLER_LOD_BIAS || lod_control == LP_SAMPLER_LOD_EXPLICIT) lod = LLVMGetParam(function, arg_index++); + LLVMValueRef min_lod = NULL; + if (sample_key & LP_SAMPLER_MIN_LOD) + min_lod = LLVMGetParam(function, arg_index++); + LLVMBuilderRef old_builder = gallivm->builder; LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, function, "entry"); gallivm->builder = LLVMCreateBuilderInContext(gallivm->context); @@ -545,7 +549,7 @@ compile_sample_function(struct llvmpipe_context *ctx, struct lp_static_texture_s if (supported) { lp_build_sample_soa_code(gallivm, texture, sampler, lp_build_sampler_soa_dynamic_state(sampler_soa), type, sample_key, 0, 0, cs.jit_resources_type, NULL, cs.jit_cs_thread_data_type, - NULL, coords, offsets, NULL, lod, ms_index, texel_out); + NULL, coords, offsets, NULL, lod, min_lod, ms_index, texel_out); } else { lp_build_sample_nop(gallivm, lp_build_texel_type(type, util_format_description(texture->format)), coords, texel_out); }