Merge branch 'pan-texture_query_lod' into 'main'

panfrost: enable ARB_texture_query_lod on v9+

Closes #14867

See merge request mesa/mesa!34339
This commit is contained in:
Erik Faye-Lund 2026-05-08 02:10:30 +02:00
commit cf784a0f3d
8 changed files with 54 additions and 21 deletions

View file

@ -135,7 +135,7 @@ GL 4.0, GLSL 4.00 --- all DONE: freedreno/a6xx, nvc0, r600, radeonsi, llvmpipe,
GL_ARB_texture_buffer_object_rgb32 DONE (freedreno, softpipe, panfrost, crocus/gen6+)
GL_ARB_texture_cube_map_array DONE (freedreno/a4xx+, nv50, softpipe, v3d, panfrost, crocus/gen6+)
GL_ARB_texture_gather DONE (freedreno, nv50, softpipe, v3d, panfrost)
GL_ARB_texture_query_lod DONE (freedreno, nv50, softpipe, v3d, panfrost, crocus/gen5+)
GL_ARB_texture_query_lod DONE (freedreno, nv50, softpipe, v3d, panfrost/v9+, crocus/gen5+)
GL_ARB_transform_feedback2 DONE (freedreno/a3xx+, nv50, softpipe, v3d, panfrost, crocus/gen6+)
GL_ARB_transform_feedback3 DONE (freedreno/a3xx+, softpipe, panfrost)

View file

@ -10,3 +10,4 @@ shaderImageGatherExtended on pvr
static C++ stdlib required on rusticl to workaround applications using their own C++ stdlib
VK_EXT_pipeline_protected_access on RADV
VK_EXT_extended_dynamic_state3 on panvk
GL_ARB_texture_query_lod on panfrost/v9+

View file

@ -690,6 +690,7 @@ panfrost_init_screen_caps(struct panfrost_screen *screen)
caps->depth_clip_disable = true;
caps->mixed_framebuffer_sizes = true;
caps->frontend_noop = true;
caps->texture_query_lod = dev->arch >= 9;
caps->sample_shading = dev->arch >= 6;
caps->fragment_shader_derivatives = true;
caps->framebuffer_no_attachment = true;

View file

@ -62,6 +62,7 @@ GL_EXT_texture_filter_anisotropic
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_mirror_clamp_to_edge
GL_EXT_texture_norm16
GL_EXT_texture_query_lod
GL_EXT_texture_rg
GL_EXT_texture_sRGB_decode
GL_EXT_texture_sRGB_R8

View file

@ -62,6 +62,7 @@ GL_EXT_texture_filter_anisotropic
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_mirror_clamp_to_edge
GL_EXT_texture_norm16
GL_EXT_texture_query_lod
GL_EXT_texture_rg
GL_EXT_texture_sRGB_decode
GL_EXT_texture_sRGB_R8

View file

@ -79,6 +79,10 @@ bi_instr_uses_helpers(bi_instr *I)
case BI_OPCODE_TEX_SINGLE:
return (I->va_lod_mode == BI_VA_LOD_MODE_COMPUTED_LOD) ||
(I->va_lod_mode == BI_VA_LOD_MODE_COMPUTED_BIAS);
case BI_OPCODE_TEX_GRADIENT:
/* If we don't use derivatives to compute the lod we need disabled lanes
* to have valid texture coordinates. */
return !I->derivative_enable;
case BI_OPCODE_WMASK:
/* Helpers are needed to implement voting in fragment shaders. */
return true;

View file

