From 899c58606d23443febc343907b9ab50a1b324014 Mon Sep 17 00:00:00 2001 From: Faith Ekstrand Date: Thu, 9 Nov 2023 14:32:30 -0600 Subject: [PATCH] nak: Only split texture destinations on Volta+ Part-of: --- src/nouveau/compiler/nak/encode_sm50.rs | 36 +++++++++++++++++++++++++ src/nouveau/compiler/nak/from_nir.rs | 15 +++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/nouveau/compiler/nak/encode_sm50.rs b/src/nouveau/compiler/nak/encode_sm50.rs index 92d091f4d40..7db8b06f861 100644 --- a/src/nouveau/compiler/nak/encode_sm50.rs +++ b/src/nouveau/compiler/nak/encode_sm50.rs @@ -1241,6 +1241,42 @@ impl SM50Instr { } } + fn set_tex_dim(&mut self, range: Range, dim: TexDim) { + assert!(range.len() == 3); + self.set_field( + range, + match dim { + TexDim::_1D => 0_u8, + TexDim::Array1D => 1_u8, + TexDim::_2D => 2_u8, + TexDim::Array2D => 3_u8, + TexDim::_3D => 4_u8, + TexDim::Cube => 6_u8, + TexDim::ArrayCube => 7_u8, + }, + ); + } + + fn encode_tld(&mut self, op: &OpTld) { + self.set_opcode(0xdd38); + + self.set_dst(op.dsts[0]); + assert!(op.dsts[1].is_none()); + self.set_reg_src(8..16, op.srcs[0]); + self.set_reg_src(20..28, op.srcs[1]); + + self.set_tex_dim(28..31, op.dim); + self.set_field(31..35, op.mask); + self.set_bit(35, op.offset); + self.set_bit(49, false); /* TODO: .NODEP */ + self.set_bit(50, op.is_ms); + + assert!( + op.lod_mode == TexLodMode::Zero || op.lod_mode == TexLodMode::Lod + ); + self.set_bit(55, op.lod_mode == TexLodMode::Zero); + } + fn encode_ipa(&mut self, op: &OpIpa) { assert!(op.offset.is_reg_or_zero()); diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index 4dc677aa3b9..8466eee146a 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -12,7 +12,7 @@ use crate::sph::{OutputTopology, PixelImap}; use nak_bindings::*; -use std::cmp::{max, min}; +use std::cmp::max; use std::collections::{HashMap, HashSet}; fn init_info_from_nir(nir: &nir_shader, sm: u8) -> ShaderInfo { @@ -1323,10 +1323,15 @@ impl<'a> ShaderFromNir<'a> { let mask = u8::try_from(mask).unwrap(); let dst_comps = u8::try_from(mask.count_ones()).unwrap(); + let dst = b.alloc_ssa(RegFile::GPR, dst_comps); + + // On Volta and later, the destination is split in two let mut dsts = [Dst::None; 2]; - dsts[0] = b.alloc_ssa(RegFile::GPR, min(dst_comps, 2)).into(); - if dst_comps > 2 { - dsts[1] = b.alloc_ssa(RegFile::GPR, dst_comps - 2).into(); + if dst_comps > 2 && b.sm() >= 70 { + dsts[0] = SSARef::try_from(&dst[0..2]).unwrap().into(); + dsts[1] = SSARef::try_from(&dst[2..]).unwrap().into(); + } else { + dsts[0] = dst.into(); } if tex.op == nir_texop_hdr_dim_nv { @@ -1429,7 +1434,7 @@ impl<'a> ShaderFromNir<'a> { if mask & (1 << i) == 0 { nir_dst.push(b.copy(0.into())[0]); } else { - nir_dst.push(dsts[di / 2].as_ssa().unwrap()[di % 2].into()); + nir_dst.push(dst[di].into()); di += 1; } }