nak: Add support for bound and cbuf textures

Reviewed-by: Mel Henning <drawoc@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27755>
This commit is contained in:
Faith Ekstrand 2024-02-22 13:06:36 -06:00 committed by Marge Bot
parent 16b6ea415f
commit 272e8ec461
4 changed files with 227 additions and 40 deletions

View file

@ -1774,6 +1774,7 @@ impl<'a> ShaderFromNir<'a> {
assert!(fault.is_none());
b.push_op(OpTxq {
dsts: dsts,
tex: TexRef::Bindless,
src: src,
query: TexQuery::Dimension,
mask: mask,
@ -1783,6 +1784,7 @@ impl<'a> ShaderFromNir<'a> {
assert!(fault.is_none());
b.push_op(OpTxq {
dsts: dsts,
tex: TexRef::Bindless,
src: src,
query: TexQuery::TextureType,
mask: mask,
@ -1814,6 +1816,7 @@ impl<'a> ShaderFromNir<'a> {
b.push_op(OpTxd {
dsts: dsts,
fault,
tex: TexRef::Bindless,
srcs: srcs,
dim: dim,
offset: offset_mode == Tld4OffsetMode::AddOffI,
@ -1823,6 +1826,7 @@ impl<'a> ShaderFromNir<'a> {
assert!(offset_mode == Tld4OffsetMode::None);
b.push_op(OpTmml {
dsts: dsts,
tex: TexRef::Bindless,
srcs: srcs,
dim: dim,
mask: mask,
@ -1832,6 +1836,7 @@ impl<'a> ShaderFromNir<'a> {
b.push_op(OpTld {
dsts: dsts,
fault,
tex: TexRef::Bindless,
srcs: srcs,
dim: dim,
lod_mode: lod_mode,
@ -1843,6 +1848,7 @@ impl<'a> ShaderFromNir<'a> {
b.push_op(OpTld4 {
dsts: dsts,
fault,
tex: TexRef::Bindless,
srcs: srcs,
dim: dim,
comp: tex.component().try_into().unwrap(),
@ -1855,6 +1861,7 @@ impl<'a> ShaderFromNir<'a> {
b.push_op(OpTex {
dsts: dsts,
fault,
tex: TexRef::Bindless,
srcs: srcs,
dim: dim,
lod_mode: lod_mode,

View file

@ -2034,6 +2034,32 @@ impl fmt::Display for FRndMode {
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub struct TexCBufRef {
pub idx: u8,
pub offset: u16,
}
#[allow(dead_code)]
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum TexRef {
Bound(u16),
CBuf(TexCBufRef),
Bindless,
}
impl fmt::Display for TexRef {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TexRef::Bound(idx) => write!(f, "tex[{idx}]"),
TexRef::CBuf(TexCBufRef { idx, offset }) => {
write!(f, "c[{idx:#x}][{offset:#x}]")
}
TexRef::Bindless => write!(f, "bindless"),
}
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum TexDim {
_1D,
@ -4636,6 +4662,8 @@ pub struct OpTex {
pub dsts: [Dst; 2],
pub fault: Dst,
pub tex: TexRef,
#[src_type(SSA)]
pub srcs: [Src; 2],
@ -4648,7 +4676,7 @@ pub struct OpTex {
impl DisplayOp for OpTex {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "tex.b{}", self.dim)?;
write!(f, "tex{}", self.dim)?;
if self.lod_mode != TexLodMode::Auto {
write!(f, ".{}", self.lod_mode)?;
}
@ -4658,7 +4686,7 @@ impl DisplayOp for OpTex {
if self.z_cmpr {
write!(f, ".dc")?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])
write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1])
}
}
impl_display_for_op!(OpTex);
@ -4669,6 +4697,8 @@ pub struct OpTld {
pub dsts: [Dst; 2],
pub fault: Dst,
pub tex: TexRef,
#[src_type(SSA)]
pub srcs: [Src; 2],
@ -4681,7 +4711,7 @@ pub struct OpTld {
impl DisplayOp for OpTld {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "tld.b{}", self.dim)?;
write!(f, "tld{}", self.dim)?;
if self.lod_mode != TexLodMode::Auto {
write!(f, ".{}", self.lod_mode)?;
}
@ -4691,7 +4721,7 @@ impl DisplayOp for OpTld {
if self.is_ms {
write!(f, ".ms")?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])
write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1])
}
}
impl_display_for_op!(OpTld);
@ -4702,6 +4732,8 @@ pub struct OpTld4 {
pub dsts: [Dst; 2],
pub fault: Dst,
pub tex: TexRef,
#[src_type(SSA)]
pub srcs: [Src; 2],
@ -4714,11 +4746,11 @@ pub struct OpTld4 {
impl DisplayOp for OpTld4 {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "tld4.g.b{}", self.dim)?;
write!(f, "tld4.g{}", self.dim)?;
if self.offset_mode != Tld4OffsetMode::None {
write!(f, ".{}", self.offset_mode)?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])
write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1])
}
}
impl_display_for_op!(OpTld4);
@ -4728,6 +4760,8 @@ impl_display_for_op!(OpTld4);
pub struct OpTmml {
pub dsts: [Dst; 2],
pub tex: TexRef,
#[src_type(SSA)]
pub srcs: [Src; 2],
@ -4739,8 +4773,8 @@ impl DisplayOp for OpTmml {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"tmml.b.lod{} {} {}",
self.dim, self.srcs[0], self.srcs[1]
"tmml.lod{} {} {} {}",
self.dim, self.tex, self.srcs[0], self.srcs[1]
)
}
}
@ -4752,6 +4786,8 @@ pub struct OpTxd {
pub dsts: [Dst; 2],
pub fault: Dst,
pub tex: TexRef,
#[src_type(SSA)]
pub srcs: [Src; 2],
@ -4762,11 +4798,11 @@ pub struct OpTxd {
impl DisplayOp for OpTxd {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "txd.b{}", self.dim)?;
write!(f, "txd{}", self.dim)?;
if self.offset {
write!(f, ".aoffi")?;
}
write!(f, " {} {}", self.srcs[0], self.srcs[1])
write!(f, " {} {} {}", self.tex, self.srcs[0], self.srcs[1])
}
}
impl_display_for_op!(OpTxd);
@ -4776,6 +4812,8 @@ impl_display_for_op!(OpTxd);
pub struct OpTxq {
pub dsts: [Dst; 2],
pub tex: TexRef,
#[src_type(SSA)]
pub src: Src,
@ -4785,7 +4823,7 @@ pub struct OpTxq {
impl DisplayOp for OpTxq {
fn fmt_op(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "txq.b {} {}", self.src, self.query)
write!(f, "txq {} {} {}", self.tex, self.src, self.query)
}
}
impl_display_for_op!(OpTxq);

View file

@ -2050,7 +2050,22 @@ impl SM50Op for OpTex {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xdeb8);
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0x0380);
e.set_field(36..49, idx);
e.set_bit(54, self.offset);
e.set_tex_lod_mode(55..57, self.lod_mode);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xdeb8);
e.set_bit(36, self.offset);
e.set_tex_lod_mode(37..39, self.lod_mode);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());
@ -2061,8 +2076,6 @@ impl SM50Op for OpTex {
e.set_tex_dim(28..31, self.dim);
e.set_field(31..35, self.mask);
e.set_bit(35, false); // ToDo: NDV
e.set_bit(36, self.offset);
e.set_tex_lod_mode(37..39, self.lod_mode);
e.set_bit(49, false); // TODO: .NODEP
e.set_bit(50, self.z_cmpr);
}
@ -2074,7 +2087,18 @@ impl SM50Op for OpTld {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xdd38);
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0xdc38);
e.set_field(36..49, idx);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xdd38);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());
@ -2102,7 +2126,27 @@ impl SM50Op for OpTld4 {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xdef8);
let offset_mode = match self.offset_mode {
Tld4OffsetMode::None => 0_u8,
Tld4OffsetMode::AddOffI => 1_u8,
Tld4OffsetMode::PerPx => 2_u8,
};
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0xc838);
e.set_field(36..49, idx);
e.set_field(54..56, offset_mode);
e.set_field(56..58, self.comp);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xdef8);
e.set_field(36..38, offset_mode);
e.set_field(38..40, self.comp);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());
@ -2113,15 +2157,6 @@ impl SM50Op for OpTld4 {
e.set_tex_dim(28..31, self.dim);
e.set_field(31..35, self.mask);
e.set_bit(35, false); // ToDo: NDV
e.set_field(
36..38,
match self.offset_mode {
Tld4OffsetMode::None => 0_u8,
Tld4OffsetMode::AddOffI => 1_u8,
Tld4OffsetMode::PerPx => 2_u8,
},
);
e.set_field(38..40, self.comp);
e.set_bit(49, false); // TODO: .NODEP
e.set_bit(50, self.z_cmpr);
}
@ -2133,7 +2168,18 @@ impl SM50Op for OpTmml {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xdf60);
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0xdf58);
e.set_field(36..49, idx);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xdf60);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());
@ -2153,7 +2199,18 @@ impl SM50Op for OpTxd {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xde78);
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0xde38);
e.set_field(36..49, idx);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xde78);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());
@ -2174,7 +2231,18 @@ impl SM50Op for OpTxq {
}
fn encode(&self, e: &mut SM50Encoder<'_>) {
e.set_opcode(0xdf50);
match self.tex {
TexRef::Bound(idx) => {
e.set_opcode(0xdf48);
e.set_field(36..49, idx);
}
TexRef::CBuf { .. } => {
panic!("SM50 doesn't have CBuf textures");
}
TexRef::Bindless => {
e.set_opcode(0xdf50);
}
}
e.set_dst(self.dsts[0]);
assert!(self.dsts[1].is_none());

View file

@ -2265,6 +2265,14 @@ impl SM70Op for OpR2UR {
}
impl SM70Encoder<'_> {
fn set_tex_cb_ref(&mut self, range: Range<usize>, cb: TexCBufRef) {
assert!(range.len() == 19);
let mut v = BitMutView::new_subset(self, range);
assert!(cb.offset % 4 == 0);
v.set_field(0..14, cb.offset / 4);
v.set_field(14..19, cb.idx);
}
fn set_tex_dim(&mut self, range: Range<usize>, dim: TexDim) {
assert!(range.len() == 3);
self.set_field(
@ -2318,8 +2326,19 @@ impl SM70Op for OpTex {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x361);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb60);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x361);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {
@ -2349,8 +2368,19 @@ impl SM70Op for OpTld {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x367);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb66);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x367);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {
@ -2384,8 +2414,19 @@ impl SM70Op for OpTld4 {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x364);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb63);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x364);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {
@ -2422,8 +2463,19 @@ impl SM70Op for OpTmml {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x36a);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb69);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x36a);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {
@ -2448,8 +2500,19 @@ impl SM70Op for OpTxd {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x36d);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb6c);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x36d);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {
@ -2476,8 +2539,19 @@ impl SM70Op for OpTxq {
}
fn encode(&self, e: &mut SM70Encoder<'_>) {
e.set_opcode(0x370);
e.set_bit(59, true); // .B
match self.tex {
TexRef::Bound(_) => {
panic!("SM70+ doesn't have legacy bound textures");
}
TexRef::CBuf(cb) => {
e.set_opcode(0xb6f);
e.set_tex_cb_ref(40..59, cb);
}
TexRef::Bindless => {
e.set_opcode(0x370);
e.set_bit(59, true); // .B
}
}
e.set_dst(self.dsts[0]);
if let Dst::Reg(reg) = self.dsts[1] {