diff --git a/src/intel/compiler/brw/brw_from_nir.cpp b/src/intel/compiler/brw/brw_from_nir.cpp index 9477a468a1b..e14e127da03 100644 --- a/src/intel/compiler/brw/brw_from_nir.cpp +++ b/src/intel/compiler/brw/brw_from_nir.cpp @@ -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] = diff --git a/src/intel/compiler/brw/brw_nir.c b/src/intel/compiler/brw/brw_nir.c index b6b52e3ffd2..9d3e8591172 100644 --- a/src/intel/compiler/brw/brw_nir.c +++ b/src/intel/compiler/brw/brw_nir.c @@ -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); diff --git a/src/intel/compiler/brw/brw_nir.h b/src/intel/compiler/brw/brw_nir.h index 588a88a2cf8..c4b45e565ae 100644 --- a/src/intel/compiler/brw/brw_nir.h +++ b/src/intel/compiler/brw/brw_nir.h @@ -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); diff --git a/src/intel/compiler/brw/brw_nir_lower_texture.c b/src/intel/compiler/brw/brw_nir_lower_texture.c index 6adeb5451b5..36e566b00b6 100644 --- a/src/intel/compiler/brw/brw_nir_lower_texture.c +++ b/src/intel/compiler/brw/brw_nir_lower_texture.c @@ -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); } /** diff --git a/src/intel/compiler/brw/brw_sampler.c b/src/intel/compiler/brw/brw_sampler.c index 326a34b24c5..309a2702122 100644 --- a/src/intel/compiler/brw/brw_sampler.c +++ b/src/intel/compiler/brw/brw_sampler.c @@ -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; }