nak: Implement image load/store

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand
2023-04-20 16:14:04 -05:00
committed by Marge Bot
parent 9d2b81e71d
commit 840c0281ce
3 changed files with 257 additions and 24 deletions
+74 -24
View File
@@ -916,6 +916,77 @@ impl SM75Instr {
self.set_field(72..76, op.mask);
}
fn set_image_dim(&mut self, range: Range<usize>, dim: ImageDim) {
assert!(range.len() == 3);
self.set_field(
range,
match dim {
ImageDim::_1D => 0_u8,
ImageDim::_1DBuffer => 1_u8,
ImageDim::_1DArray => 2_u8,
ImageDim::_2D => 3_u8,
ImageDim::_2DArray => 4_u8,
ImageDim::_3D => 5_u8,
},
);
}
fn set_mem_order_scope(&mut self, order: &MemOrder, scope: &MemScope) {
if self.sm <= 75 {
self.set_field(
77..79,
match scope {
MemScope::CTA => 0_u8,
MemScope::Cluster => 1_u8,
MemScope::GPU => 2_u8,
MemScope::System => 3_u8,
},
);
self.set_field(
79..81,
match order {
/* Constant => 0_u8, */
MemOrder::Weak => 1_u8,
MemOrder::Strong => 2_u8,
/* MMIO => 3_u8, */
},
);
} else {
assert!(*scope == MemScope::System);
assert!(*order == MemOrder::Strong);
self.set_field(77..81, 0xa);
}
}
fn encode_suld(&mut self, op: &OpSuLd) {
self.set_opcode(0x998);
self.set_dst(op.dst);
self.set_reg_src(24..32, op.coord);
self.set_reg_src(64..72, op.handle);
self.set_pred_dst(81..84, op.resident);
self.set_image_dim(61..64, op.image_dim);
self.set_mem_order_scope(&op.mem_order, &op.mem_scope);
assert!(op.mask == 0x1 || op.mask == 0x3 || op.mask == 0xf);
self.set_field(72..76, op.mask);
}
fn encode_sust(&mut self, op: &OpSuSt) {
self.set_opcode(0x99c);
self.set_reg_src(24..32, op.coord);
self.set_reg_src(32..40, op.data);
self.set_reg_src(64..72, op.handle);
self.set_image_dim(61..64, op.image_dim);
self.set_mem_order_scope(&op.mem_order, &op.mem_scope);
assert!(op.mask == 0x1 || op.mask == 0x3 || op.mask == 0xf);
self.set_field(72..76, op.mask);
}
fn set_mem_access(&mut self, access: &MemAccess) {
self.set_field(
72..73,
@@ -936,30 +1007,7 @@ impl SM75Instr {
MemType::B128 => 6_u8,
},
);
if self.sm <= 75 {
self.set_field(
77..79,
match access.scope {
MemScope::CTA => 0_u8,
MemScope::Cluster => 1_u8,
MemScope::GPU => 2_u8,
MemScope::System => 3_u8,
},
);
self.set_field(
79..81,
match access.order {
/* Constant => 0_u8, */
/* Weak? => 1_u8, */
MemOrder::Strong => 2_u8,
/* MMIO => 3_u8, */
},
);
} else {
assert!(access.scope == MemScope::System);
assert!(access.order == MemOrder::Strong);
self.set_field(77..81, 0xa);
}
self.set_mem_order_scope(&access.order, &access.scope);
}
fn encode_ld(&mut self, op: &OpLd) {
@@ -1118,6 +1166,8 @@ impl SM75Instr {
Op::Tmml(op) => si.encode_tmml(&op),
Op::Txd(op) => si.encode_txd(&op),
Op::Txq(op) => si.encode_txq(&op),
Op::SuLd(op) => si.encode_suld(&op),
Op::SuSt(op) => si.encode_sust(&op),
Op::Ld(op) => si.encode_ld(&op),
Op::St(op) => si.encode_st(&op),
Op::ALd(op) => si.encode_ald(&op),
+75
View File
@@ -778,9 +778,84 @@ impl<'a> ShaderFromNir<'a> {
}
}
fn get_image_dim(&mut self, intrin: &nir_intrinsic_instr) -> ImageDim {
let is_array = intrin.image_array();
let image_dim = intrin.image_dim();
match intrin.image_dim() {
GLSL_SAMPLER_DIM_1D => {
if is_array {
ImageDim::_1DArray
} else {
ImageDim::_1D
}
}
GLSL_SAMPLER_DIM_2D => {
if is_array {
ImageDim::_2DArray
} else {
ImageDim::_2D
}
}
GLSL_SAMPLER_DIM_3D => {
assert!(!is_array);
ImageDim::_3D
}
GLSL_SAMPLER_DIM_CUBE => ImageDim::_2DArray,
GLSL_SAMPLER_DIM_BUF => {
assert!(!is_array);
ImageDim::_1DBuffer
}
_ => panic!("Unsupported image dimension: {}", image_dim),
}
}
fn get_image_coord(
&mut self,
intrin: &nir_intrinsic_instr,
dim: ImageDim,
) -> Src {
let vec = self.get_ssa(intrin.get_src(1).as_def());
/* let sample = self.get_src(&srcs[2]); */
let comps = usize::from(dim.coord_comps());
SSARef::try_from(&vec[0..comps]).unwrap().into()
}
fn parse_intrinsic(&mut self, intrin: &nir_intrinsic_instr) {
let srcs = intrin.srcs_as_slice();
match intrin.intrinsic {
nir_intrinsic_bindless_image_load => {
let handle = self.get_src(&srcs[0]);
let dim = self.get_image_dim(intrin);
let coord = self.get_image_coord(intrin, dim);
/* let sample = self.get_src(&srcs[2]); */
let dst = self.get_dst(&intrin.def);
self.instrs.push(Instr::new(OpSuLd {
dst: dst,
resident: Dst::None,
image_dim: dim,
mem_order: MemOrder::Weak,
mem_scope: MemScope::CTA,
mask: 0xf,
handle: handle,
coord: coord,
}));
}
nir_intrinsic_bindless_image_store => {
let handle = self.get_src(&srcs[0]);
let dim = self.get_image_dim(intrin);
let coord = self.get_image_coord(intrin, dim);
/* let sample = self.get_src(&srcs[2]); */
let data = self.get_src(&srcs[3]);
self.instrs.push(Instr::new(OpSuSt {
image_dim: dim,
mem_order: MemOrder::Weak,
mem_scope: MemScope::CTA,
mask: 0xf,
handle: handle,
coord: coord,
data: data,
}));
}
nir_intrinsic_load_barycentric_centroid => (),
nir_intrinsic_load_barycentric_pixel => (),
nir_intrinsic_load_barycentric_sample => (),
+108
View File
@@ -1015,6 +1015,42 @@ impl fmt::Display for TexQuery {
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum ImageDim {
_1D,
_1DBuffer,
_1DArray,
_2D,
_2DArray,
_3D,
}
impl ImageDim {
pub fn coord_comps(&self) -> u8 {
match self {
ImageDim::_1D => 1,
ImageDim::_1DBuffer => 1,
ImageDim::_1DArray => 2,
ImageDim::_2D => 2,
ImageDim::_2DArray => 3,
ImageDim::_3D => 3,
}
}
}
impl fmt::Display for ImageDim {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ImageDim::_1D => write!(f, "1D"),
ImageDim::_1DBuffer => write!(f, "1D_BUFFER"),
ImageDim::_1DArray => write!(f, "1D_ARRAY"),
ImageDim::_2D => write!(f, "2D"),
ImageDim::_2DArray => write!(f, "2D_ARRAY"),
ImageDim::_3D => write!(f, "3D"),
}
}
}
pub enum IntType {
U8,
I8,
@@ -1158,9 +1194,19 @@ impl fmt::Display for MemType {
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub enum MemOrder {
Weak,
Strong,
}
impl fmt::Display for MemOrder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MemOrder::Weak => write!(f, "WEAK"),
MemOrder::Strong => write!(f, "STRONG"),
}
}
}
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
pub enum MemScope {
CTA,
@@ -1833,6 +1879,63 @@ impl fmt::Display for OpTxq {
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpSuLd {
pub dst: Dst,
pub resident: Dst,
pub image_dim: ImageDim,
pub mem_order: MemOrder,
pub mem_scope: MemScope,
pub mask: u8,
pub handle: Src,
pub coord: Src,
}
impl fmt::Display for OpSuLd {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"SULD.P.{}.{}.{} {{ {} {} }} [{}] {}",
self.image_dim,
self.mem_order,
self.mem_scope,
self.dst,
self.resident,
self.coord,
self.handle,
)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpSuSt {
pub image_dim: ImageDim,
pub mem_order: MemOrder,
pub mem_scope: MemScope,
pub mask: u8,
pub handle: Src,
pub coord: Src,
pub data: Src,
}
impl fmt::Display for OpSuSt {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"SUST.P.{}.{}.{} [{}] {} {}",
self.image_dim,
self.mem_order,
self.mem_scope,
self.coord,
self.data,
self.handle,
)
}
}
#[repr(C)]
#[derive(SrcsAsSlice, DstsAsSlice)]
pub struct OpLd {
@@ -2292,6 +2395,8 @@ pub enum Op {
Tmml(OpTmml),
Txd(OpTxd),
Txq(OpTxq),
SuLd(OpSuLd),
SuSt(OpSuSt),
Ld(OpLd),
St(OpSt),
ALd(OpALd),
@@ -2707,6 +2812,7 @@ impl Instr {
pub fn can_eliminate(&self) -> bool {
match self.op {
Op::ASt(_)
| Op::SuSt(_)
| Op::St(_)
| Op::Bra(_)
| Op::Exit(_)
@@ -2745,6 +2851,8 @@ impl Instr {
Op::Tmml(_) => None,
Op::Txd(_) => None,
Op::Txq(_) => None,
Op::SuLd(_) => None,
Op::SuSt(_) => None,
Op::Ld(_) => None,
Op::St(_) => None,
Op::Bra(_) | Op::Exit(_) => Some(15),