diff --git a/src/compiler/nir/nir_divergence_analysis.c b/src/compiler/nir/nir_divergence_analysis.c index cfb3688f702..8c45b4a758c 100644 --- a/src/compiler/nir/nir_divergence_analysis.c +++ b/src/compiler/nir/nir_divergence_analysis.c @@ -617,6 +617,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state) case nir_intrinsic_image_load: case nir_intrinsic_image_deref_load: case nir_intrinsic_bindless_image_load: + case nir_intrinsic_bindless_image_load_raw_nv: case nir_intrinsic_image_sparse_load: case nir_intrinsic_image_deref_sparse_load: case nir_intrinsic_bindless_image_sparse_load: diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 47cde3be456..d40e02260eb 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -2404,6 +2404,9 @@ intrinsic("ipa_nv", dest_comp=1, src_comp=[1, 1], bit_sizes=[32], intrinsic("ldtram_nv", dest_comp=2, bit_sizes=[32], indices=[BASE, FLAGS], flags=[CAN_ELIMINATE, CAN_REORDER]) +# NVIDIA-specific Image intrinsics +image("load_raw_nv", src_comp=[4, 1, 1], extra_indices=[DEST_TYPE], dest_comp=0, flags=[CAN_ELIMINATE]) + # NVIDIA-specific Geometry Shader intrinsics. # These contain an additional integer source and destination with the primitive handle input/output. intrinsic("emit_vertex_nv", dest_comp=1, src_comp=[1], indices=[STREAM_ID]) diff --git a/src/compiler/rust/nir.rs b/src/compiler/rust/nir.rs index 95225c12f7c..d0fdbb4e412 100644 --- a/src/compiler/rust/nir.rs +++ b/src/compiler/rust/nir.rs @@ -319,6 +319,10 @@ impl nir_intrinsic_instr { self.get_const_index(NIR_INTRINSIC_IMAGE_ARRAY) != 0 } + pub fn format(&self) -> pipe_format { + self.get_const_index(NIR_INTRINSIC_FORMAT) as pipe_format + } + pub fn access(&self) -> gl_access_qualifier { self.get_const_index(NIR_INTRINSIC_ACCESS) as gl_access_qualifier } diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index de20c0a5abb..8c6820bf2f5 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -2047,6 +2047,19 @@ impl<'a> ShaderFromNir<'a> { } } + fn get_image_mem_type(&self, intrin: &nir_intrinsic_instr) -> MemType { + match intrin.format() { + PIPE_FORMAT_R8_UINT => MemType::U8, + PIPE_FORMAT_R8_SINT => MemType::I8, + PIPE_FORMAT_R16_UINT => MemType::U16, + PIPE_FORMAT_R16_SINT => MemType::I16, + PIPE_FORMAT_R32_UINT => MemType::B32, + PIPE_FORMAT_R32G32_UINT => MemType::B64, + PIPE_FORMAT_R32G32B32A32_UINT => MemType::B128, + _ => panic!("Unknown format"), + } + } + fn get_image_coord( &mut self, intrin: &nir_intrinsic_instr, @@ -2460,7 +2473,8 @@ impl<'a> ShaderFromNir<'a> { }); self.set_dst(&intrin.def, dst); } - nir_intrinsic_bindless_image_load => { + nir_intrinsic_bindless_image_load + | nir_intrinsic_bindless_image_load_raw_nv => { let handle = self.get_src(&srcs[0]); let dim = self.get_image_dim(intrin); let coord = self.get_image_coord(intrin, dim); @@ -2478,9 +2492,16 @@ impl<'a> ShaderFromNir<'a> { let comps = intrin.num_components; assert!(intrin.def.bit_size() == 32); - assert!(comps == 1 || comps == 2 || comps == 4); - let image_access = - ImageAccess::Formatted(ChannelMask::for_comps(comps)); + let image_access = if intrin.intrinsic + == nir_intrinsic_bindless_image_load_raw_nv + { + let mem_type = self.get_image_mem_type(intrin); + assert!(mem_type.bits().div_ceil(32) == comps.into()); + ImageAccess::Binary(mem_type) + } else { + assert!(comps == 1 || comps == 2 || comps == 4); + ImageAccess::Formatted(ChannelMask::for_comps(comps)) + }; let dst = b.alloc_ssa(RegFile::GPR, comps);