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

Author: Faith Ekstrand <faith.ekstr...@collabora.com>
Date:   Mon Jan  8 17:50:26 2024 -0600

nak: Add explicit padding to nak_shader_info

This ensures that the padding bits stay zero, even as we copy the
structure around through multiple languages.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27049>

---

 src/nouveau/compiler/meson.build |  2 ++
 src/nouveau/compiler/nak.h       | 26 +++++++++++++++++++++++++-
 src/nouveau/compiler/nak/api.rs  | 31 ++++++++++++++++++++++++++++++-
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/src/nouveau/compiler/meson.build b/src/nouveau/compiler/meson.build
index 535294ecf1f..f8a55046edb 100644
--- a/src/nouveau/compiler/meson.build
+++ b/src/nouveau/compiler/meson.build
@@ -78,11 +78,13 @@ nak_bindings_rs = rust.bindgen(
     '--allowlist-type', 'mesa_scope',
     '--allowlist-type', 'mesa_prim',
     '--allowlist-type', 'tess_primitive_mode',
+    '--allowlist-var', 'NAK_.*',
     '--allowlist-var', 'nir_.*_infos',
     '--allowlist-function', '_mesa_shader_stage_to_string',
     '--allowlist-function', 'nak_.*',
     '--allowlist-function', 'nir_.*',
     '--allowlist-function', 'glsl_.*',
+    '--explicit-padding',
     '--no-prepend-enum-name',
   ],
   dependencies : libnak_deps,
diff --git a/src/nouveau/compiler/nak.h b/src/nouveau/compiler/nak.h
index 5a3cf249401..cfec9e4f738 100644
--- a/src/nouveau/compiler/nak.h
+++ b/src/nouveau/compiler/nak.h
@@ -79,6 +79,20 @@ struct nak_xfb_info {
    uint8_t attr_index[4][128];
 };
 
+/* This is an enum so bindgen will generate it */
+#define NAK_SHADER_INFO_STAGE_UNION_SIZE 12
+
+/* This struct MUST have explicit padding fields to ensure that all padding is
+ * zeroed and the zeros get properly copied, even across API boundaries.  This
+ * is ensured in two ways:
+ *
+ *  - Bindgen is invoked with --explicit-padding and if a __bindgen_paddingN
+ *    member ever crops up, that tells us we need to add an explicit member
+ *    here.
+ *
+ *  - There is a set of const asserts in nak/api.rs which ensure that all of
+ *    the union fields are equal to NAK_SHADER_INFO_STAGE_UNION_SIZE.
+ */
 struct nak_shader_info {
    gl_shader_stage stage;
 
@@ -88,6 +102,8 @@ struct nak_shader_info {
    /** Number of barriers used */
    uint8_t num_barriers;
 
+   uint16_t _pad0;
+
    /** Size of shader local (scratch) memory */
    uint32_t slm_size;
 
@@ -98,6 +114,8 @@ struct nak_shader_info {
 
          /* Shared memory size */
          uint16_t smem_size;
+
+         uint8_t _pad[4];
       } cs;
 
       struct {
@@ -106,16 +124,20 @@ struct nak_shader_info {
          bool post_depth_coverage;
          bool uses_sample_shading;
          bool early_fragment_tests;
+
+         uint8_t _pad[7];
       } fs;
 
       struct {
          enum nak_ts_domain domain;
          enum nak_ts_spacing spacing;
          enum nak_ts_prims prims;
+
+         uint8_t _pad[9];
       } ts;
 
       /* Used to initialize the union for other stages */
-      uint32_t dummy;
+      uint8_t _pad[NAK_SHADER_INFO_STAGE_UNION_SIZE];
    };
 
    struct {
@@ -123,6 +145,8 @@ struct nak_shader_info {
       uint8_t clip_enable;
       uint8_t cull_enable;
 
+      uint8_t _pad[1];
+
       struct nak_xfb_info xfb;
    } vtg;
 
diff --git a/src/nouveau/compiler/nak/api.rs b/src/nouveau/compiler/nak/api.rs
index 69ceb774feb..35fad6f2aa2 100644
--- a/src/nouveau/compiler/nak/api.rs
+++ b/src/nouveau/compiler/nak/api.rs
@@ -154,6 +154,7 @@ pub extern "C" fn nak_compiler_create(
     let nak = Box::new(nak_compiler {
         sm: dev.sm,
         nir_options: nir_options(dev),
+        ..unsafe { std::mem::zeroed() }
     });
 
     Box::into_raw(nak)
@@ -198,6 +199,7 @@ impl ShaderBin {
             } else {
                 asm.as_ptr()
             },
+            ..unsafe { std::mem::zeroed() }
         };
         ShaderBin {
             bin: bin,
@@ -226,6 +228,25 @@ fn eprint_hex(label: &str, data: &[u32]) {
     eprintln!("");
 }
 
+const _: () = {
+    assert!(
+        std::mem::size_of::<nak_shader_info__bindgen_ty_1>()
+            == NAK_SHADER_INFO_STAGE_UNION_SIZE as usize
+    );
+    assert!(
+        std::mem::size_of::<nak_shader_info__bindgen_ty_1__bindgen_ty_1>()
+            == NAK_SHADER_INFO_STAGE_UNION_SIZE as usize
+    );
+    assert!(
+        std::mem::size_of::<nak_shader_info__bindgen_ty_1__bindgen_ty_2>()
+            == NAK_SHADER_INFO_STAGE_UNION_SIZE as usize
+    );
+    assert!(
+        std::mem::size_of::<nak_shader_info__bindgen_ty_1__bindgen_ty_2>()
+            == NAK_SHADER_INFO_STAGE_UNION_SIZE as usize
+    );
+};
+
 #[no_mangle]
 pub extern "C" fn nak_compile_shader(
     nir: *mut nir_shader,
@@ -304,6 +325,7 @@ pub extern "C" fn nak_compile_shader(
             max(4, s.info.num_gprs)
         },
         num_barriers: s.info.num_barriers,
+        _pad0: Default::default(),
         slm_size: s.info.slm_size,
         __bindgen_anon_1: match &s.info.stage {
             ShaderStageInfo::Compute(cs_info) => {
@@ -315,6 +337,7 @@ pub extern "C" fn nak_compile_shader(
                             cs_info.local_size[2],
                         ],
                         smem_size: cs_info.smem_size,
+                        _pad: Default::default(),
                     },
                 }
             }
@@ -333,6 +356,7 @@ pub extern "C" fn nak_compile_shader(
                         uses_sample_shading: nir_fs_info.uses_sample_shading(),
                         early_fragment_tests: nir_fs_info
                             .early_fragment_tests(),
+                        _pad: Default::default(),
                     },
                 }
             }
@@ -369,10 +393,14 @@ pub extern "C" fn nak_compile_shader(
                         } else {
                             NAK_TS_PRIMS_TRIANGLES_CW
                         },
+
+                        _pad: Default::default(),
                     },
                 }
             }
-            _ => nak_shader_info__bindgen_ty_1 { dummy: 0 },
+            _ => nak_shader_info__bindgen_ty_1 {
+                _pad: Default::default(),
+            },
         },
         vtg: match &s.info.stage {
             ShaderStageInfo::Geometry(_)
@@ -388,6 +416,7 @@ pub extern "C" fn nak_compile_shader(
                     writes_layer: writes_layer,
                     clip_enable: clip_enable.try_into().unwrap(),
                     cull_enable: cull_enable.try_into().unwrap(),
+                    _pad: Default::default(),
                     xfb: unsafe { nak_xfb_from_nir(nir.xfb_info) },
                 }
             }

Reply via email to