rusticl/mem: align fill pattern buffer to 4 bytes
authorKarol Herbst <kherbst@redhat.com>
Wed, 28 Sep 2022 00:01:45 +0000 (02:01 +0200)
committerMarge Bot <emma+marge@anholt.net>
Sat, 1 Oct 2022 12:27:19 +0000 (12:27 +0000)
drivers might treat it as a uint32_t* buffer.

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18853>

src/gallium/frontends/rusticl/core/memory.rs
src/gallium/frontends/rusticl/mesa/pipe/context.rs

index 91dd70f..c4b4eea 100644 (file)
@@ -11,12 +11,14 @@ use mesa_rust::pipe::context::*;
 use mesa_rust::pipe::resource::*;
 use mesa_rust::pipe::transfer::*;
 use mesa_rust_gen::*;
+use mesa_rust_util::math::*;
 use mesa_rust_util::properties::Properties;
 use rusticl_opencl_gen::*;
 
 use std::cmp;
 use std::collections::HashMap;
 use std::convert::TryInto;
+use std::mem::size_of;
 use std::ops::AddAssign;
 use std::os::raw::c_void;
 use std::ptr;
@@ -611,8 +613,24 @@ impl Mem {
 
         let res = self.get_res()?.get(&q.device).unwrap();
         let bx = create_box(origin, region, self.mem_type)?;
-        let mut new_pattern = vec![0; self.image_format.pixel_size().unwrap() as usize];
+        // make sure we allocate multiples of 4 bytes so drivers don't read out of bounds or
+        // unaligned.
+        // TODO: use div_ceil once it's available
+        let size = align(
+            self.image_format.pixel_size().unwrap() as usize,
+            size_of::<u32>(),
+        );
+        let mut new_pattern: Vec<u32> = vec![0; size / size_of::<u32>()];
+
+        // we don't support CL_DEPTH for now
+        assert!(pattern.len() == 4);
 
+        // SAFETY: pointers have to be valid for read/writes of exactly one pixel of their
+        // respective format.
+        // `new_pattern` has the correct size due to the `size` above.
+        // `pattern` is validated through the CL API and allows undefined behavior if not followed
+        // by CL API rules. It's expected to be a 4 component array of 32 bit values, except for
+        // CL_DEPTH where it's just one value.
         unsafe {
             util_format_pack_rgba(
                 self.image_format.to_pipe_format().unwrap(),
index 140e619..36f21b1 100644 (file)
@@ -101,7 +101,7 @@ impl PipeContext {
         }
     }
 
-    pub fn clear_texture(&self, res: &PipeResource, pattern: &[u8], bx: &pipe_box) {
+    pub fn clear_texture(&self, res: &PipeResource, pattern: &[u32], bx: &pipe_box) {
         unsafe {
             self.pipe.as_ref().clear_texture.unwrap()(
                 self.pipe.as_ptr(),