brw: Use nir_texop_resinfo_intel for query_levels and txs
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

This eliminates the need to special case query_levels.

Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40451>
This commit is contained in:
Kenneth Graunke 2026-03-14 03:08:01 -07:00 committed by Marge Bot
parent 0e143ae663
commit ca3cabd2f8
5 changed files with 50 additions and 35 deletions

View file

@ -6529,7 +6529,7 @@ brw_from_nir_emit_texture(nir_to_brw_state &ntb,
const unsigned dest_size = nir_tex_instr_dest_size(instr);
unsigned dest_comp;
if (instr->op != nir_texop_tg4 && instr->op != nir_texop_query_levels) {
if (instr->op != nir_texop_tg4) {
unsigned write_mask = nir_def_components_read(&instr->def);
assert(write_mask != 0); /* dead code should have been eliminated */
@ -6600,8 +6600,7 @@ brw_from_nir_emit_texture(nir_to_brw_state &ntb,
*/
const bool non_aligned_component_stride =
(brw_type_size_bytes(dst_type) * bld.dispatch_width()) % grf_size != 0;
if (instr->op != nir_texop_query_levels && !instr->is_sparse &&
!non_aligned_component_stride) {
if (!instr->is_sparse && !non_aligned_component_stride) {
/* In most cases we can write directly to the result. */
tex->dst = nir_def_reg;
} else {
@ -6615,26 +6614,6 @@ brw_from_nir_emit_texture(nir_to_brw_state &ntb,
for (unsigned i = dest_comp; i < dest_size; i++)
nir_dest[i].type = dst.type;
if (instr->op == nir_texop_query_levels) {
/* # levels is in .w */
if (devinfo->ver == 9) {
/**
* Wa_1940217:
*
* When a surface of type SURFTYPE_NULL is accessed by resinfo, the
* MIPCount returned is undefined instead of 0.
*/
brw_inst *mov = bld.MOV(bld.null_reg_d(), dst);
mov->conditional_mod = BRW_CONDITIONAL_NZ;
nir_dest[0] = bld.vgrf(BRW_TYPE_D);
brw_inst *sel =
bld.SEL(nir_dest[0], offset(dst, bld, 3), brw_imm_d(0));
sel->predicate = BRW_PREDICATE_NORMAL;
} else {
nir_dest[0] = offset(dst, bld, 3);
}
}
/* The residency bits are only in the first component. */
if (instr->is_sparse) {
nir_dest[dest_size - 1] =

View file

@ -2716,7 +2716,7 @@ brw_postprocess_nir_opts(brw_pass_tracker *pt,
OPT(nir_opt_constant_folding);
/* Needs to happen before the backend opcode selection */
OPT(brw_nir_pre_lower_texture);
OPT(brw_nir_pre_lower_texture, devinfo);
/* Needs to happen before the texture lowering */
OPT(brw_nir_texture_backend_opcode, devinfo);

View file

@ -262,7 +262,8 @@ bool brw_nir_lower_mcs_fetch(nir_shader *shader,
bool brw_nir_texture_backend_opcode(nir_shader *shader,
const struct intel_device_info *devinfo);
bool brw_nir_pre_lower_texture(nir_shader *nir);
bool brw_nir_pre_lower_texture(nir_shader *nir,
const struct intel_device_info *devinfo);
bool brw_nir_lower_texture(nir_shader *nir);

View file

@ -18,9 +18,40 @@
* to sample_po_c_l instead.
*/
static bool
pre_lower_tex_instr(nir_builder *b, nir_tex_instr *tex)
pre_lower_tex_instr(nir_builder *b, nir_tex_instr *tex,
const struct intel_device_info *devinfo)
{
switch (tex->op) {
case nir_texop_txs: {
unsigned mask = nir_component_mask(tex->def.num_components);
tex->op = nir_texop_resinfo_intel;
tex->def.num_components = 4;
b->cursor = nir_after_instr(&tex->instr);
nir_def_rewrite_uses_after(&tex->def, nir_channels(b, &tex->def, mask));
return true;
}
case nir_texop_query_levels: {
tex->op = nir_texop_resinfo_intel;
tex->def.num_components = 4;
b->cursor = nir_after_instr(&tex->instr);
nir_def *level = nir_channel(b, &tex->def, 3);
if (devinfo->ver == 9) {
/* Wa_1940217:
*
* When a surface of type SURFTYPE_NULL is accessed by resinfo,
* the MIPCount returned is undefined instead of 0.
*/
nir_def *width_nonzero = nir_i2b(b, nir_channel(b, &tex->def, 0));
level = nir_bcsel(b, width_nonzero, level, nir_imm_int(b, 0));
}
nir_def_rewrite_uses_after(&tex->def, level);
return true;
}
case nir_texop_txb: {
int bias_index = nir_tex_instr_src_index(tex, nir_tex_src_bias);
assert(bias_index != -1);
@ -96,10 +127,14 @@ pre_lower_intrinsic_instr(nir_builder *b, nir_intrinsic_instr *intrin)
bool bindless = rsrc && (nir_intrinsic_resource_access_intel(rsrc) &
nir_resource_intel_bindless);
nir_def *txs = nir_txs(b, .lod = nir_imm_int(b, 0),
.dim = dim, .is_array = is_array,
.texture_offset = bindless ? NULL : surface->ssa,
.texture_handle = bindless ? surface->ssa : NULL);
nir_def *resinfo =
nir_build_tex(b, nir_texop_resinfo_intel,
.lod = nir_imm_int(b, 0),
.dim = dim, .is_array = is_array,
.texture_offset = bindless ? NULL : surface->ssa,
.texture_handle = bindless ? surface->ssa : NULL);
nir_def *txs =
nir_channels(b, resinfo, nir_component_mask(intrin->def.num_components));
/* SKL PRM, vol07, 3D Media GPGPU Engine, Bounds Checking and Faulting:
*
@ -133,7 +168,7 @@ pre_lower_texture_instr(nir_builder *b, nir_instr *instr, void *data)
{
switch (instr->type) {
case nir_instr_type_tex:
return pre_lower_tex_instr(b, nir_instr_as_tex(instr));
return pre_lower_tex_instr(b, nir_instr_as_tex(instr), data);
case nir_instr_type_intrinsic:
return pre_lower_intrinsic_instr(b, nir_instr_as_intrinsic(instr));
@ -144,12 +179,13 @@ pre_lower_texture_instr(nir_builder *b, nir_instr *instr, void *data)
}
bool
brw_nir_pre_lower_texture(nir_shader *shader)
brw_nir_pre_lower_texture(nir_shader *shader,
const struct intel_device_info *devinfo)
{
return nir_shader_instructions_pass(shader,
pre_lower_texture_instr,
nir_metadata_control_flow,
NULL);
(void*) devinfo);
}
/**

View file

@ -790,10 +790,9 @@ brw_get_sampler_opcode_from_tex(const struct intel_device_info *devinfo,
/* Deal with some corner cases first */
switch (tex->op) {
case nir_texop_lod: return BRW_SAMPLER_OPCODE_LOD;
case nir_texop_query_levels: return BRW_SAMPLER_OPCODE_RESINFO;
case nir_texop_texture_samples: return BRW_SAMPLER_OPCODE_SAMPLEINFO;
case nir_texop_txf_ms_mcs_intel: return BRW_SAMPLER_OPCODE_LD_MCS;
case nir_texop_txs: return BRW_SAMPLER_OPCODE_RESINFO;
case nir_texop_resinfo_intel: return BRW_SAMPLER_OPCODE_RESINFO;
default: break;
}