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

Author: Karol Herbst <kher...@redhat.com>
Date:   Sat Oct 28 02:01:07 2023 +0200

rusticl: use real buffer for cb0 for drivers prefering

At the moment it's radeonsi and zink.

Consequentially this also fixes data races in zink due to driver internal
reasons.

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

---

 src/gallium/frontends/rusticl/core/device.rs       |  6 ++++
 src/gallium/frontends/rusticl/core/kernel.rs       |  2 +-
 src/gallium/frontends/rusticl/core/queue.rs        | 39 +++++++++++++++++++---
 src/gallium/frontends/rusticl/mesa/pipe/context.rs | 18 ++++++++++
 src/gallium/frontends/rusticl/mesa/pipe/screen.rs  | 11 ++++--
 5 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/src/gallium/frontends/rusticl/core/device.rs 
b/src/gallium/frontends/rusticl/core/device.rs
index 5a0e7bdc915..b6c74006d6b 100644
--- a/src/gallium/frontends/rusticl/core/device.rs
+++ b/src/gallium/frontends/rusticl/core/device.rs
@@ -1006,6 +1006,12 @@ impl Device {
         id as u32
     }
 
+    pub fn prefers_real_buffer_in_cb0(&self) -> bool {
+        self.screen
+            .param(pipe_cap::PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0)
+            == 1
+    }
+
     pub fn shareable_shaders(&self) -> bool {
         self.screen.param(pipe_cap::PIPE_CAP_SHAREABLE_SHADERS) == 1
     }