@ -1043,8 +1043,11 @@ va_pack_instr(const bi_instr *I, unsigned arch)
hex |= (1ull << 46);
if (I->op == BI_OPCODE_TEX_GRADIENT) {
if (I->force_delta_enable)
if (I->force_delta_enable) {
if (arch < 10)
invalid_instruction(I, "gradient instruction does not support .force_delta_enable");
hex |= (1ull << 12);
}
if (I->lod_bias_disable)
hex |= (1ull << 13);
if (I->lod_clamp_disable)

View file

@ -983,7 +983,8 @@ va_lower_lod(nir_builder *b, nir_tex_instr *tex, uint64_t gpu_id)
struct pan_va_tex_flags flags = {
.wide_indices = tex_h->num_components > 1,
.derivative_enable = false,
.force_delta_enable = true,
.force_delta_enable = false,
.lod_clamp_disable = true,
};
tex_h = nir_pad_vector_imm_int(b, tex_h, 0, 2);
@ -992,29 +993,50 @@ va_lower_lod(nir_builder *b, nir_tex_instr *tex, uint64_t gpu_id)
if (tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
coord = build_cube_desc(b, coord);
nir_def *comps[2];
for (unsigned i = 0; i < 2; i++) {
flags.lod_clamp_disable = i != 0;
nir_def *grdesc = nir_build_tex(b, nir_texop_gradient_pan,
.dim = tex->sampler_dim,
.dest_type = nir_type_int32,
.backend_flags = PAN_AS_U32(flags),
.texture_handle = tex_h,
.backend1 = coord);
nir_def *grdesc = nir_build_tex(b, nir_texop_gradient_pan,
.dim = tex->sampler_dim,
.dest_type = nir_type_int32,
.backend_flags = PAN_AS_U32(flags),
.texture_handle = tex_h,
.backend1 = coord);
nir_def *lod_i16 = nir_unpack_32_2x16_split_x(b, grdesc);
nir_def *lod_i16 = nir_unpack_32_2x16_split_x(b, grdesc);
assert(tex->dest_type == nir_type_float32);
nir_def *lod = nir_i2f32(b, lod_i16);
assert(tex->dest_type == nir_type_float32);
nir_def *lambda_prime = nir_fdiv_imm(b, nir_i2f32(b, lod_i16), 256.0);
lod = nir_fdiv_imm(b, lod, 256.0);
if (i == 0)
lod = nir_fround_even(b, lod);
nir_def *samp = pan_nir_load_va_desc(b, 2, 32, srcs.samp_h, 0);
nir_def *samp_w0 = nir_channel(b, samp, 0);
nir_def *samp_w1 = nir_channel(b, samp, 1);
comps[i] = lod;
}
/* decode min/max lod from descriptor */
nir_def *min_lod = nir_ubitfield_extract_imm(b, samp_w1, 0, 13);
nir_def *max_lod = nir_ubitfield_extract_imm(b, samp_w1, 16, 13);
min_lod = nir_fdiv_imm(b, nir_u2f32(b, min_lod), 256.0);
max_lod = nir_fdiv_imm(b, nir_u2f32(b, max_lod), 256.0);
nir_def_replace(&tex->def, nir_vec2(b, comps[0], comps[1]));
/* clamp max_lod to actual number of levels */
nir_def *levels = pan_nir_load_va_tex_levels(b, srcs.tex_h);
levels = nir_u2f32(b, nir_iadd_imm(b, levels, -1));
max_lod = nir_fmin(b, max_lod, levels);
/* clamp res.x to [min_lod, max_lod] range */
nir_def *lod = nir_fclamp(b, lambda_prime, min_lod, max_lod);
/* decode mipmap mode from descriptor */
nir_def *mipmap_mode = nir_ubitfield_extract_imm(b, samp_w0, 30, 2);
/* adjust lod.x for MALI_MIPMAP_MODE_NONE */
lod = nir_bcsel(b, nir_ieq_imm(b, mipmap_mode, 1 /* MALI_MIPMAP_MODE_NONE */),
nir_imm_zero(b, 1, 32), lod);
/* adjust lod.x for MALI_MIPMAP_MODE_NEAREST */
nir_def *nearest_lod =
nir_fadd_imm(b, nir_fceil(b, nir_fadd_imm(b, lod, 0.5)), -1.0);
lod = nir_bcsel(b, nir_ieq_imm(b, mipmap_mode, 0 /* MALI_MIPMAP_MODE_NEAREST */),
nearest_lod, lod);
nir_def_replace(&tex->def, nir_vec2(b, lod, lambda_prime));
return true;
}