Module: Mesa
Branch: main
Commit: 7fb91f22d5d261afbabfc4c17168da204e28fc7f
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7fb91f22d5d261afbabfc4c17168da204e28fc7f

Author: Mary Guillemard <mary.guillem...@collabora.com>
Date:   Fri Sep 29 11:14:30 2023 +0200

nak: Add more bits discovered in SPH

This adds barycentric related bits and various others.

We still need to figure out the bits between 640..672, 800..1024 and checks
some "reserved" bits. (especially around the GS passthrough bit)

Signed-off-by: Mary Guillemard <mary.guillem...@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26224>

---

 src/nouveau/compiler/nak_from_nir.rs |  8 ++++
 src/nouveau/compiler/nak_ir.rs       | 27 +++++++++++
 src/nouveau/compiler/nak_sph.rs      | 88 ++++++++++++++++++++++++++++++++++++
 3 files changed, 123 insertions(+)

diff --git a/src/nouveau/compiler/nak_from_nir.rs 
b/src/nouveau/compiler/nak_from_nir.rs
index 436ed5c156c..18df8cd5102 100644
--- a/src/nouveau/compiler/nak_from_nir.rs
+++ b/src/nouveau/compiler/nak_from_nir.rs
@@ -51,6 +51,8 @@ fn init_info_from_nir(nir: &nir_shader, sm: u8) -> ShaderInfo 
{
                 };
 
                 ShaderStageInfo::Geometry(GeometryShaderInfo {
+                    // TODO: Should be set if 
VK_NV_geometry_shader_passthrough is in use.
+                    passthrough_enable: false,
                     stream_out_mask: info_gs.active_stream_mask(),
                     threads_per_input_primitive: info_gs.invocations,
                     output_topology: output_topology,
@@ -75,19 +77,25 @@ fn init_info_from_nir(nir: &nir_shader, sm: u8) -> 
ShaderInfo {
                     ab: 1 << 31,
                     c: 0,
                 },
+                sysvals_in_d: [PixelImap::Unused; 8],
                 attr_in: [PixelImap::Unused; 128],
+                barycentric_attr_in: [0; 4],
                 reads_sample_mask: false,
                 uses_kill: false,
                 writes_color: 0,
                 writes_sample_mask: false,
                 writes_depth: false,
+                // TODO: Should be set if interlocks are in use. 
(VK_EXT_fragment_shader_interlock)
+                does_interlock: false,
             }),
             MESA_SHADER_VERTEX
             | MESA_SHADER_GEOMETRY
             | MESA_SHADER_TESS_CTRL
             | MESA_SHADER_TESS_EVAL => ShaderIoInfo::Vtg(VtgIoInfo {
                 sysvals_in: SysValInfo::default(),
+                sysvals_in_d: 0,
                 sysvals_out: SysValInfo::default(),
+                sysvals_out_d: 0,
                 attr_in: [0; 4],
                 attr_out: [0; 4],
 
diff --git a/src/nouveau/compiler/nak_ir.rs b/src/nouveau/compiler/nak_ir.rs
index 8fba9ef3597..6af4eb1a05f 100644
--- a/src/nouveau/compiler/nak_ir.rs
+++ b/src/nouveau/compiler/nak_ir.rs
@@ -4930,6 +4930,7 @@ pub struct ComputeShaderInfo {
 
 #[derive(Debug)]
 pub struct GeometryShaderInfo {
+    pub passthrough_enable: bool,
     pub stream_out_mask: u8,
     pub threads_per_input_primitive: u8,
     pub output_topology: OutputTopology,
@@ -4939,6 +4940,7 @@ pub struct GeometryShaderInfo {
 impl Default for GeometryShaderInfo {
     fn default() -> Self {
         Self {
+            passthrough_enable: false,
             stream_out_mask: 0,
             threads_per_input_primitive: 0,
             output_topology: OutputTopology::LineStrip,
@@ -4972,7 +4974,9 @@ pub struct SysValInfo {
 #[derive(Debug)]
 pub struct VtgIoInfo {
     pub sysvals_in: SysValInfo,
+    pub sysvals_in_d: u8,
     pub sysvals_out: SysValInfo,
+    pub sysvals_out_d: u8,
     pub attr_in: [u32; 4],
     pub attr_out: [u32; 4],
     pub store_req_start: u8,
@@ -4987,6 +4991,12 @@ impl VtgIoInfo {
             &mut self.sysvals_in
         };
 
+        let sysvals_d = if written {
+            &mut self.sysvals_out_d
+        } else {
+            &mut self.sysvals_in_d
+        };
+
         let mut attr = BitMutView::new(if written {
             &mut self.attr_out
         } else {
@@ -5005,6 +5015,8 @@ impl VtgIoInfo {
                 panic!("FF color I/O not supported");
             } else if addr < 0x300 {
                 sysvals.c |= 1 << ((addr - 0x2c0) / 4);
+            } else if addr >= 0x3a0 && addr < 0x3c0 {
+                *sysvals_d |= 1 << ((addr - 0x3a0) / 4);
             }
         }
     }
@@ -5028,13 +5040,16 @@ impl VtgIoInfo {
 #[derive(Debug)]
 pub struct FragmentIoInfo {
     pub sysvals_in: SysValInfo,
+    pub sysvals_in_d: [PixelImap; 8],
     pub attr_in: [PixelImap; 128],
+    pub barycentric_attr_in: [u32; 4],
 
     pub reads_sample_mask: bool,
     pub uses_kill: bool,
     pub writes_color: u32,
     pub writes_sample_mask: bool,
     pub writes_depth: bool,
+    pub does_interlock: bool,
 }
 
 impl FragmentIoInfo {
@@ -5048,8 +5063,20 @@ impl FragmentIoInfo {
             panic!("FF color I/O not supported");
         } else if addr < 0x300 {
             self.sysvals_in.c |= 1 << ((addr - 0x2c0) / 4);
+        } else if addr >= 0x3a0 && addr < 0x3c0 {
+            let attr_idx = (addr - 0x3a0) as usize / 4;
+            self.sysvals_in_d[attr_idx] = interp;
         }
     }
+
+    pub fn mark_barycentric_attr_in(&mut self, addr: u16) {
+        assert!(addr >= 0x80 && addr < 0x280);
+
+        let mut attr = BitMutView::new(&mut self.barycentric_attr_in);
+
+        let attr_idx = (addr - 0x080) as usize / 4;
+        attr.set_bit(attr_idx, true);
+    }
 }
 
 #[derive(Debug)]
diff --git a/src/nouveau/compiler/nak_sph.rs b/src/nouveau/compiler/nak_sph.rs
index 01ad101a6ae..1b8a7f8754f 100644
--- a/src/nouveau/compiler/nak_sph.rs
+++ b/src/nouveau/compiler/nak_sph.rs
@@ -172,6 +172,12 @@ impl ShaderProgramHeader {
         }
     }
 
+    #[inline]
+    fn imap_system_values_d_vtg(&mut self) -> SubSPHView<'_> {
+        assert!(self.shader_type != ShaderType::Fragment);
+        BitMutView::new_subset(&mut self.data, 392..400)
+    }
+
     #[inline]
     fn omap_system_values_ab(&mut self) -> SubSPHView<'_> {
         assert!(self.shader_type != ShaderType::Fragment);
@@ -191,6 +197,12 @@ impl ShaderProgramHeader {
         BitMutView::new_subset(&mut self.data, 576..592)
     }
 
+    #[inline]
+    fn imap_system_values_d_ps(&mut self) -> SubSPHView<'_> {
+        assert!(self.shader_type == ShaderType::Fragment);
+        BitMutView::new_subset(&mut self.data, 560..576)
+    }
+
     #[inline]
     fn omap_target(&mut self) -> SubSPHView<'_> {
         assert!(self.shader_type == ShaderType::Fragment);
@@ -198,6 +210,12 @@ impl ShaderProgramHeader {
         BitMutView::new_subset(&mut self.data, 576..608)
     }
 
+    #[inline]
+    fn omap_system_values_d_vtg(&mut self) -> SubSPHView<'_> {
+        assert!(self.shader_type != ShaderType::Fragment);
+        BitMutView::new_subset(&mut self.data, 632..640)
+    }
+
     #[inline]
     fn set_sph_type(&mut self, sph_type: u8, sph_version: u8) {
         let mut common_word0 = self.common_word0();
@@ -240,6 +258,12 @@ impl ShaderProgramHeader {
         self.common_word0().set_field(17..21, sass_version);
     }
 
+    #[inline]
+    pub fn set_gs_passthrough_enable(&mut self, gs_passthrough_enable: bool) {
+        assert!(self.shader_type == ShaderType::Geometry);
+        self.common_word0().set_bit(24, gs_passthrough_enable);
+    }
+
     #[inline]
     pub fn set_does_load_or_store(&mut self, does_load_or_store: bool) {
         self.common_word0().set_bit(26, does_load_or_store);
@@ -349,6 +373,11 @@ impl ShaderProgramHeader {
         self.imap_system_values_c().set_field(0..16, val);
     }
 
+    pub fn set_imap_system_values_d_vtg(&mut self, val: u8) {
+        assert!(self.shader_type != ShaderType::Fragment);
+        self.imap_system_values_d_vtg().set_field(0..8, val);
+    }
+
     #[inline]
     pub fn set_imap_vector_ps(&mut self, index: usize, value: PixelImap) {
         assert!(index < 128);
@@ -358,6 +387,19 @@ impl ShaderProgramHeader {
             .set_field(index * 2..(index + 1) * 2, u8::from(value));
     }
 
+    #[inline]
+    pub fn set_imap_system_values_d_ps(
+        &mut self,
+        index: usize,
+        value: PixelImap,
+    ) {
+        assert!(index < 8);
+        assert!(self.shader_type == ShaderType::Fragment);
+
+        self.imap_system_values_d_ps()
+            .set_field(index * 2..(index + 1) * 2, u8::from(value));
+    }
+
     #[inline]
     pub fn set_imap_vector_vtg(&mut self, index: usize, value: u32) {
         assert!(index < 4);
@@ -377,6 +419,11 @@ impl ShaderProgramHeader {
         self.omap_system_values_c().set_field(0..16, val);
     }
 
+    pub fn set_omap_system_values_d_vtg(&mut self, val: u8) {
+        assert!(self.shader_type != ShaderType::Fragment);
+        self.omap_system_values_d_vtg().set_field(0..8, val);
+    }
+
     #[inline]
     pub fn set_omap_vector(&mut self, index: usize, value: u32) {
         assert!(index < 4);
@@ -401,6 +448,35 @@ impl ShaderProgramHeader {
         assert!(self.shader_type == ShaderType::Fragment);
         self.set_bit(609, depth);
     }
+
+    #[inline]
+    pub fn set_does_interlock(&mut self, does_interlock: bool) {
+        assert!(self.shader_type == ShaderType::Fragment);
+        self.set_bit(610, does_interlock);
+    }
+
+    // TODO: This seems always set on fragment shaders, figure out what this 
is for.
+    #[inline]
+    pub fn set_unknown_bit611(&mut self, value: bool) {
+        assert!(self.shader_type == ShaderType::Fragment);
+        self.set_bit(611, value);
+    }
+
+    #[inline]
+    fn pervertex_imap_vector_ps(&mut self) -> SubSPHView<'_> {
+        assert!(self.shader_type == ShaderType::Fragment);
+
+        BitMutView::new_subset(&mut self.data, 672..800)
+    }
+
+    #[inline]
+    pub fn set_pervertex_imap_vector(&mut self, index: usize, value: u32) {
+        assert!(index < 4);
+        assert!(self.shader_type == ShaderType::Fragment);
+
+        self.pervertex_imap_vector_ps()
+            .set_field(index * 32..(index + 1) * 32, value);
+    }
 }
 
 pub fn encode_header(
@@ -428,6 +504,7 @@ pub fn encode_header(
         ShaderIoInfo::Vtg(io) => {
             sph.set_imap_system_values_ab(io.sysvals_in.ab);
             sph.set_imap_system_values_c(io.sysvals_in.c);
+            sph.set_imap_system_values_d_vtg(io.sysvals_in_d);
 
             for (index, value) in io.attr_in.iter().enumerate() {
                 sph.set_imap_vector_vtg(index, *value);
@@ -442,11 +519,16 @@ pub fn encode_header(
 
             sph.set_omap_system_values_ab(io.sysvals_out.ab);
             sph.set_omap_system_values_c(io.sysvals_out.c);
+            sph.set_omap_system_values_d_vtg(io.sysvals_out_d);
         }
         ShaderIoInfo::Fragment(io) => {
             sph.set_imap_system_values_ab(io.sysvals_in.ab);
             sph.set_imap_system_values_c(io.sysvals_in.c);
 
+            for (index, imap) in io.sysvals_in_d.iter().enumerate() {
+                sph.set_imap_system_values_d_ps(index, *imap);
+            }
+
             for (index, imap) in io.attr_in.iter().enumerate() {
                 sph.set_imap_vector_ps(index, *imap);
             }
@@ -458,12 +540,18 @@ pub fn encode_header(
             sph.set_omap_sample_mask(io.writes_sample_mask);
             sph.set_omap_depth(io.writes_depth);
             sph.set_omap_targets(io.writes_color);
+            sph.set_does_interlock(io.does_interlock);
+
+            for (index, value) in io.barycentric_attr_in.iter().enumerate() {
+                sph.set_pervertex_imap_vector(index, *value);
+            }
         }
         _ => {}
     }
 
     match &shader_info.stage {
         ShaderStageInfo::Geometry(stage) => {
+            sph.set_gs_passthrough_enable(stage.passthrough_enable);
             sph.set_stream_out_mask(stage.stream_out_mask);
             sph.set_threads_per_input_primitive(
                 stage.threads_per_input_primitive,

Reply via email to