diff --git a/src/gallium/frontends/rusticl/core/kernel.rs 
b/src/gallium/frontends/rusticl/core/kernel.rs
index 6ab38c5c9d4..a73638fdb54 100644
--- a/src/gallium/frontends/rusticl/core/kernel.rs
+++ b/src/gallium/frontends/rusticl/core/kernel.rs
@@ -1085,7 +1085,7 @@ impl Kernel {
             ctx.set_sampler_views(&mut sviews);
             ctx.set_shader_images(&iviews);
             ctx.set_global_binding(resources.as_slice(), &mut globals);
-            ctx.set_constant_buffer(0, &input);
+            ctx.update_cb0(&input);
 
             ctx.launch_grid(work_dim, block, grid, variable_local_size as u32);
 
diff --git a/src/gallium/frontends/rusticl/core/queue.rs 
b/src/gallium/frontends/rusticl/core/queue.rs
index 1275f48786e..85cb6f39552 100644
--- a/src/gallium/frontends/rusticl/core/queue.rs
+++ b/src/gallium/frontends/rusticl/core/queue.rs
@@ -6,6 +6,8 @@ use crate::core::platform::*;
 use crate::impl_cl_type_trait;
 
 use mesa_rust::pipe::context::PipeContext;
+use mesa_rust::pipe::resource::PipeResource;
+use mesa_rust::pipe::screen::ResourceType;
 use mesa_rust_util::properties::*;
 use rusticl_opencl_gen::*;
 
@@ -23,16 +25,43 @@ use std::thread::JoinHandle;
 /// Used for tracking bound GPU state to lower CPU overhead and centralize 
state tracking
 pub struct QueueContext {
     ctx: PipeContext,
+    cb0: Option<PipeResource>,
 }
 
 impl QueueContext {
     fn new_for(device: &Device) -> CLResult<Self> {
-        Ok(Self {
-            ctx: device
+        let ctx = device
+            .screen()
+            .create_context()
+            .ok_or(CL_OUT_OF_HOST_MEMORY)?;
+        let size = device.param_max_size() as u32;
+        let cb0 = if device.prefers_real_buffer_in_cb0() {
+            device
                 .screen()
-                .create_context()
-                .ok_or(CL_OUT_OF_HOST_MEMORY)?,
-        })
+                .resource_create_buffer(size, ResourceType::Cb0, 0)
+        } else {
+            None
+        };
+
+        if let Some(cb0) = &cb0 {
+            ctx.bind_constant_buffer(0, cb0);
+        }
+
+        Ok(Self { ctx: ctx, cb0: cb0 })
+    }
+
+    pub fn update_cb0(&self, data: &[u8]) {
+        // only update if we actually bind data
+        if !data.is_empty() {
+            // if we have a real buffer, update that, otherwise just set the 
data directly
+            if let Some(cb) = &self.cb0 {
+                debug_assert!(data.len() <= cb.width() as usize);
+                self.ctx
+                    .buffer_subdata(cb, 0, data.as_ptr().cast(), data.len() as 
u32);
+            } else {
+                self.ctx.set_constant_buffer(0, data);
+            }
+        }
     }
 }
 
diff --git a/src/gallium/frontends/rusticl/mesa/pipe/context.rs 
b/src/gallium/frontends/rusticl/mesa/pipe/context.rs
index 26512cbf8b4..0d0faeda33a 100644
--- a/src/gallium/frontends/rusticl/mesa/pipe/context.rs
+++ b/src/gallium/frontends/rusticl/mesa/pipe/context.rs
@@ -381,6 +381,24 @@ impl PipeContext {
         unsafe { 
self.pipe.as_ref().delete_sampler_state.unwrap()(self.pipe.as_ptr(), ptr) }
     }
 
+    pub fn bind_constant_buffer(&self, idx: u32, res: &PipeResource) {
+        let cb = pipe_constant_buffer {
+            buffer: res.pipe(),
+            buffer_offset: 0,
+            buffer_size: res.width(),
+            user_buffer: ptr::null(),
+        };
+        unsafe {
+            self.pipe.as_ref().set_constant_buffer.unwrap()(
+                self.pipe.as_ptr(),
+                pipe_shader_type::PIPE_SHADER_COMPUTE,
+                idx,
+                false,
+                &cb,
+            )
+        }
+    }
+
     pub fn set_constant_buffer(&self, idx: u32, data: &[u8]) {
         let cb = pipe_constant_buffer {
             buffer: ptr::null_mut(),
diff --git a/src/gallium/frontends/rusticl/mesa/pipe/screen.rs 
b/src/gallium/frontends/rusticl/mesa/pipe/screen.rs
index ff11cae7343..4c3f4d23aae 100644
--- a/src/gallium/frontends/rusticl/mesa/pipe/screen.rs
+++ b/src/gallium/frontends/rusticl/mesa/pipe/screen.rs
@@ -73,16 +73,21 @@ impl ComputeParam<Vec<u64>> for PipeScreen {
 pub enum ResourceType {
     Normal,
     Staging,
+    Cb0,
 }
 
 impl ResourceType {
-    fn apply(&self, tmpl: &mut pipe_resource) {
+    fn apply(&self, tmpl: &mut pipe_resource, screen: &PipeScreen) {
         match self {
             Self::Staging => {
                 tmpl.set_usage(pipe_resource_usage::PIPE_USAGE_STAGING.0);
                 tmpl.flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT | 
PIPE_RESOURCE_FLAG_MAP_COHERENT;
                 tmpl.bind |= PIPE_BIND_LINEAR;
             }
+            Self::Cb0 => {
+                tmpl.flags |= screen.param(pipe_cap::PIPE_CAP_CONSTBUF0_FLAGS) 
as u32;
+                tmpl.bind |= PIPE_BIND_CONSTANT_BUFFER;
+            }
             Self::Normal => {}
         }
     }
@@ -146,7 +151,7 @@ impl PipeScreen {
         tmpl.array_size = 1;
         tmpl.bind = pipe_bind;
 
-        res_type.apply(&mut tmpl);
+        res_type.apply(&mut tmpl, self);
 
         self.resource_create(&tmpl)
     }
@@ -194,7 +199,7 @@ impl PipeScreen {
             tmpl.bind |= PIPE_BIND_SHADER_IMAGE;
         }
 
-        res_type.apply(&mut tmpl);
+        res_type.apply(&mut tmpl, self);
 
         self.resource_create(&tmpl)
     }

Reply via email to