nak: Implement load_ubo with an indirect cbuf index

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28474>
This commit is contained in:
Faith Ekstrand 2024-03-29 11:24:21 -05:00 committed by Marge Bot
parent f4ac517cc8
commit b5f4b16811
2 changed files with 31 additions and 4 deletions

View file

@ -488,7 +488,15 @@ impl SM50Instr {
self.set_reg_src(8..16, op.offset);
self.set_field(20..36, cb.offset);
self.set_field(36..41, cb_idx);
self.set_field(44..46, 0_u8); // TODO: subop
self.set_field(
44..46,
match op.mode {
LdcMode::Indexed => 0_u8,
LdcMode::IndexedLinear => 1_u8,
LdcMode::IndexedSegmented => 2_u8,
LdcMode::IndexedSegmentedLinear => 3_u8,
},
);
self.set_mem_type(48..51, op.mem_type);
}

View file

@ -2474,7 +2474,7 @@ impl<'a> ShaderFromNir<'a> {
nir_intrinsic_load_ubo => {
let size_B =
(intrin.def.bit_size() / 8) * intrin.def.num_components();
let idx = srcs[0];
let idx = &srcs[0];
let (off, off_imm) = self.get_io_addr_offset(&srcs[1], 16);
let (off, off_imm) =
@ -2507,8 +2507,27 @@ impl<'a> ShaderFromNir<'a> {
});
}
} else {
panic!("Indirect UBO indices not yet supported");
// In the IndexedSegmented mode, the hardware computes the
// actual index and offset as follows:
//
// idx = imm_idx + reg[31:16]
// offset = imm_offset + reg[15:0]
// ldc c[idx][offset]
//
// So pack the index and offset accordingly
let idx = self.get_src(idx);
let off_idx = b.prmt(off, idx, [0, 1, 4, 5]);
let cb = CBufRef {
buf: CBuf::Binding(0),
offset: off_imm,
};
b.push_op(OpLdc {
dst: dst.into(),
cb: cb.into(),
offset: off_idx.into(),
mode: LdcMode::IndexedSegmented,
mem_type: MemType::from_size(size_B, false),
});
}
self.set_dst(&intrin.def, dst);
}