- Temp first_layer =
- bld.vop3(aco_opcode::v_bfe_u32, bld.def(v1), rsrc_word5,
- Operand::c32(0u), Operand::c32(13u));
+ Temp first_layer = bld.vop3(aco_opcode::v_bfe_u32, bld.def(v1), rsrc_word5, Operand::c32(0u),
+ Operand::c32(13u));
+
+ if (has_lod) {
+ /* If there's a lod parameter it matter if the image is 3d or 2d because
+ * the hw reads either the fourth or third component as lod. So detect
+ * 3d images and place the lod at the third component otherwise.
+ * For non 3D descriptors we effectively add lod twice to coords,
+ * but the hw will only read the first one, the second is ignored.
+ */
+ Temp rsrc_word3 = emit_extract_vector(ctx, rsrc, 3, s1);
+ Temp type = bld.sop2(aco_opcode::s_bfe_u32, bld.def(s1), bld.def(s1, scc), rsrc_word3,
+ Operand::c32(28 | (4 << 16))); /* extract last 4 bits */
+ Temp is_3d = bld.vopc_e64(aco_opcode::v_cmp_eq_u32, bld.def(bld.lm), type,
+ Operand::c32(V_008F1C_SQ_RSRC_IMG_3D));
+ first_layer =
+ bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1), as_vgpr(ctx, lod), first_layer, is_3d);
+ }
+